//! Extension traits for converting `Ref` into references backed by //! standard slices. use zerocopy::{Immutable, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut}; /// A trait for converting a `Ref` into a `Ref<&[u8], T>`. /// /// This can be useful when you need a reference that is tied to a slice rather /// than the original buffer type `B`. /// /// Note: This trait is implemented to [`Ref`] of byte slices (`&[u8]`). pub trait ZerocopyEmancipateExt { /// Converts this reference into a reference backed by a plain byte slice. /// /// # Example /// /// ``` /// # use std::ops::Deref; /// # use zerocopy::{IntoBytes, SplitByteSlice, FromBytes, FromZeros, Ref, Immutable, KnownLayout}; /// # use rosenpass_util::zerocopy::ZerocopyEmancipateExt; /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] /// #[repr(C)] /// struct Data(u32); /// #[repr(align(4))] /// struct AlignedBuf([u8; 4]); /// let bytes = AlignedBuf([0xAA, 0xBB, 0xCC, 0xDD]); /// let r = Ref::<&[u8], Data>::new(&bytes.0).unwrap(); /// let emancipated: Ref<&[u8], Data> = r.emancipate(); // same data, but guaranteed &[u8] backing /// assert_eq!(emancipated.0, 0xDDCCBBAA); /// ``` fn emancipate(&self) -> Ref<&[u8], T>; } /// A trait for converting a `Ref` into a mutable `Ref<&mut [u8], T>`. /// /// Similar to [`ZerocopyEmancipateExt`], but for mutable references. /// /// Note: this trait is implemented to [`Ref`] of mutable byte /// slices (`&mut [u8]`). pub trait ZerocopyEmancipateMutExt { /// Converts this reference into a mutable reference backed by a plain /// mutable byte slice. /// /// # Example /// /// ``` /// # use zerocopy::{IntoBytes, FromBytes, Ref, Immutable, KnownLayout}; /// # use rosenpass_util::zerocopy::{ZerocopyEmancipateMutExt}; /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] /// #[repr(C)] /// struct Data(u32); /// #[repr(align(4))] /// struct AlignedBuf([u8; 4]); /// let mut bytes = AlignedBuf([0xAA, 0xBB, 0xCC, 0xDD]); /// let mut r = Ref::<&mut [u8], Data>::new(&mut bytes.0).unwrap(); /// let mut emancipated: Ref<&mut [u8], Data> = r.emancipate_mut(); // same data, but guaranteed &[u8] backing /// assert_eq!(emancipated.0, 0xDDCCBBAA); /// emancipated.0 = 0x33221100; /// drop(emancipated); /// assert_eq!(bytes.0, [0x00, 0x11, 0x22, 0x33]); /// ``` fn emancipate_mut(&mut self) -> Ref<&mut [u8], T>; } impl ZerocopyEmancipateExt for Ref where B: SplitByteSlice, T: KnownLayout + Immutable, { fn emancipate(&self) -> Ref<&[u8], T> { Ref::from_bytes(zerocopy::Ref::bytes(self)).unwrap() } } impl ZerocopyEmancipateMutExt for Ref where B: SplitByteSliceMut, T: KnownLayout + Immutable, { fn emancipate_mut(&mut self) -> Ref<&mut [u8], T> { Ref::from_bytes(zerocopy::Ref::bytes_mut(self)).unwrap() } }