1use core::mem::MaybeUninit;
6
7use crate::fuchsia::{HandleDecoder, HandleEncoder, WireHandle, WireOptionalHandle};
8use crate::{
9 Constrained, Decode, DecodeError, Encode, EncodeError, EncodeOption, FromWire, FromWireOption,
10 IntoNatural, Slot, Unconstrained, 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 Owned<'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 pub fn is_invalid(&self) -> bool {
44 self.handle.is_invalid()
45 }
46
47 #[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, constraint: <Self as Constrained>::Constraint) -> Result<(), DecodeError> {
56 munge!(let Self { handle } = slot.as_mut());
57 WireHandle::decode(handle, decoder, constraint)
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 Owned<'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 #[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, constraint: <Self as Constrained>::Constraint) -> Result<(), DecodeError> {
110 munge!(let Self { handle } = slot.as_mut());
111 WireOptionalHandle::decode(handle, decoder, constraint)
112 }
113 }
114
115 unsafe impl<E: HandleEncoder + ?Sized> Encode<$wire, E> for zx::$natural {
116 fn encode(
117 self,
118 encoder: &mut E,
119 out: &mut MaybeUninit<$wire>,
120 constraint: <$wire as Constrained>::Constraint,
121 ) -> Result<(), EncodeError> {
122 munge!(let $wire { handle } = out);
123 Handle::from(self).encode(encoder, handle, constraint)
124 }
125 }
126
127 impl FromWire<$wire> for zx::$natural {
128 fn from_wire(wire: $wire) -> Self {
129 Handle::from_wire(wire.handle).into()
130 }
131 }
132
133 impl IntoNatural for $wire {
134 type Natural = zx::$natural;
135 }
136
137 unsafe impl<E: HandleEncoder + ?Sized> EncodeOption<$wire_optional, E> for zx::$natural {
138 fn encode_option(
139 this: Option<Self>,
140 encoder: &mut E,
141 out: &mut MaybeUninit<$wire_optional>,
142 constraint: (),
143 ) -> Result<(), EncodeError> {
144 munge!(let $wire_optional { handle } = out);
145 Encode::encode(this.map(Handle::from), encoder, handle, constraint)
146 }
147 }
148
149 impl FromWireOption<$wire_optional> for zx::$natural {
150 fn from_wire_option(wire: $wire_optional) -> Option<Self> {
151 Handle::from_wire_option(wire.handle).map(zx::$natural::from)
152 }
153 }
154
155 impl IntoNatural for $wire_optional {
156 type Natural = Option<zx::$natural>;
157 }
158
159 impl Unconstrained for $wire {}
161 impl Unconstrained for $wire_optional {}
162 )* };
163}
164
165define_wire_handle_types! {
166 WireProcess(WireOptionalProcess): Process,
167 WireThread(WireOptionalThread): Thread,
168 WireVmo(WireOptionalVmo): Vmo,
169 WireChannel(WireOptionalChannel): Channel,
170 WireEvent(WireOptionalEvent): Event,
171 WirePort(WireOptionalPort): Port,
172 WireInterrupt(WireOptionalInterrupt): Interrupt,
173 WireDebugLog(WireOptionalDebugLog): DebugLog,
175 WireSocket(WireOptionalSocket): Socket,
176 WireResource(WireOptionalResource): Resource,
177 WireEventPair(WireOptionalEventPair): EventPair,
178 WireJob(WireOptionalJob): Job,
179 WireVmar(WireOptionalVmar): Vmar,
180 WireFifo(WireOptionalFifo): Fifo,
181 WireGuest(WireOptionalGuest): Guest,
182 WireVcpu(WireOptionalVcpu): Vcpu,
183 WireTimer(WireOptionalTimer): Timer,
184 WireIommu(WireOptionalIommu): Iommu,
185 WireBti(WireOptionalBti): Bti,
186 WireProfile(WireOptionalProfile): Profile,
187 WirePmt(WireOptionalPmt): Pmt,
188 WirePager(WireOptionalPager): Pager,
190 WireException(WireOptionalException): Exception,
191 WireClock(WireOptionalClock): Clock,
192 WireStream(WireOptionalStream): Stream,
193 WireIob(WireOptionalIob): Iob,
195 WireCounter(WireOptionalCounter): Counter,
196}