fidl_next_codec/fuchsia/
channel.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    munge, Decode, DecodeError, Encodable, EncodableOption, Encode, EncodeError, EncodeOption,
10    FromWire, FromWireOption, Slot, Wire,
11};
12
13use zx::sys::zx_handle_t;
14use zx::{Channel, Handle};
15
16/// A Zircon channel.
17#[derive(Debug)]
18#[repr(transparent)]
19pub struct WireChannel {
20    handle: WireHandle,
21}
22
23unsafe impl Wire for WireChannel {
24    type Decoded<'de> = Self;
25
26    #[inline]
27    fn zero_padding(out: &mut MaybeUninit<Self>) {
28        munge!(let Self { handle } = out);
29        WireHandle::zero_padding(handle);
30    }
31}
32
33impl WireChannel {
34    /// Encodes a channel as present in an output.
35    pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
36        munge!(let Self { handle } = out);
37        WireHandle::set_encoded_present(handle);
38    }
39
40    /// Returns whether the underlying `zx_handle_t` is invalid.
41    pub fn is_invalid(&self) -> bool {
42        self.handle.is_invalid()
43    }
44
45    /// Returns the underlying [`zx_handle_t`].
46    #[inline]
47    pub fn as_raw_handle(&self) -> zx_handle_t {
48        self.handle.as_raw_handle()
49    }
50}
51
52unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for WireChannel {
53    fn decode(mut slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
54        munge!(let Self { handle } = slot.as_mut());
55        WireHandle::decode(handle, decoder)
56    }
57}
58
59/// An optional Zircon channel.
60#[derive(Debug)]
61#[repr(transparent)]
62pub struct WireOptionalChannel {
63    handle: WireOptionalHandle,
64}
65
66unsafe impl Wire for WireOptionalChannel {
67    type Decoded<'de> = Self;
68
69    #[inline]
70    fn zero_padding(out: &mut MaybeUninit<Self>) {
71        munge!(let Self { handle } = out);
72        WireOptionalHandle::zero_padding(handle);
73    }
74}
75
76impl WireOptionalChannel {
77    /// Encodes a channel as present in an output.
78    pub fn set_encoded_present(out: &mut MaybeUninit<Self>) {
79        munge!(let Self { handle } = out);
80        WireOptionalHandle::set_encoded_present(handle);
81    }
82
83    /// Encodes a channel as absent in an output.
84    pub fn set_encoded_absent(out: &mut MaybeUninit<Self>) {
85        munge!(let Self { handle } = out);
86        WireOptionalHandle::set_encoded_absent(handle);
87    }
88
89    /// Returns whether a channel is present.
90    pub fn is_some(&self) -> bool {
91        !self.handle.is_some()
92    }
93
94    /// Returns whether a channel is absent.
95    pub fn is_none(&self) -> bool {
96        self.handle.is_none()
97    }
98
99    /// Returns the underlying [`zx_handle_t`], if any.
100    #[inline]
101    pub fn as_raw_handle(&self) -> Option<zx_handle_t> {
102        self.handle.as_raw_handle()
103    }
104}
105
106unsafe impl<D: HandleDecoder + ?Sized> Decode<D> for WireOptionalChannel {
107    fn decode(mut slot: Slot<'_, Self>, decoder: &mut D) -> Result<(), DecodeError> {
108        munge!(let Self { handle } = slot.as_mut());
109        WireOptionalHandle::decode(handle, decoder)
110    }
111}
112
113impl Encodable for Channel {
114    type Encoded = WireChannel;
115}
116
117unsafe impl<E: HandleEncoder + ?Sized> Encode<E> for Channel {
118    fn encode(
119        self,
120        encoder: &mut E,
121        out: &mut MaybeUninit<Self::Encoded>,
122    ) -> Result<(), EncodeError> {
123        munge!(let WireChannel { handle } = out);
124        Handle::from(self).encode(encoder, handle)
125    }
126}
127
128impl FromWire<WireChannel> for Channel {
129    fn from_wire(wire: WireChannel) -> Self {
130        Handle::from_wire(wire.handle).into()
131    }
132}
133
134impl EncodableOption for Channel {
135    type EncodedOption = WireOptionalChannel;
136}
137
138unsafe impl<E: HandleEncoder + ?Sized> EncodeOption<E> for Channel {
139    fn encode_option(
140        this: Option<Self>,
141        encoder: &mut E,
142        out: &mut MaybeUninit<Self::EncodedOption>,
143    ) -> Result<(), EncodeError> {
144        munge!(let WireOptionalChannel { handle } = out);
145        Handle::encode_option(this.map(Handle::from), encoder, handle)
146    }
147}
148
149impl FromWireOption<WireOptionalChannel> for Channel {
150    fn from_wire_option(wire: WireOptionalChannel) -> Option<Self> {
151        Handle::from_wire_option(wire.handle).map(Channel::from)
152    }
153}