From f6d43cd200d3fb4234b98ba8a23e13cfe32b2cca Mon Sep 17 00:00:00 2001 From: Leonora Tindall Date: Sun, 7 Nov 2021 12:53:43 -0600 Subject: [PATCH] feat: add conversion methods --- src/lib.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ebde3ce..8efeae7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,16 @@ use std::slice; /// `MinSlice` is merely a way of reinterpreting an existing slice /// (`&[T]` or `&mut [T]`), and it is exactly the same size as a slice: /// one pointer and one `usize`. +/// +/// # Example +/// +/// ``` +/// # use nslice::MinSlice; +/// let slice: &[u8] = b"Hello, world"; +/// let minslice = MinSlice::::from_slice(slice).unwrap(); +/// let value: u8 = minslice.head[6]; +/// assert_eq!(value, b' ') +/// ``` pub struct MinSlice { /// The bounded region of memory. Exactly `N` `T`s. pub head: [T; N], @@ -47,7 +57,7 @@ impl MinSlice { None } } - + /// Produce a `&mut MinSlice` from a mutable slice of `T`s. /// Returns `None` if there are not enough elements in `slice`. pub fn from_mut(slice: &mut [T]) -> Option<&mut MinSlice> { @@ -57,6 +67,56 @@ impl MinSlice { None } } +} + +impl MinSlice { + /// Returns a slice over the memory referred to by the `MinSlice`. + /// Its length is guaranteed to be no less than `N`. + pub fn as_slice(&self) -> &[T] { + unsafe { slice::from_raw_parts(self.head.as_ptr(), N + self.tail.len()) } + } + + /// Returns a mutable slice over the memory referred to by the `MinSlice`. + /// Its length is guaranteed to be no less than `N`. + pub fn as_mut_slice(&mut self) -> &mut [T] { + unsafe { slice::from_raw_parts_mut(self.head.as_mut_ptr(), N + self.tail.len()) } + } + + /// Resize the `MinSlice`, returning a new `Some(&MinSlice)` + /// if there are at least `M` `T`s in `self`. + pub fn resize(&self) -> Option<&MinSlice> { + MinSlice::::from_slice(self.as_slice()) + } + + /// Resize the `MinSlice`, returning a new `Some(&mut MinSlice)` + /// if there are at least `M` `T`s in `self`. + pub fn resize_mut(&mut self) -> Option<&mut MinSlice> { + MinSlice::::from_mut(self.as_mut_slice()) + } + + /// Get a reference to a value from the `MinSlice` by index. + /// + /// Return `Some(&T)` for the `T` at index `i` if `i < (N + self.tail.len)`, + /// or `None` otherwise. + pub fn get(&self, i: usize) -> Option<&T> { + if i < N { + Some(&self.head[i]) + } else { + self.tail.get(i) + } + } + + /// Get a mutable reference to a value from the `MinSlice` by index. + /// + /// Return `Some(&mut T)` for the `T` at index `i` if `i < (N + self.tail.len)`, + /// or `None` otherwise. + pub fn get_mut(&mut self, i: usize) -> Option<&mut T> { + if i < N { + Some(&mut self.head[i]) + } else { + self.tail.get_mut(i) + } + } /// Produce a `&MinSlice` from a slice of `T`s without checking its length. /// @@ -112,14 +172,26 @@ impl ExactSlice { } } + /// Returns a slice over the memory referred to by the `ExactSlice`. + /// Its length is guaranteed to be exactly `N`. + pub fn as_slice(&self) -> &[T] { + unsafe { slice::from_raw_parts(self.head.as_ptr(), N) } + } + + /// Returns a mutable slice over the memory referred to by the `ExactSlice`. + /// Its length is guaranteed to be exactly `N`. + pub fn as_mut_slice(&mut self) -> &mut [T] { + unsafe { slice::from_raw_parts_mut(self.head.as_mut_ptr(), N) } + } + /// Produce a `&MinSlice` from this `&ExactSlice`. Its `tail` will be empty. - pub fn as_min_slice(&self) -> Option<&MinSlice> { - MinSlice::from_slice(&self.head[..]) + pub fn as_min_slice(&self) -> &MinSlice { + unsafe { MinSlice::from_slice_unchecked(&self.head[..]) } } /// Produce a `&mut MinSlice` from this `&min ExactSlice`. Its `tail` will be empty. - pub fn as_mut_min_slice(&mut self) -> Option<&mut MinSlice> { - MinSlice::from_mut(&mut self.head[..]) + pub fn as_mut_min_slice(&mut self) -> &mut MinSlice { + unsafe { MinSlice::from_mut_unchecked(&mut self.head[..]) } } /// Produce an `&ExactSlice` from a slice of `T`s without checking its length.