fidl_next_codec/fuchsia/
mod.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
5//! Fuchsia-specific extensions to the FIDL codec.
6
7mod handle;
8mod handle_types;
9mod object_type;
10mod rights;
11
12use zx::Handle;
13use zx::sys::zx_handle_t;
14
15use crate::decoder::InternalHandleDecoder;
16use crate::encoder::InternalHandleEncoder;
17use crate::{DecodeError, EncodeError};
18
19pub use self::handle::*;
20pub use self::handle_types::*;
21pub use self::object_type::*;
22pub use self::rights::*;
23pub use zx;
24
25/// A decoder which support Zircon handles.
26pub trait HandleDecoder: InternalHandleDecoder {
27    /// Takes the next raw handle from the decoder.
28    ///
29    /// The returned raw handle must not be considered owned until the decoder is committed.
30    fn take_raw_handle(&mut self) -> Result<zx_handle_t, DecodeError>;
31
32    /// Returns the number of handles remaining in the decoder.
33    fn handles_remaining(&mut self) -> usize;
34
35    /// Takes the next raw driver handle from the decoder.
36    #[doc(hidden)]
37    fn take_raw_driver_handle(&mut self) -> Result<u32, DecodeError> {
38        Err(DecodeError::DriverHandlesUnsupported)
39    }
40}
41
42/// An encoder which supports Zircon handles.
43pub trait HandleEncoder: InternalHandleEncoder {
44    /// Pushes a handle into the encoder.
45    fn push_handle(&mut self, handle: Handle) -> Result<(), EncodeError>;
46
47    /// Returns the number of handles added to the encoder.
48    fn handles_pushed(&self) -> usize;
49
50    /// Pushes a raw driver handle into the encoder.
51    ///
52    /// # Safety
53    ///
54    /// `raw_driver_handle` must be a valid `DriverHandle`. Calling
55    /// `push_raw_driver_Handle` moves ownership of the handle into the encoder.
56    #[doc(hidden)]
57    unsafe fn push_raw_driver_handle(
58        &mut self,
59        #[allow(unused)] raw_driver_handle: u32,
60    ) -> Result<(), EncodeError> {
61        Err(EncodeError::DriverHandlesUnsupported)
62    }
63}
64
65// TODO: `HandleDecoder` and `HandleEncoder` have terrible little methods:
66// `take_raw_driver_handle` and `push_raw_driver_handle`. These exist because of
67// two intersecting problems:
68//
69// 1. When writing `Encode` and `Decode` impls for a type, it can't just add
70//    `where` clauses bounding `<field_ty>: Encode<___E>`. This is because some
71//    FIDL type definitions are recursive, and Rust impls can't be coinductive.
72//    So instead, we have to check whether the type is a `resource` and emit
73//    `E: HandleEncoder` if it is.
74//
75// 2. The FIDL IR only tracks whether or not a type is a resource. It doesn't
76//    track which resource types it contains. That means that if a type is a
77//    resource, we don't know whether that's because it contains a handle, or
78//    because it contains a driver handle.
79//
80// So the unfortunate result is that we have to combine all of the resource type
81// encoding and decoding traits into a single one. If we fix this someday, then
82// we can get rid of those methods and make separate `DriverHandleDecoder` and
83// `DriverHandleEncoder` types.
84//
85// /// A decoder which support driver handles.
86// pub trait DriverHandleDecoder: InternalHandleDecoder {
87//     /// Takes the next raw driver handle from the decoder.
88//     ///
89//     /// The returned raw driver handle must not be considered owned until the decoder is committed.
90//     fn take_raw_driver_handle(&mut self) -> Result<fdf_handle_t, DecodeError>;
91//
92//     /// Returns the number of driver handles remaining in the decoder.
93//     fn driver_handles_remaining(&mut self) -> usize;
94// }
95//
96// /// An encoder which supports Zircon handles.
97// pub trait DriverHandleEncoder: InternalHandleEncoder {
98//     /// Pushes a driver handle into the encoder.
99//     fn push_driver_handle(&mut self, handle: DriverHandle) -> Result<(), EncodeError>;
100//
101//     /// Returns the number of driver handles added to the encoder.
102//     fn driver_handles_pushed(&self) -> usize;
103// }