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> {
29 type Decoder = &'de mut [Chunk];
30
31 fn as_decoder(&'de mut self) -> Self::Decoder {
32 self.as_mut_slice()
33 }
34}
35
36pub trait AsDecoderExt: for<'de> AsDecoder<'de> {
38 fn into_decoded<T>(self) -> Result<Decoded<T, Self>, DecodeError>
43 where
44 Self: for<'de> AsDecoder<'de> + Sized,
45 T: Wire<Constraint = ()>,
46 for<'de> T::Narrowed<'de>: Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = ()>;
47
48 fn into_decoded_with_constraint<T>(
53 self,
54 constraint: T::Constraint,
55 ) -> Result<Decoded<T, Self>, DecodeError>
56 where
57 Self: for<'de> AsDecoder<'de> + Sized,
58 T: Wire,
59 for<'de> T::Narrowed<'de>:
60 Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = T::Constraint>;
61}
62
63impl<D: for<'de> AsDecoder<'de>> AsDecoderExt for D {
64 fn into_decoded<T>(self) -> Result<Decoded<T, Self>, DecodeError>
65 where
66 Self: for<'de> AsDecoder<'de> + Sized,
67 T: Wire<Constraint = ()>,
68 for<'de> T::Narrowed<'de>: Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = ()>,
69 {
70 Self::into_decoded_with_constraint::<T>(self, ())
71 }
72
73 fn into_decoded_with_constraint<T>(
74 mut self,
75 constraint: T::Constraint,
76 ) -> Result<Decoded<T, Self>, DecodeError>
77 where
78 Self: for<'de> AsDecoder<'de> + Sized,
79 T: Wire,
80 for<'de> T::Narrowed<'de>:
81 Decode<<Self as AsDecoder<'de>>::Decoder, Constraint = T::Constraint>,
82 {
83 let mut decoder = self.as_decoder();
84 let mut slot = decoder.take_slot::<T::Narrowed<'_>>()?;
85 T::Narrowed::decode(slot.as_mut(), &mut decoder, constraint)?;
86 decoder.commit();
87 decoder.finish()?;
88
89 let ptr = unsafe { NonNull::new_unchecked(slot.as_mut_ptr().cast()) };
90 drop(decoder);
91 Ok(Decoded { ptr, decoder: ManuallyDrop::new(self) })
92 }
93}
94
95pub struct Decoded<T: ?Sized, D> {
97 ptr: NonNull<T>,
98 decoder: ManuallyDrop<D>,
99}
100
101unsafe impl<T: Send + ?Sized, D: Send> Send for Decoded<T, D> {}
104
105unsafe impl<T: Sync + ?Sized, D: Sync> Sync for Decoded<T, D> {}
107
108impl<T: ?Sized, D> Drop for Decoded<T, D> {
109 fn drop(&mut self) {
110 unsafe {
113 self.ptr.as_ptr().drop_in_place();
114 }
115 unsafe {
117 ManuallyDrop::drop(&mut self.decoder);
118 }
119 }
120}
121
122impl<T: ?Sized, D> Decoded<T, D> {
123 pub fn into_raw_parts(mut self) -> (*mut T, D) {
125 let ptr = self.ptr.as_ptr();
126 let decoder = unsafe { ManuallyDrop::take(&mut self.decoder) };
129 forget(self);
130 (ptr, decoder)
131 }
132
133 pub fn take(self) -> T::Natural
138 where
139 T: Wire + IntoNatural,
140 T::Natural: for<'de> FromWire<T::Narrowed<'de>>,
141 {
142 self.take_as::<T::Natural>()
143 }
144
145 pub fn take_as<U>(self) -> U
149 where
150 T: Wire,
151 U: for<'de> FromWire<T::Narrowed<'de>>,
152 {
153 self.take_with(|wire| U::from_wire(wire))
154 }
155
156 pub fn take_with<U>(self, f: impl for<'de> FnOnce(T::Narrowed<'de>) -> U) -> U
160 where
161 T: Wire,
162 {
163 let (ptr, decoder) = self.into_raw_parts();
164 let value = unsafe { ptr.cast::<T::Narrowed<'_>>().read() };
165 let result = f(value);
166 drop(decoder);
167 result
168 }
169}
170
171impl<T: ?Sized, B> Deref for Decoded<T, B> {
172 type Target = T;
173
174 fn deref(&self) -> &Self::Target {
175 unsafe { self.ptr.as_ref() }
178 }
179}
180
181impl<T: fmt::Debug + ?Sized, B: fmt::Debug> fmt::Debug for Decoded<T, B> {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 self.deref().fmt(f)
184 }
185}