fidl_next_codec/
decoded.rs1use core::fmt;
6use core::mem::{ManuallyDrop, forget};
7use core::ops::Deref;
8use core::ptr::NonNull;
9
10use crate::{Chunk, Decode, DecodeError, Decoder, DecoderExt as _, FromWire, IntoNatural, Wire};
11
12pub unsafe trait AsDecoder<'de> {
21 type Decoder: Decoder<'de>;
23
24 fn as_decoder(&'de mut self) -> Self::Decoder;
26}
27
28unsafe impl<'de> AsDecoder<'de> for Vec<Chunk> {
31 type Decoder = &'de mut [Chunk];
32
33 fn as_decoder(&'de mut self) -> Self::Decoder {
34 self.as_mut_slice()
35 }
36}
37
38pub trait AsDecoderExt: for<'de> AsDecoder<'de> {
40 fn into_decoded<T>(self) -> Result<Decoded<T, Self>, DecodeError>
45 where
46 Self: for<'de> AsDecoder<'de> + Sized,
47 T: Wire<Constraint = ()>,
48 for<'de> T::Narrowed<'de>: Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = ()>;
49
50 fn into_decoded_with_constraint<T>(
55 self,
56 constraint: T::Constraint,
57 ) -> Result<Decoded<T, Self>, DecodeError>
58 where
59 Self: for<'de> AsDecoder<'de> + Sized,
60 T: Wire,
61 for<'de> T::Narrowed<'de>:
62 Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = T::Constraint>;
63}
64
65impl<D: for<'de> AsDecoder<'de>> AsDecoderExt for D {
66 fn into_decoded<T>(self) -> Result<Decoded<T, Self>, DecodeError>
67 where
68 Self: for<'de> AsDecoder<'de> + Sized,
69 T: Wire<Constraint = ()>,
70 for<'de> T::Narrowed<'de>: Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = ()>,
71 {
72 Self::into_decoded_with_constraint::<T>(self, ())
73 }
74
75 fn into_decoded_with_constraint<T>(
76 mut self,
77 constraint: T::Constraint,
78 ) -> Result<Decoded<T, Self>, DecodeError>
79 where
80 Self: for<'de> AsDecoder<'de> + Sized,
81 T: Wire,
82 for<'de> T::Narrowed<'de>:
83 Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = T::Constraint>,
84 {
85 let mut decoder = self.as_decoder();
86 let mut slot = decoder.take_slot::<T::Narrowed<'_>>()?;
87 T::Narrowed::decode(slot.as_mut(), &mut decoder, constraint)?;
88 decoder.commit();
89 decoder.finish()?;
90
91 let ptr = unsafe { NonNull::new_unchecked(slot.as_mut_ptr().cast()) };
94 drop(decoder);
95 Ok(Decoded { ptr, decoder: ManuallyDrop::new(self) })
96 }
97}
98
99pub struct Decoded<T: ?Sized, D> {
101 ptr: NonNull<T>,
102 decoder: ManuallyDrop<D>,
103}
104
105unsafe impl<T: Send + ?Sized, D: Send> Send for Decoded<T, D> {}
108
109unsafe impl<T: Sync + ?Sized, D: Sync> Sync for Decoded<T, D> {}
112
113impl<T: ?Sized, D> Drop for Decoded<T, D> {
114 fn drop(&mut self) {
115 unsafe {
118 self.ptr.as_ptr().drop_in_place();
119 }
120 unsafe {
122 ManuallyDrop::drop(&mut self.decoder);
123 }
124 }
125}
126
127impl<T: ?Sized, D> Decoded<T, D> {
128 pub unsafe fn new_unchecked(ptr: *mut T, decoder: D) -> Self {
135 Self { ptr: unsafe { NonNull::new_unchecked(ptr) }, decoder: ManuallyDrop::new(decoder) }
137 }
138
139 pub fn into_raw_parts(mut self) -> (*mut T, D) {
141 let ptr = self.ptr.as_ptr();
142 let decoder = unsafe { ManuallyDrop::take(&mut self.decoder) };
145 forget(self);
146 (ptr, decoder)
147 }
148
149 pub fn take(self) -> T::Natural
154 where
155 T: Wire + IntoNatural,
156 T::Natural: for<'de> FromWire<T::Narrowed<'de>>,
157 {
158 self.take_as::<T::Natural>()
159 }
160
161 pub fn take_as<U>(self) -> U
165 where
166 T: Wire,
167 U: for<'de> FromWire<T::Narrowed<'de>>,
168 {
169 self.take_with(|wire| U::from_wire(wire))
170 }
171
172 pub fn take_with<U>(self, f: impl for<'de> FnOnce(T::Narrowed<'de>) -> U) -> U
176 where
177 T: Wire,
178 {
179 let (ptr, decoder) = self.into_raw_parts();
180 let value = unsafe { ptr.cast::<T::Narrowed<'_>>().read() };
183 let result = f(value);
184 drop(decoder);
185 result
186 }
187}
188
189impl<T: ?Sized, B> Deref for Decoded<T, B> {
190 type Target = T;
191
192 fn deref(&self) -> &Self::Target {
193 unsafe { self.ptr.as_ref() }
196 }
197}
198
199impl<T: fmt::Debug + ?Sized, B: fmt::Debug> fmt::Debug for Decoded<T, B> {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 self.deref().fmt(f)
202 }
203}