fidl_next_codec/fuchsia/
handle_types.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::mem::MaybeUninit;
6
7use crate::fuchsia::{HandleDecoder, HandleEncoder, WireHandle, WireOptionalHandle};
8use crate::{
9    Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError, EncodeOption, FromWire,
10    FromWireOption, Slot, Wire, munge,
11};
12
13use zx::Handle;
14use zx::sys::zx_handle_t;
15
16macro_rules! define_wire_handle_types {
17    ($($wire:ident($wire_optional:ident): $natural:ident),* $(,)?) => { $(
18        #[doc = concat!("A Zircon ", stringify!($natural), ".")]
19        #[derive(Debug)]
20        #[repr(transparent)]
21        pub struct $wire {
22            handle: WireHandle,
23        }
24
25        unsafe impl Wire for $wire {
26            type Decoded<'de> = Self;
27
28            #[inline]
29            fn zero_padding(out: &mut MaybeUninit<Self>) {
30                munge!(let Self { handle } = out);
31                WireHandle::zero_padding(handle);
32            }
33        }
34
35        impl $wire {
36            #[doc = concat!("Encodes a ", stringify!($natural), " as present in an output.")]
37            pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
38                munge!(let Self { handle } = out);
39                WireHandle::set_encoded_present(handle);
40            }
41
42            /// Returns whether the underlying `zx_handle_t` is invalid.
43            pub fn is_invalid(&self) -> bool {
44                self.handle.is_invalid()
45            }
46
47            /// Returns the underlying [`zx_handle_t`].
48            #[inline]
49            pub fn as_raw_handle(&self) -> zx_handle_t {
50                self.handle.as_raw_handle()
51            }
52        }
53
54        unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for $wire {
55            fn decode(mut slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
56                munge!(let Self { handle } = slot.as_mut());
57                WireHandle::decode(handle, decoder)
58            }
59        }
60
61        #[doc = concat!("An optional Zircon ", stringify!($natural), ".")]
62        #[derive(Debug)]
63        #[repr(transparent)]
64        pub struct $wire_optional {
65            handle: WireOptionalHandle,
66        }
67
68        unsafe impl Wire for $wire_optional {
69            type Decoded<'de> = Self;
70
71            #[inline]
72            fn zero_padding(out: &mut MaybeUninit<Self>) {
73                munge!(let Self { handle } = out);
74                WireOptionalHandle::zero_padding(handle);
75            }
76        }
77
78        impl $wire_optional {
79            #[doc = concat!("Encodes a ", stringify!($natural), " as present in an output.")]
80            pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
81                munge!(let Self { handle } = out);
82                WireOptionalHandle::set_encoded_present(handle);
83            }
84
85            #[doc = concat!("Encodes a ", stringify!($natural), " as absent in an output.")]
86            pub fn set_encoded_absent(out: &mut MaybeUninit<Self>) {
87                munge!(let Self { handle } = out);
88                WireOptionalHandle::set_encoded_absent(handle);
89            }
90
91            #[doc = concat!("Returns whether a ", stringify!($natural), " is present.")]
92            pub fn is_some(&self) -> bool {
93                !self.handle.is_some()
94            }
95
96            #[doc = concat!("Returns whether a ", stringify!($natural), " is absent.")]
97            pub fn is_none(&self) -> bool {
98                self.handle.is_none()
99            }
100
101            /// Returns the underlying [`zx_handle_t`], if any.
102            #[inline]
103            pub fn as_raw_handle(&self) -> Option<zx_handle_t> {
104                self.handle.as_raw_handle()
105            }
106        }
107
108        unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for $wire_optional {
109            fn decode(mut slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
110                munge!(let Self { handle } = slot.as_mut());
111                WireOptionalHandle::decode(handle, decoder)
112            }
113        }
114
115        impl Encodable for zx::$natural {
116            type Encoded = $wire;
117        }
118
119        unsafe impl<E: HandleEncoder + ?Sized> Encode<E> for zx::$natural {
120            fn encode(
121                self,
122                encoder: &mut E,
123                out: &mut MaybeUninit<Self::Encoded>,
124            ) -> Result<(), EncodeError> {
125                munge!(let $wire { handle } = out);
126                Handle::from(self).encode(encoder, handle)
127            }
128        }
129
130        impl FromWire<$wire> for zx::$natural {
131            fn from_wire(wire: $wire) -> Self {
132                Handle::from_wire(wire.handle).into()
133            }
134        }
135
136        impl EncodableOption for zx::$natural {
137            type EncodedOption = $wire_optional;
138        }
139
140        unsafe impl<E: HandleEncoder + ?Sized> EncodeOption<E> for zx::$natural {
141            fn encode_option(
142                this: Option<Self>,
143                encoder: &mut E,
144                out: &mut MaybeUninit<Self::EncodedOption>,
145            ) -> Result<(), EncodeError> {
146                munge!(let $wire_optional { handle } = out);
147                Handle::encode_option(this.map(Handle::from), encoder, handle)
148            }
149        }
150
151        impl FromWireOption<$wire_optional> for zx::$natural {
152            fn from_wire_option(wire: $wire_optional) -> Option<Self> {
153                Handle::from_wire_option(wire.handle).map(zx::$natural::from)
154            }
155        }
156    )* };
157}
158
159define_wire_handle_types! {
160    WireProcess(WireOptionalProcess): Process,
161    WireThread(WireOptionalThread): Thread,
162    WireVmo(WireOptionalVmo): Vmo,
163    WireChannel(WireOptionalChannel): Channel,
164    WireEvent(WireOptionalEvent): Event,
165    WirePort(WireOptionalPort): Port,
166    WireInterrupt(WireOptionalInterrupt): Interrupt,
167    WireSocket(WireOptionalSocket): Socket,
168    WireResource(WireOptionalResource): Resource,
169    WireEventPair(WireOptionalEventPair): EventPair,
170    WireJob(WireOptionalJob): Job,
171    WireVmar(WireOptionalVmar): Vmar,
172    WireFifo(WireOptionalFifo): Fifo,
173    WireGuest(WireOptionalGuest): Guest,
174    WireVcpu(WireOptionalVcpu): Vcpu,
175    WireTimer(WireOptionalTimer): Timer,
176    WireIommu(WireOptionalIommu): Iommu,
177    WireBti(WireOptionalBti): Bti,
178    WireProfile(WireOptionalProfile): Profile,
179    WirePmt(WireOptionalPmt): Pmt,
180    WirePager(WireOptionalPager): Pager,
181    WireException(WireOptionalException): Exception,
182    WireClock(WireOptionalClock): Clock,
183    WireStream(WireOptionalStream): Stream,
184    WireIob(WireOptionalIob): Iob,
185}