zx/channel/
io_slice.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 crate::sys::zx_channel_iovec_t;
6use std::ops::Deref;
7
8/// A reference to a readable slice of memory for channel writes and calls, analogous to
9/// `std::io::IoSlice` but for Zircon channel I/O. ABI-compatible with `zx_channel_iovec_t`,
10/// guaranteeing the pointed-to bytes are readable using lifetimes.
11#[derive(Copy, Clone)]
12#[repr(transparent)]
13pub struct ChannelIoSlice<'a>(zx_channel_iovec_t, std::marker::PhantomData<&'a [u8]>);
14
15impl<'a> ChannelIoSlice<'a> {
16    /// Convert a Rust byte slice to a `ChannelIoSlice`. If the input slice is longer than can be
17    /// referenced by a `zx_channel_iovec_t` the length will be truncated, although this is
18    /// significantly longer than `ZX_CHANNEL_MAX_MSG_BYTES` in practice.
19    pub fn new(buf: &'a [u8]) -> Self {
20        let mut inner = zx_channel_iovec_t::default();
21        inner.buffer = buf.as_ptr();
22        inner.capacity = buf.len() as u32;
23        Self(inner, std::marker::PhantomData)
24    }
25}
26
27impl<'a> Deref for ChannelIoSlice<'a> {
28    type Target = [u8];
29    fn deref(&self) -> &[u8] {
30        // SAFETY: lifetime marker guarantees these bytes are still live.
31        unsafe { std::slice::from_raw_parts(self.0.buffer, self.0.capacity as usize) }
32    }
33}
34
35impl<'a> std::cmp::PartialEq for ChannelIoSlice<'a> {
36    fn eq(&self, rhs: &Self) -> bool {
37        self.deref().eq(rhs.deref())
38    }
39}
40impl<'a> std::cmp::Eq for ChannelIoSlice<'a> {}
41
42impl<'a> std::hash::Hash for ChannelIoSlice<'a> {
43    fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
44        self.deref().hash(h)
45    }
46}
47
48impl<'a> std::fmt::Debug for ChannelIoSlice<'a> {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        self.deref().fmt(f)
51    }
52}
53
54// SAFETY: this type has no meaningful drop impl other than releasing its borrow.
55unsafe impl<'a> Send for ChannelIoSlice<'a> {}
56
57// SAFETY: this type has no mutability.
58unsafe impl<'a> Sync for ChannelIoSlice<'a> {}