1use core::fmt;
8use core::mem::{MaybeUninit, forget};
9use core::num::NonZero;
10
11use fdf_channel::channel::Channel;
12use fdf_core::handle::{DriverHandle, fdf_handle_t};
13use fidl_next::fuchsia::{HandleDecoder, HandleEncoder};
14use fidl_next::{
15 Constrained, Decode, DecodeError, Encode, EncodeError, EncodeOption, FromWire, FromWireOption,
16 IntoNatural, Slot, ValidationError, Wire, munge, wire,
17};
18
19#[repr(C, align(4))]
25pub union DriverChannel {
26 encoded: wire::Uint32,
27 decoded: fdf_handle_t,
28}
29
30impl Drop for DriverChannel {
31 fn drop(&mut self) {
32 let raw_handle = unsafe { NonZero::new_unchecked(self.as_raw_handle()) };
34 let handle = unsafe { DriverHandle::new_unchecked(raw_handle) };
36 drop(handle);
37 }
38}
39
40impl Constrained for DriverChannel {
41 type Constraint = ();
42
43 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
44 Ok(())
45 }
46}
47
48unsafe impl Wire for DriverChannel {
52 type Narrowed<'de> = Self;
53
54 #[inline]
55 fn zero_padding(_: &mut MaybeUninit<Self>) {
56 }
58}
59
60impl DriverChannel {
61 pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
63 let encoded = unsafe {
67 munge!(let Self { encoded } = out);
68 encoded
69 };
70 encoded.write(wire::Uint32(u32::MAX));
71 }
72
73 #[inline]
75 pub fn as_raw_handle(&self) -> fdf_handle_t {
76 unsafe { self.decoded }
79 }
80}
81
82impl fmt::Debug for DriverChannel {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 self.as_raw_handle().fmt(f)
85 }
86}
87
88unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for DriverChannel {
91 fn decode(
92 mut slot: Slot<'_, Self>,
93 decoder: &mut D,
94 _: <Self as Constrained>::Constraint,
95 ) -> Result<(), DecodeError> {
96 let encoded = unsafe {
99 munge!(let Self { encoded } = slot.as_mut());
100 encoded
101 };
102
103 match **encoded {
104 u32::MAX => {
105 let handle = decoder.take_raw_driver_handle()?;
106 let mut decoded = unsafe {
109 munge!(let Self { decoded } = slot);
110 decoded
111 };
112 decoded.write(handle);
113 }
114 e => return Err(DecodeError::InvalidHandlePresence(e)),
115 }
116 Ok(())
117 }
118}
119
120#[repr(C, align(4))]
126pub union OptionalDriverChannel {
127 encoded: wire::Uint32,
128 decoded: fdf_handle_t,
129}
130
131impl Drop for OptionalDriverChannel {
132 fn drop(&mut self) {
133 if let Some(handle) = self.as_raw_handle() {
134 let handle = unsafe { NonZero::new_unchecked(handle) };
137 let handle = unsafe { DriverHandle::new_unchecked(handle) };
139 drop(handle);
140 }
141 }
142}
143
144impl Constrained for OptionalDriverChannel {
145 type Constraint = ();
146
147 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
148 Ok(())
149 }
150}
151
152unsafe impl Wire for OptionalDriverChannel {
156 type Narrowed<'de> = Self;
157
158 #[inline]
159 fn zero_padding(_: &mut MaybeUninit<Self>) {
160 }
162}
163
164impl OptionalDriverChannel {
165 pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
167 let encoded = unsafe {
171 munge!(let Self { encoded } = out);
172 encoded
173 };
174 encoded.write(wire::Uint32(u32::MAX));
175 }
176
177 pub fn set_encoded_absent(out: &mut MaybeUninit<Self>) {
179 let encoded = unsafe {
183 munge!(let Self { encoded } = out);
184 encoded
185 };
186 encoded.write(wire::Uint32(0));
187 }
188
189 pub fn is_some(&self) -> bool {
191 self.as_raw_handle().is_some()
192 }
193
194 pub fn is_none(&self) -> bool {
196 self.as_raw_handle().is_none()
197 }
198
199 #[inline]
201 pub fn as_raw_handle(&self) -> Option<fdf_handle_t> {
202 let decoded = unsafe { self.decoded };
205 if decoded == 0 { None } else { Some(decoded) }
206 }
207}
208
209unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for OptionalDriverChannel {
213 fn decode(
214 mut slot: Slot<'_, Self>,
215 decoder: &mut D,
216 _: <Self as Constrained>::Constraint,
217 ) -> Result<(), DecodeError> {
218 let encoded = unsafe {
221 munge!(let Self { encoded } = slot.as_mut());
222 encoded
223 };
224
225 match **encoded {
226 0 => (),
227 u32::MAX => {
228 let handle = decoder.take_raw_driver_handle()?;
229 let mut decoded = unsafe {
232 munge!(let Self { decoded } = slot);
233 decoded
234 };
235 decoded.write(handle);
236 }
237 e => return Err(DecodeError::InvalidHandlePresence(e)),
238 }
239 Ok(())
240 }
241}
242
243unsafe impl<E: HandleEncoder + ?Sized> Encode<DriverChannel, E> for crate::DriverChannel {
246 fn encode(
247 self,
248 encoder: &mut E,
249 out: &mut MaybeUninit<DriverChannel>,
250 _: (),
251 ) -> Result<(), EncodeError> {
252 let handle = self.channel.into_driver_handle();
253 unsafe {
255 encoder.push_raw_driver_handle(handle.into_raw().get())?;
256 }
257 DriverChannel::set_encoded_present(out);
258 Ok(())
259 }
260}
261
262impl FromWire<DriverChannel> for crate::DriverChannel {
263 fn from_wire(wire: DriverChannel) -> Self {
264 let raw_handle = unsafe { NonZero::new_unchecked(wire.as_raw_handle()) };
266 let handle = unsafe { DriverHandle::new_unchecked(raw_handle) };
268 let channel = unsafe { Channel::from_driver_handle(handle) };
270 forget(wire);
271 crate::DriverChannel::new(channel)
272 }
273}
274
275impl IntoNatural for DriverChannel {
276 type Natural = crate::DriverChannel;
277}
278
279unsafe impl<E: HandleEncoder + ?Sized> EncodeOption<OptionalDriverChannel, E>
282 for crate::DriverChannel
283{
284 fn encode_option(
285 this: Option<Self>,
286 encoder: &mut E,
287 out: &mut MaybeUninit<OptionalDriverChannel>,
288 _: (),
289 ) -> Result<(), EncodeError> {
290 if let Some(driver_channel) = this {
291 let handle = driver_channel.channel.into_driver_handle();
292 unsafe {
294 encoder.push_raw_driver_handle(handle.into_raw().get())?;
295 }
296 OptionalDriverChannel::set_encoded_present(out);
297 } else {
298 OptionalDriverChannel::set_encoded_absent(out);
299 }
300 Ok(())
301 }
302}
303
304impl FromWireOption<OptionalDriverChannel> for crate::DriverChannel {
305 fn from_wire_option(wire: OptionalDriverChannel) -> Option<Self> {
306 let raw_handle = wire.as_raw_handle();
307 forget(wire);
308 raw_handle.map(|raw| {
309 let raw_handle = unsafe { NonZero::new_unchecked(raw) };
312 let handle = unsafe { DriverHandle::new_unchecked(raw_handle) };
315 let channel = unsafe { Channel::from_driver_handle(handle) };
317 crate::DriverChannel::new(channel)
318 })
319 }
320}
321
322impl IntoNatural for OptionalDriverChannel {
323 type Natural = Option<crate::DriverChannel>;
324}
325
326#[cfg(test)]
327mod tests {
328 use fdf_channel::arena::Arena;
329 use fdf_channel::message::Message;
330 use fdf_core::handle::MixedHandleType;
331 use fidl_next::{AsDecoderExt as _, Chunk, EncoderExt as _, chunks};
332
333 use crate::{RecvBuffer, SendBuffer};
334
335 use super::*;
336
337 #[test]
338 fn roundtrip() {
339 let (channel, _) = Channel::<[Chunk]>::create();
340 let handle_raw = unsafe { channel.driver_handle().get_raw() };
342 let driver_channel = crate::DriverChannel::new(channel);
343
344 let encoder = SendBuffer::encode(driver_channel).unwrap();
345
346 assert_eq!(encoder.handles.len(), 1);
347 let driver_ref = encoder.handles[0].as_ref().unwrap().resolve_ref();
348 let MixedHandleType::Driver(handle) = &driver_ref else {
349 panic!("expected a driver handle");
350 };
351 assert_eq!(unsafe { handle.get_raw() }, handle_raw);
352 assert_eq!(encoder.data, chunks![0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00],);
353
354 let arena = Arena::new();
355 let data = arena.insert_boxed_slice(encoder.data.into_boxed_slice());
356 let handles = arena.insert_boxed_slice(encoder.handles.into_boxed_slice());
357 let buffer = Some(Message::new(&arena, Some(data), Some(handles)));
358 let decoder = RecvBuffer { message: buffer };
359
360 let decoded = decoder.into_decoded::<DriverChannel>().unwrap();
361 assert_eq!(decoded.as_raw_handle(), handle_raw.get());
362
363 let handle = decoded.take();
364 let roundtripped_raw = unsafe { handle.channel.driver_handle().get_raw() };
365 assert_eq!(roundtripped_raw, handle_raw);
366 }
367
368 #[test]
369 fn roundtrip_some() {
370 let (channel, _) = Channel::<[Chunk]>::create();
371 let handle_raw = unsafe { channel.driver_handle().get_raw() };
373 let driver_channel = crate::DriverChannel::new(channel);
374
375 let encoder = SendBuffer::encode(Some(driver_channel)).unwrap();
376
377 assert_eq!(encoder.handles.len(), 1);
378 let driver_ref = encoder.handles[0].as_ref().unwrap().resolve_ref();
379 let MixedHandleType::Driver(handle) = &driver_ref else {
380 panic!("expected a driver handle");
381 };
382 assert_eq!(unsafe { handle.get_raw() }, handle_raw);
383 assert_eq!(encoder.data, chunks![0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00],);
384
385 let arena = Arena::new();
386 let data = arena.insert_boxed_slice(encoder.data.into_boxed_slice());
387 let handles = arena.insert_boxed_slice(encoder.handles.into_boxed_slice());
388 let buffer = Some(Message::new(&arena, Some(data), Some(handles)));
389 let decoder = RecvBuffer { message: buffer };
390
391 let decoded = decoder.into_decoded::<OptionalDriverChannel>().unwrap();
392 assert_eq!(decoded.as_raw_handle(), Some(handle_raw.get()));
393
394 let handle = decoded.take();
395 let roundtripped_raw = unsafe { handle.unwrap().channel.driver_handle().get_raw() };
396 assert_eq!(roundtripped_raw, handle_raw);
397 }
398
399 #[test]
400 fn roundtrip_none() {
401 let encoder = SendBuffer::encode(None::<crate::DriverChannel>).unwrap();
402
403 assert_eq!(encoder.handles.len(), 0);
404 assert_eq!(encoder.data, chunks![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],);
405
406 let arena = Arena::new();
407 let data = arena.insert_boxed_slice(encoder.data.into_boxed_slice());
408 let handles = arena.insert_boxed_slice(encoder.handles.into_boxed_slice());
409 let buffer = Some(Message::new(&arena, Some(data), Some(handles)));
410 let decoder = RecvBuffer { message: buffer };
411
412 let decoded = decoder.into_decoded::<OptionalDriverChannel>().unwrap();
413 assert_eq!(decoded.as_raw_handle(), None);
414
415 let handle = decoded.take();
416 assert!(handle.is_none());
417 }
418}