1// Copyright 2025 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_iovec_t;
6use std::ops::Deref;
78/// A reference to a readable slice of memory for IOB writes, analogous to `std::io::IoSlice` but
9/// for Zircon IOB I/O. ABI-compatible with `zx_iovec_t`, guaranteeing the pointed-to bytes are
10/// readable using lifetimes.
11#[derive(Copy, Clone)]
12#[repr(transparent)]
13pub struct IobIoSlice<'a>(zx_iovec_t, std::marker::PhantomData<&'a [u8]>);
1415impl<'a> IobIoSlice<'a> {
16/// Convert a Rust byte slice to a `IobIoSlice`. If the input slice is longer than can be
17 /// referenced by a `zx_iovec_t` the length will be truncated.
18pub fn new(buf: &'a [u8]) -> Self {
19Self(zx_iovec_t { buffer: buf.as_ptr(), capacity: buf.len() }, std::marker::PhantomData)
20 }
21}
2223impl<'a> Deref for IobIoSlice<'a> {
24type Target = [u8];
25fn deref(&self) -> &[u8] {
26// SAFETY: lifetime marker guarantees these bytes are still live.
27unsafe { std::slice::from_raw_parts(self.0.buffer, self.0.capacity as usize) }
28 }
29}
3031impl<'a> std::cmp::PartialEq for IobIoSlice<'a> {
32fn eq(&self, rhs: &Self) -> bool {
33self.deref().eq(rhs.deref())
34 }
35}
36impl<'a> std::cmp::Eq for IobIoSlice<'a> {}
3738impl<'a> std::hash::Hash for IobIoSlice<'a> {
39fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
40self.deref().hash(h)
41 }
42}
4344impl<'a> std::fmt::Debug for IobIoSlice<'a> {
45fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46self.deref().fmt(f)
47 }
48}
4950// SAFETY: this type has no meaningful drop impl other than releasing its borrow.
51unsafe impl<'a> Send for IobIoSlice<'a> {}
5253// SAFETY: this type has no mutability.
54unsafe impl<'a> Sync for IobIoSlice<'a> {}