fidl_next_codec/wire/
boxed.rs
1use core::fmt;
6use core::ptr::NonNull;
7
8use munge::munge;
9
10use crate::{
11 Decode, DecodeError, Decoder, DecoderExt as _, Encodable, EncodableOption, Encode, EncodeError,
12 EncodeOption, Slot, TakeFrom, WirePointer, ZeroPadding,
13};
14
15#[repr(C)]
17pub struct WireBox<T> {
18 ptr: WirePointer<T>,
19}
20
21unsafe impl<T: Send> Send for WireBox<T> {}
24
25unsafe impl<T: Sync> Sync for WireBox<T> {}
27
28impl<T> Drop for WireBox<T> {
29 fn drop(&mut self) {
30 if self.is_some() {
31 unsafe {
32 self.ptr.as_ptr().drop_in_place();
33 }
34 }
35 }
36}
37
38unsafe impl<T> ZeroPadding for WireBox<T> {
39 #[inline]
40 unsafe fn zero_padding(_: *mut Self) {
41 }
43}
44
45impl<T> WireBox<T> {
46 pub fn encode_present(slot: Slot<'_, Self>) {
48 munge!(let Self { ptr } = slot);
49 WirePointer::encode_present(ptr);
50 }
51
52 pub fn encode_absent(slot: Slot<'_, Self>) {
54 munge!(let Self { ptr } = slot);
55 WirePointer::encode_absent(ptr);
56 }
57
58 pub fn is_some(&self) -> bool {
60 !self.ptr.as_ptr().is_null()
61 }
62
63 pub fn is_none(&self) -> bool {
65 !self.is_some()
66 }
67
68 pub fn as_ref(&self) -> Option<&T> {
70 NonNull::new(self.ptr.as_ptr()).map(|ptr| unsafe { ptr.as_ref() })
71 }
72}
73
74impl<T: fmt::Debug> fmt::Debug for WireBox<T> {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 self.as_ref().fmt(f)
77 }
78}
79
80unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireBox<T> {
81 fn decode(slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
82 munge!(let Self { mut ptr } = slot);
83
84 if WirePointer::is_encoded_present(ptr.as_mut())? {
85 let value = decoder.decode_next::<T>()?;
86 WirePointer::set_decoded(ptr, value.into_raw());
87 }
88
89 Ok(())
90 }
91}
92
93impl<T: EncodableOption> Encodable for Option<T> {
94 type Encoded = T::EncodedOption;
95}
96
97impl<E: ?Sized, T: EncodeOption<E>> Encode<E> for Option<T> {
98 fn encode(
99 &mut self,
100 encoder: &mut E,
101 slot: Slot<'_, Self::Encoded>,
102 ) -> Result<(), EncodeError> {
103 T::encode_option(self.as_mut(), encoder, slot)
104 }
105}
106
107impl<T: TakeFrom<WT>, WT> TakeFrom<WireBox<WT>> for Option<T> {
108 fn take_from(from: &WireBox<WT>) -> Self {
109 from.as_ref().map(|value| T::take_from(value))
110 }
111}