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    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            /// 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, 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            /// 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, 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        // TODO: validate handle rights.
160        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    // WirePciDevice(WireOptionalPciDevice): PciDevice,
174    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    // WireSuspendToken(WireOptionalSuspendToken): SuspendToken,
189    WirePager(WireOptionalPager): Pager,
190    WireException(WireOptionalException): Exception,
191    WireClock(WireOptionalClock): Clock,
192    WireStream(WireOptionalStream): Stream,
193    // WireMsi(WireOptionalMsi): Msi,
194    WireIob(WireOptionalIob): Iob,
195    WireCounter(WireOptionalCounter): Counter,
196}