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}