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.
45use crate::sys::zx_channel_iovec_t;
6use std::ops::Deref;
78/// 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]>);
1415impl<'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.
19pub fn new(buf: &'a [u8]) -> Self {
20let mut inner = zx_channel_iovec_t::default();
21 inner.buffer = buf.as_ptr();
22 inner.capacity = buf.len() as u32;
23Self(inner, std::marker::PhantomData)
24 }
25}
2627impl<'a> Deref for ChannelIoSlice<'a> {
28type Target = [u8];
29fn deref(&self) -> &[u8] {
30// SAFETY: lifetime marker guarantees these bytes are still live.
31unsafe { std::slice::from_raw_parts(self.0.buffer, self.0.capacity as usize) }
32 }
33}
3435impl<'a> std::cmp::PartialEq for ChannelIoSlice<'a> {
36fn eq(&self, rhs: &Self) -> bool {
37self.deref().eq(rhs.deref())
38 }
39}
40impl<'a> std::cmp::Eq for ChannelIoSlice<'a> {}
4142impl<'a> std::hash::Hash for ChannelIoSlice<'a> {
43fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
44self.deref().hash(h)
45 }
46}
4748impl<'a> std::fmt::Debug for ChannelIoSlice<'a> {
49fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50self.deref().fmt(f)
51 }
52}
5354// SAFETY: this type has no meaningful drop impl other than releasing its borrow.
55unsafe impl<'a> Send for ChannelIoSlice<'a> {}
5657// SAFETY: this type has no mutability.
58unsafe impl<'a> Sync for ChannelIoSlice<'a> {}