util_cursor/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::fmt;
5
6pub struct Cursor<T> {
7    pub data: T,
8    pub offset: usize,
9}
10
11impl<'a, T> Cursor<&'a [T]> {
12    /// Returns remaining slice from the current offset.
13    /// It doesn't change the offset.
14    ///
15    /// # Examples
16    ///
17    /// ```
18    /// use util_cursor::Cursor;
19    ///
20    /// let mut cursor = Cursor::new([1, 2].as_ref());
21    ///
22    /// assert_eq!(cursor.remaining_slice(), &[1, 2]);
23    /// cursor.offset = 42;
24    /// assert!(cursor.remaining_slice().is_empty());
25    /// ```
26    #[inline]
27    pub fn remaining_slice(&self) -> &'a [T] {
28        unsafe { self.data.get_unchecked(self.offset.min(self.data.len())..) }
29    }
30
31    /// Read slice from the current offset.
32    ///
33    /// # Example
34    /// ```
35    /// use util_cursor::Cursor;
36    /// let mut view = Cursor::new([1, 2, 3].as_ref());
37    ///
38    /// assert_eq!(view.read_slice(2), Some([1, 2].as_ref()));
39    /// assert_eq!(view.read_slice(3), None);
40    /// ```
41    #[inline]
42    pub fn read_slice(&mut self, len: usize) -> Option<&'a [T]> {
43        let total_len = self.offset + len;
44        let slice = self.data.get(self.offset..total_len)?;
45        self.offset = total_len;
46        Some(slice)
47    }
48}
49
50impl<T> Cursor<T> {
51    /// Creates a new [`Cursor<T>`].
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use util_cursor::Cursor;
57    ///
58    /// let cursor = Cursor::new([1, 2].as_ref());
59    /// ```
60    #[inline]
61    pub const fn new(data: T) -> Self {
62        Self { data, offset: 0 }
63    }
64}
65
66impl<T> From<T> for Cursor<T> {
67    #[inline]
68    fn from(data: T) -> Self {
69        Self::new(data)
70    }
71}
72
73impl<T: Clone> Clone for Cursor<T> {
74    fn clone(&self) -> Self {
75        Self {
76            data: self.data.clone(),
77            offset: self.offset,
78        }
79    }
80}
81
82impl<T: fmt::Debug> fmt::Debug for Cursor<T> {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        f.debug_struct("Cursor")
85            .field("data", &self.data)
86            .field("offset", &self.offset)
87            .finish()
88    }
89}