embedrs_bytes/buf/
take.rs

1use {Buf};
2
3use core::cmp;
4
5/// A `Buf` adapter which limits the bytes read from an underlying buffer.
6///
7/// This struct is generally created by calling `take()` on `Buf`. See
8/// documentation of [`take()`](trait.Buf.html#method.take) for more details.
9#[derive(Debug)]
10pub struct Take<T> {
11    inner: T,
12    limit: usize,
13}
14
15pub fn new<T>(inner: T, limit: usize) -> Take<T> {
16    Take {
17        inner: inner,
18        limit: limit,
19    }
20}
21
22impl<T> Take<T> {
23    /// Consumes this `Take`, returning the underlying value.
24    ///
25    /// # Examples
26    ///
27    /// ```rust
28    /// use embedrs_bytes::{Buf, BufMut};
29    /// use std::io::Cursor;
30    ///
31    /// let mut buf = Cursor::new(b"hello world").take(2);
32    /// let mut dst = vec![];
33    ///
34    /// dst.put(&mut buf);
35    /// assert_eq!(*dst, b"he"[..]);
36    ///
37    /// let mut buf = buf.into_inner();
38    ///
39    /// dst.clear();
40    /// dst.put(&mut buf);
41    /// assert_eq!(*dst, b"llo world"[..]);
42    /// ```
43    pub fn into_inner(self) -> T {
44        self.inner
45    }
46
47    /// Gets a reference to the underlying `Buf`.
48    ///
49    /// It is inadvisable to directly read from the underlying `Buf`.
50    ///
51    /// # Examples
52    ///
53    /// ```rust
54    /// use embedrs_bytes::{Buf, BufMut};
55    /// use std::io::Cursor;
56    ///
57    /// let mut buf = Cursor::new(b"hello world").take(2);
58    ///
59    /// assert_eq!(0, buf.get_ref().position());
60    /// ```
61    pub fn get_ref(&self) -> &T {
62        &self.inner
63    }
64
65    /// Gets a mutable reference to the underlying `Buf`.
66    ///
67    /// It is inadvisable to directly read from the underlying `Buf`.
68    ///
69    /// # Examples
70    ///
71    /// ```rust
72    /// use embedrs_bytes::{Buf, BufMut};
73    /// use std::io::Cursor;
74    ///
75    /// let mut buf = Cursor::new(b"hello world").take(2);
76    /// let mut dst = vec![];
77    ///
78    /// buf.get_mut().set_position(2);
79    ///
80    /// dst.put(&mut buf);
81    /// assert_eq!(*dst, b"ll"[..]);
82    /// ```
83    pub fn get_mut(&mut self) -> &mut T {
84        &mut self.inner
85    }
86
87    /// Returns the maximum number of bytes that can be read.
88    ///
89    /// # Note
90    ///
91    /// If the inner `Buf` has fewer bytes than indicated by this method then
92    /// that is the actual number of available bytes.
93    ///
94    /// # Examples
95    ///
96    /// ```rust
97    /// use embedrs_bytes::Buf;
98    /// use std::io::Cursor;
99    ///
100    /// let mut buf = Cursor::new(b"hello world").take(2);
101    ///
102    /// assert_eq!(2, buf.limit());
103    /// assert_eq!(b'h', buf.get_u8());
104    /// assert_eq!(1, buf.limit());
105    /// ```
106    pub fn limit(&self) -> usize {
107        self.limit
108    }
109
110    /// Sets the maximum number of bytes that can be read.
111    ///
112    /// # Note
113    ///
114    /// If the inner `Buf` has fewer bytes than `lim` then that is the actual
115    /// number of available bytes.
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// use embedrs_bytes::{Buf, BufMut};
121    /// use std::io::Cursor;
122    ///
123    /// let mut buf = Cursor::new(b"hello world").take(2);
124    /// let mut dst = vec![];
125    ///
126    /// dst.put(&mut buf);
127    /// assert_eq!(*dst, b"he"[..]);
128    ///
129    /// dst.clear();
130    ///
131    /// buf.set_limit(3);
132    /// dst.put(&mut buf);
133    /// assert_eq!(*dst, b"llo"[..]);
134    /// ```
135    pub fn set_limit(&mut self, lim: usize) {
136        self.limit = lim
137    }
138}
139
140impl<T: Buf> Buf for Take<T> {
141    fn remaining(&self) -> usize {
142        cmp::min(self.inner.remaining(), self.limit)
143    }
144
145    fn bytes(&self) -> &[u8] {
146        let bytes = self.inner.bytes();
147        &bytes[..cmp::min(bytes.len(), self.limit)]
148    }
149
150    fn advance(&mut self, cnt: usize) {
151        assert!(cnt <= self.limit);
152        self.inner.advance(cnt);
153        self.limit -= cnt;
154    }
155}