1a1d56debSopenharmony_ci// Copyright (c) 2023 Huawei Device Co., Ltd.
2a1d56debSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
3a1d56debSopenharmony_ci// you may not use this file except in compliance with the License.
4a1d56debSopenharmony_ci// You may obtain a copy of the License at
5a1d56debSopenharmony_ci//
6a1d56debSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
7a1d56debSopenharmony_ci//
8a1d56debSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
9a1d56debSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
10a1d56debSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11a1d56debSopenharmony_ci// See the License for the specific language governing permissions and
12a1d56debSopenharmony_ci// limitations under the License.
13a1d56debSopenharmony_ci
14a1d56debSopenharmony_ciuse super::{BytesReader, Cacheable, NBytesReadable, Position, RemainderCountable};
15a1d56debSopenharmony_ciuse std::convert::Infallible;
16a1d56debSopenharmony_ci
17a1d56debSopenharmony_ci/// Reader for reading slices. This reader implements `BytesReader` trait,
18a1d56debSopenharmony_ci/// `Cacheable` trait and `Countable` trait.
19a1d56debSopenharmony_ci///
20a1d56debSopenharmony_ci/// let slice = "Hello World";
21a1d56debSopenharmony_ci/// let mut reader = SliceReader::new(slice.as_bytes());
22a1d56debSopenharmony_ci/// assert_eq!(reader.next(), Ok(Some(b'H')));
23a1d56debSopenharmony_ci/// assert_eq!(reader.peek(), Ok(Some(b'e')));
24a1d56debSopenharmony_ci/// assert_eq!(reader.peek(), Ok(Some(b'e')));
25a1d56debSopenharmony_cipub(crate) struct SliceReader<'a> {
26a1d56debSopenharmony_ci    slice: &'a [u8],
27a1d56debSopenharmony_ci    index: usize,         // A cursor to the next character to be read.
28a1d56debSopenharmony_ci    cache: Option<Cache>, // A cache for storing accumulated characters.
29a1d56debSopenharmony_ci}
30a1d56debSopenharmony_ci
31a1d56debSopenharmony_ci// A simple cache implementation for `SliceReader`. We just need to save a
32a1d56debSopenharmony_ci// starting position.
33a1d56debSopenharmony_cistruct Cache(usize);
34a1d56debSopenharmony_ci
35a1d56debSopenharmony_ciimpl<'a> SliceReader<'a> {
36a1d56debSopenharmony_ci    /// Create a new `SliceReader` from the given slice.
37a1d56debSopenharmony_ci    ///
38a1d56debSopenharmony_ci    /// let slice = "Hello World";
39a1d56debSopenharmony_ci    /// let reader = SliceReader::new(slice.as_bytes());
40a1d56debSopenharmony_ci    #[inline]
41a1d56debSopenharmony_ci    pub(crate) fn new(slice: &'a [u8]) -> Self {
42a1d56debSopenharmony_ci        Self {
43a1d56debSopenharmony_ci            slice,
44a1d56debSopenharmony_ci            index: 0,
45a1d56debSopenharmony_ci            cache: None,
46a1d56debSopenharmony_ci        }
47a1d56debSopenharmony_ci    }
48a1d56debSopenharmony_ci}
49a1d56debSopenharmony_ci
50a1d56debSopenharmony_ciimpl<'a> BytesReader for SliceReader<'a> {
51a1d56debSopenharmony_ci    type Error = Infallible; // Use Infallible because no error will be returned in SliceReader.
52a1d56debSopenharmony_ci
53a1d56debSopenharmony_ci    #[inline]
54a1d56debSopenharmony_ci    fn next(&mut self) -> Result<Option<u8>, Self::Error> {
55a1d56debSopenharmony_ci        if self.index >= self.slice.len() {
56a1d56debSopenharmony_ci            return Ok(None);
57a1d56debSopenharmony_ci        }
58a1d56debSopenharmony_ci        let ch = self.slice[self.index];
59a1d56debSopenharmony_ci        self.index += 1;
60a1d56debSopenharmony_ci        Ok(Some(ch))
61a1d56debSopenharmony_ci    }
62a1d56debSopenharmony_ci
63a1d56debSopenharmony_ci    #[inline]
64a1d56debSopenharmony_ci    fn peek(&mut self) -> Result<Option<u8>, Self::Error> {
65a1d56debSopenharmony_ci        if self.index >= self.slice.len() {
66a1d56debSopenharmony_ci            return Ok(None);
67a1d56debSopenharmony_ci        }
68a1d56debSopenharmony_ci        Ok(Some(self.slice[self.index]))
69a1d56debSopenharmony_ci    }
70a1d56debSopenharmony_ci
71a1d56debSopenharmony_ci    #[inline]
72a1d56debSopenharmony_ci    fn discard(&mut self) {
73a1d56debSopenharmony_ci        if self.index < self.slice.len() {
74a1d56debSopenharmony_ci            self.index += 1;
75a1d56debSopenharmony_ci        }
76a1d56debSopenharmony_ci    }
77a1d56debSopenharmony_ci
78a1d56debSopenharmony_ci    #[inline]
79a1d56debSopenharmony_ci    fn index(&self) -> usize {
80a1d56debSopenharmony_ci        self.index
81a1d56debSopenharmony_ci    }
82a1d56debSopenharmony_ci
83a1d56debSopenharmony_ci    fn position(&self) -> Position {
84a1d56debSopenharmony_ci        // The traversal method is used to calculate the `Position`, which
85a1d56debSopenharmony_ci        // is expensive, and it is not recommended to call it frequently.
86a1d56debSopenharmony_ci        let index = core::cmp::min(self.index, self.slice.len());
87a1d56debSopenharmony_ci
88a1d56debSopenharmony_ci        let mut position = Position { line: 1, column: 1 };
89a1d56debSopenharmony_ci        for i in 0..index {
90a1d56debSopenharmony_ci            match self.slice[i] {
91a1d56debSopenharmony_ci                b'\n' => {
92a1d56debSopenharmony_ci                    position.line += 1;
93a1d56debSopenharmony_ci                    position.column = 1;
94a1d56debSopenharmony_ci                }
95a1d56debSopenharmony_ci                _ => {
96a1d56debSopenharmony_ci                    position.column += 1;
97a1d56debSopenharmony_ci                }
98a1d56debSopenharmony_ci            }
99a1d56debSopenharmony_ci        }
100a1d56debSopenharmony_ci        position
101a1d56debSopenharmony_ci    }
102a1d56debSopenharmony_ci}
103a1d56debSopenharmony_ci
104a1d56debSopenharmony_ciimpl<'a> Cacheable for SliceReader<'a> {
105a1d56debSopenharmony_ci    #[inline]
106a1d56debSopenharmony_ci    fn start_caching(&mut self) {
107a1d56debSopenharmony_ci        self.cache = Some(Cache(self.index));
108a1d56debSopenharmony_ci    }
109a1d56debSopenharmony_ci
110a1d56debSopenharmony_ci    #[inline]
111a1d56debSopenharmony_ci    fn cached_len(&mut self) -> Option<usize> {
112a1d56debSopenharmony_ci        self.cache.as_ref().map(|c| self.index - c.0)
113a1d56debSopenharmony_ci    }
114a1d56debSopenharmony_ci
115a1d56debSopenharmony_ci    #[inline]
116a1d56debSopenharmony_ci    fn cached_slice(&mut self) -> Option<&[u8]> {
117a1d56debSopenharmony_ci        self.cache.as_ref().map(|c| &self.slice[c.0..self.index])
118a1d56debSopenharmony_ci    }
119a1d56debSopenharmony_ci
120a1d56debSopenharmony_ci    #[inline]
121a1d56debSopenharmony_ci    fn cached_data(&mut self) -> Option<Vec<u8>> {
122a1d56debSopenharmony_ci        self.cache
123a1d56debSopenharmony_ci            .as_ref()
124a1d56debSopenharmony_ci            .map(|c| self.slice[c.0..self.index].to_vec())
125a1d56debSopenharmony_ci    }
126a1d56debSopenharmony_ci
127a1d56debSopenharmony_ci    #[inline]
128a1d56debSopenharmony_ci    fn end_caching(&mut self) {
129a1d56debSopenharmony_ci        self.cache = None;
130a1d56debSopenharmony_ci    }
131a1d56debSopenharmony_ci
132a1d56debSopenharmony_ci    #[inline]
133a1d56debSopenharmony_ci    fn take_cached_data(&mut self) -> Option<Vec<u8>> {
134a1d56debSopenharmony_ci        self.cache
135a1d56debSopenharmony_ci            .take()
136a1d56debSopenharmony_ci            .map(|c| self.slice[c.0..self.index].to_vec())
137a1d56debSopenharmony_ci    }
138a1d56debSopenharmony_ci}
139a1d56debSopenharmony_ci
140a1d56debSopenharmony_ciimpl<'a> RemainderCountable for SliceReader<'a> {
141a1d56debSopenharmony_ci    #[inline]
142a1d56debSopenharmony_ci    fn remainder_len(&self) -> usize {
143a1d56debSopenharmony_ci        self.slice.len() - self.index
144a1d56debSopenharmony_ci    }
145a1d56debSopenharmony_ci
146a1d56debSopenharmony_ci    #[inline]
147a1d56debSopenharmony_ci    fn remainder_slice(&self) -> &[u8] {
148a1d56debSopenharmony_ci        &self.slice[self.index..]
149a1d56debSopenharmony_ci    }
150a1d56debSopenharmony_ci
151a1d56debSopenharmony_ci    #[inline]
152a1d56debSopenharmony_ci    fn remainder_data(&self) -> Vec<u8> {
153a1d56debSopenharmony_ci        self.remainder_slice().to_vec()
154a1d56debSopenharmony_ci    }
155a1d56debSopenharmony_ci}
156a1d56debSopenharmony_ci
157a1d56debSopenharmony_ciimpl<'a> NBytesReadable for SliceReader<'a> {
158a1d56debSopenharmony_ci    fn next_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error> {
159a1d56debSopenharmony_ci        if self.index + n > self.slice.len() {
160a1d56debSopenharmony_ci            return Ok(None);
161a1d56debSopenharmony_ci        }
162a1d56debSopenharmony_ci        let result = &self.slice[self.index..self.index + n];
163a1d56debSopenharmony_ci        self.index += n;
164a1d56debSopenharmony_ci        Ok(Some(result))
165a1d56debSopenharmony_ci    }
166a1d56debSopenharmony_ci
167a1d56debSopenharmony_ci    fn peek_n(&mut self, n: usize) -> Result<Option<&[u8]>, Self::Error> {
168a1d56debSopenharmony_ci        if self.index + n > self.slice.len() {
169a1d56debSopenharmony_ci            return Ok(None);
170a1d56debSopenharmony_ci        }
171a1d56debSopenharmony_ci        Ok(Some(&self.slice[self.index..self.index + n]))
172a1d56debSopenharmony_ci    }
173a1d56debSopenharmony_ci
174a1d56debSopenharmony_ci    fn discard_n(&mut self, n: usize) {
175a1d56debSopenharmony_ci        if self.index + n > self.slice.len() {
176a1d56debSopenharmony_ci            return;
177a1d56debSopenharmony_ci        }
178a1d56debSopenharmony_ci        self.index += n;
179a1d56debSopenharmony_ci    }
180a1d56debSopenharmony_ci}
181a1d56debSopenharmony_ci
182a1d56debSopenharmony_ci#[cfg(test)]
183a1d56debSopenharmony_cimod ut_slice_reader {
184a1d56debSopenharmony_ci    use super::{BytesReader, Cacheable, NBytesReadable, RemainderCountable, SliceReader};
185a1d56debSopenharmony_ci
186a1d56debSopenharmony_ci    /// UT test case for `SliceReader::new`.
187a1d56debSopenharmony_ci    ///
188a1d56debSopenharmony_ci    /// # Title
189a1d56debSopenharmony_ci    /// ut_slice_reader_new
190a1d56debSopenharmony_ci    ///
191a1d56debSopenharmony_ci    /// # Brief
192a1d56debSopenharmony_ci    /// 1. Call `SliceReader::new`.
193a1d56debSopenharmony_ci    /// 2. Check that parts of the return value are default values.
194a1d56debSopenharmony_ci    #[test]
195a1d56debSopenharmony_ci    fn ut_slice_reader_new() {
196a1d56debSopenharmony_ci        let slice = "A";
197a1d56debSopenharmony_ci        let slice_reader = SliceReader::new(slice.as_bytes());
198a1d56debSopenharmony_ci        assert_eq!(slice_reader.slice, slice.as_bytes());
199a1d56debSopenharmony_ci        assert_eq!(slice_reader.index, 0);
200a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_none());
201a1d56debSopenharmony_ci    }
202a1d56debSopenharmony_ci
203a1d56debSopenharmony_ci    /// UT test case for `SliceReader::next`.
204a1d56debSopenharmony_ci    ///
205a1d56debSopenharmony_ci    /// # Title
206a1d56debSopenharmony_ci    /// ut_slice_reader_next
207a1d56debSopenharmony_ci    ///
208a1d56debSopenharmony_ci    /// # Brief
209a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
210a1d56debSopenharmony_ci    /// 2. Call `SliceReader::next`.
211a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
212a1d56debSopenharmony_ci    ///     - If the end is not read, it returns `Ok(Some(..))`, and the index
213a1d56debSopenharmony_ci    ///     is moved backward; if the end is read, it returns `Ok(None)`, and
214a1d56debSopenharmony_ci    ///     the index is not moved.
215a1d56debSopenharmony_ci    #[test]
216a1d56debSopenharmony_ci    fn ut_slice_reader_next() {
217a1d56debSopenharmony_ci        let slice = "A";
218a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
219a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(Some(b'A')));
220a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(None));
221a1d56debSopenharmony_ci    }
222a1d56debSopenharmony_ci
223a1d56debSopenharmony_ci    /// UT test case for `SliceReader::peek`.
224a1d56debSopenharmony_ci    ///
225a1d56debSopenharmony_ci    /// # Title
226a1d56debSopenharmony_ci    /// ut_slice_reader_peek
227a1d56debSopenharmony_ci    ///
228a1d56debSopenharmony_ci    /// # Brief
229a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
230a1d56debSopenharmony_ci    /// 2. Call `SliceReader::peek`.
231a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
232a1d56debSopenharmony_ci    ///     - If the end is not read, it returns `Ok(Some(..))`; if the end is
233a1d56debSopenharmony_ci    ///     read, it returns `Ok(None)`.
234a1d56debSopenharmony_ci    #[test]
235a1d56debSopenharmony_ci    fn ut_slice_reader_peek() {
236a1d56debSopenharmony_ci        let slice = "A";
237a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
238a1d56debSopenharmony_ci        assert_eq!(slice_reader.peek(), Ok(Some(b'A')));
239a1d56debSopenharmony_ci        assert_eq!(slice_reader.peek(), Ok(Some(b'A')));
240a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(Some(b'A')));
241a1d56debSopenharmony_ci        assert_eq!(slice_reader.peek(), Ok(None));
242a1d56debSopenharmony_ci    }
243a1d56debSopenharmony_ci
244a1d56debSopenharmony_ci    /// UT test case for `SliceReader::discard`.
245a1d56debSopenharmony_ci    ///
246a1d56debSopenharmony_ci    /// # Title
247a1d56debSopenharmony_ci    /// ut_slice_reader_discard
248a1d56debSopenharmony_ci    ///
249a1d56debSopenharmony_ci    /// # Brief
250a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
251a1d56debSopenharmony_ci    /// 2. Call `SliceReader::discard`.
252a1d56debSopenharmony_ci    /// 3. Check `index` against the following conditions:
253a1d56debSopenharmony_ci    ///     - If the end is not read, the index is moved backward; if the end is
254a1d56debSopenharmony_ci    ///     read, the index is not moved.
255a1d56debSopenharmony_ci    #[test]
256a1d56debSopenharmony_ci    fn ut_slice_reader_discard() {
257a1d56debSopenharmony_ci        let slice = "A";
258a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
259a1d56debSopenharmony_ci        assert_eq!(slice_reader.index, 0);
260a1d56debSopenharmony_ci        slice_reader.discard();
261a1d56debSopenharmony_ci        assert_eq!(slice_reader.index, 1);
262a1d56debSopenharmony_ci        slice_reader.discard();
263a1d56debSopenharmony_ci        assert_eq!(slice_reader.index, 1);
264a1d56debSopenharmony_ci    }
265a1d56debSopenharmony_ci
266a1d56debSopenharmony_ci    /// UT test case for `SliceReader::index`.
267a1d56debSopenharmony_ci    ///
268a1d56debSopenharmony_ci    /// # Title
269a1d56debSopenharmony_ci    /// ut_slice_reader_index
270a1d56debSopenharmony_ci    ///
271a1d56debSopenharmony_ci    /// # Brief
272a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
273a1d56debSopenharmony_ci    /// 2. Call `SliceReader::index`.
274a1d56debSopenharmony_ci    /// 3. Check if the `index` is correct.
275a1d56debSopenharmony_ci    #[test]
276a1d56debSopenharmony_ci    fn ut_slice_reader_index() {
277a1d56debSopenharmony_ci        let slice = "A";
278a1d56debSopenharmony_ci        let slice_reader = SliceReader::new(slice.as_bytes());
279a1d56debSopenharmony_ci        assert_eq!(slice_reader.index(), 0);
280a1d56debSopenharmony_ci    }
281a1d56debSopenharmony_ci
282a1d56debSopenharmony_ci    /// UT test case for `SliceReader::position`.
283a1d56debSopenharmony_ci    ///
284a1d56debSopenharmony_ci    /// # Title
285a1d56debSopenharmony_ci    /// ut_slice_reader_position
286a1d56debSopenharmony_ci    ///
287a1d56debSopenharmony_ci    /// # Brief
288a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
289a1d56debSopenharmony_ci    /// 2. Call `SliceReader::position`.
290a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
291a1d56debSopenharmony_ci    ///     - If `'\n'` is read, the line number will increase and the column
292a1d56debSopenharmony_ci    ///     number will return to 1; if other characters are read, the line
293a1d56debSopenharmony_ci    ///     number will remain unchanged and the column number will increase.
294a1d56debSopenharmony_ci    #[test]
295a1d56debSopenharmony_ci    fn ut_slice_reader_position() {
296a1d56debSopenharmony_ci        let slice = "A\nB";
297a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
298a1d56debSopenharmony_ci        let position = slice_reader.position();
299a1d56debSopenharmony_ci        assert_eq!(position.line(), 1);
300a1d56debSopenharmony_ci        assert_eq!(position.column(), 1);
301a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(Some(b'A')));
302a1d56debSopenharmony_ci
303a1d56debSopenharmony_ci        let position = slice_reader.position();
304a1d56debSopenharmony_ci        assert_eq!(position.line(), 1);
305a1d56debSopenharmony_ci        assert_eq!(position.column(), 2);
306a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(Some(b'\n')));
307a1d56debSopenharmony_ci
308a1d56debSopenharmony_ci        let position = slice_reader.position();
309a1d56debSopenharmony_ci        assert_eq!(position.line(), 2);
310a1d56debSopenharmony_ci        assert_eq!(position.column(), 1);
311a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(Some(b'B')));
312a1d56debSopenharmony_ci
313a1d56debSopenharmony_ci        let position = slice_reader.position();
314a1d56debSopenharmony_ci        assert_eq!(position.line(), 2);
315a1d56debSopenharmony_ci        assert_eq!(position.column(), 2);
316a1d56debSopenharmony_ci
317a1d56debSopenharmony_ci        assert_eq!(slice_reader.next(), Ok(None));
318a1d56debSopenharmony_ci        let position = slice_reader.position();
319a1d56debSopenharmony_ci        assert_eq!(position.line(), 2);
320a1d56debSopenharmony_ci        assert_eq!(position.column(), 2);
321a1d56debSopenharmony_ci    }
322a1d56debSopenharmony_ci
323a1d56debSopenharmony_ci    /// UT test case for `SliceReader::start_caching`.
324a1d56debSopenharmony_ci    ///
325a1d56debSopenharmony_ci    /// # Title
326a1d56debSopenharmony_ci    /// ut_slice_reader_start_caching
327a1d56debSopenharmony_ci    ///
328a1d56debSopenharmony_ci    /// # Brief
329a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
330a1d56debSopenharmony_ci    /// 2. Call `SliceReader::start_caching`.
331a1d56debSopenharmony_ci    /// 3. Check if `cache` is correct.
332a1d56debSopenharmony_ci    #[test]
333a1d56debSopenharmony_ci    fn ut_slice_reader_start_caching() {
334a1d56debSopenharmony_ci        let slice = "A";
335a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
336a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_none());
337a1d56debSopenharmony_ci        slice_reader.start_caching();
338a1d56debSopenharmony_ci        assert_eq!(slice_reader.cache.as_ref().unwrap().0, 0);
339a1d56debSopenharmony_ci    }
340a1d56debSopenharmony_ci
341a1d56debSopenharmony_ci    /// UT test case for `SliceReader::cached_len`.
342a1d56debSopenharmony_ci    ///
343a1d56debSopenharmony_ci    /// # Title
344a1d56debSopenharmony_ci    /// ut_slice_reader_cached_len
345a1d56debSopenharmony_ci    ///
346a1d56debSopenharmony_ci    /// # Brief
347a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
348a1d56debSopenharmony_ci    /// 2. Call `SliceReader::cached_len`.
349a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
350a1d56debSopenharmony_ci    ///     - Returns `None` if caching is not enabled, otherwise returns
351a1d56debSopenharmony_ci    ///     `Some(..)`.
352a1d56debSopenharmony_ci    #[test]
353a1d56debSopenharmony_ci    fn ut_slice_reader_cached_len() {
354a1d56debSopenharmony_ci        let slice = "A";
355a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
356a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_len(), None);
357a1d56debSopenharmony_ci        slice_reader.start_caching();
358a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_len(), Some(0));
359a1d56debSopenharmony_ci    }
360a1d56debSopenharmony_ci
361a1d56debSopenharmony_ci    /// UT test case for `SliceReader::cached_slice`.
362a1d56debSopenharmony_ci    ///
363a1d56debSopenharmony_ci    /// # Title
364a1d56debSopenharmony_ci    /// ut_slice_reader_cached_slice
365a1d56debSopenharmony_ci    ///
366a1d56debSopenharmony_ci    /// # Brief
367a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
368a1d56debSopenharmony_ci    /// 2. Call `SliceReader::cached_slice`.
369a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
370a1d56debSopenharmony_ci    ///     - Returns `None` if caching is not enabled, otherwise returns
371a1d56debSopenharmony_ci    ///     `Some(..)`.
372a1d56debSopenharmony_ci    #[test]
373a1d56debSopenharmony_ci    fn ut_slice_reader_cached_slice() {
374a1d56debSopenharmony_ci        let slice = "A";
375a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
376a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_slice(), None);
377a1d56debSopenharmony_ci        slice_reader.start_caching();
378a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_slice(), Some([].as_slice()));
379a1d56debSopenharmony_ci    }
380a1d56debSopenharmony_ci
381a1d56debSopenharmony_ci    /// UT test case for `SliceReader::cached_data`.
382a1d56debSopenharmony_ci    ///
383a1d56debSopenharmony_ci    /// # Title
384a1d56debSopenharmony_ci    /// ut_slice_reader_cached_slice
385a1d56debSopenharmony_ci    ///
386a1d56debSopenharmony_ci    /// # Brief
387a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
388a1d56debSopenharmony_ci    /// 2. Call `SliceReader::cached_data`.
389a1d56debSopenharmony_ci    /// 3. Check the return value against the following conditions:
390a1d56debSopenharmony_ci    ///     - Returns `None` if caching is not enabled, otherwise returns
391a1d56debSopenharmony_ci    ///     `Some(..)`.
392a1d56debSopenharmony_ci    #[test]
393a1d56debSopenharmony_ci    fn ut_slice_reader_cached_data() {
394a1d56debSopenharmony_ci        let slice = "A";
395a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
396a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_data(), None);
397a1d56debSopenharmony_ci        slice_reader.start_caching();
398a1d56debSopenharmony_ci        assert_eq!(slice_reader.cached_data(), Some(Vec::new()));
399a1d56debSopenharmony_ci    }
400a1d56debSopenharmony_ci
401a1d56debSopenharmony_ci    /// UT test case for `SliceReader::end_caching`.
402a1d56debSopenharmony_ci    ///
403a1d56debSopenharmony_ci    /// # Title
404a1d56debSopenharmony_ci    /// ut_slice_reader_end_caching
405a1d56debSopenharmony_ci    ///
406a1d56debSopenharmony_ci    /// # Brief
407a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
408a1d56debSopenharmony_ci    /// 2. Call `SliceReader::end_caching`.
409a1d56debSopenharmony_ci    /// 3. Check if `cache` is correct.
410a1d56debSopenharmony_ci    #[test]
411a1d56debSopenharmony_ci    fn ut_slice_reader_end_caching() {
412a1d56debSopenharmony_ci        let slice = "A";
413a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
414a1d56debSopenharmony_ci        slice_reader.start_caching();
415a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_some());
416a1d56debSopenharmony_ci        slice_reader.end_caching();
417a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_none());
418a1d56debSopenharmony_ci    }
419a1d56debSopenharmony_ci
420a1d56debSopenharmony_ci    /// UT test case for `SliceReader::take_cached_data`.
421a1d56debSopenharmony_ci    ///
422a1d56debSopenharmony_ci    /// # Title
423a1d56debSopenharmony_ci    /// ut_slice_reader_take_cached_data
424a1d56debSopenharmony_ci    ///
425a1d56debSopenharmony_ci    /// # Brief
426a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
427a1d56debSopenharmony_ci    /// 2. Call `SliceReader::take_cached_data`.
428a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
429a1d56debSopenharmony_ci    #[test]
430a1d56debSopenharmony_ci    fn ut_slice_reader_take_cached_data() {
431a1d56debSopenharmony_ci        let slice = "A";
432a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
433a1d56debSopenharmony_ci        slice_reader.start_caching();
434a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_some());
435a1d56debSopenharmony_ci        assert_eq!(slice_reader.take_cached_data(), Some(Vec::new()));
436a1d56debSopenharmony_ci        assert!(slice_reader.cache.is_none());
437a1d56debSopenharmony_ci    }
438a1d56debSopenharmony_ci
439a1d56debSopenharmony_ci    /// UT test case for `SliceReader::remainder_len`.
440a1d56debSopenharmony_ci    ///
441a1d56debSopenharmony_ci    /// # Title
442a1d56debSopenharmony_ci    /// ut_slice_reader_remainder_len
443a1d56debSopenharmony_ci    ///
444a1d56debSopenharmony_ci    /// # Brief
445a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
446a1d56debSopenharmony_ci    /// 2. Call `SliceReader::remainder_len`.
447a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
448a1d56debSopenharmony_ci    #[test]
449a1d56debSopenharmony_ci    fn ut_slice_reader_remainder_len() {
450a1d56debSopenharmony_ci        let slice = "A";
451a1d56debSopenharmony_ci        let slice_reader = SliceReader::new(slice.as_bytes());
452a1d56debSopenharmony_ci        assert_eq!(slice_reader.remainder_len(), 1);
453a1d56debSopenharmony_ci    }
454a1d56debSopenharmony_ci
455a1d56debSopenharmony_ci    /// UT test case for `SliceReader::remainder_slice`.
456a1d56debSopenharmony_ci    ///
457a1d56debSopenharmony_ci    /// # Title
458a1d56debSopenharmony_ci    /// ut_slice_reader_remainder_slice
459a1d56debSopenharmony_ci    ///
460a1d56debSopenharmony_ci    /// # Brief
461a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
462a1d56debSopenharmony_ci    /// 2. Call `SliceReader::remainder_slice`.
463a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
464a1d56debSopenharmony_ci    #[test]
465a1d56debSopenharmony_ci    fn ut_slice_reader_remainder_slice() {
466a1d56debSopenharmony_ci        let slice = "A";
467a1d56debSopenharmony_ci        let slice_reader = SliceReader::new(slice.as_bytes());
468a1d56debSopenharmony_ci        assert_eq!(slice_reader.remainder_slice(), slice.as_bytes());
469a1d56debSopenharmony_ci    }
470a1d56debSopenharmony_ci
471a1d56debSopenharmony_ci    /// UT test case for `SliceReader::remainder_data`.
472a1d56debSopenharmony_ci    ///
473a1d56debSopenharmony_ci    /// # Title
474a1d56debSopenharmony_ci    /// ut_slice_reader_remainder_slice
475a1d56debSopenharmony_ci    ///
476a1d56debSopenharmony_ci    /// # Brief
477a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
478a1d56debSopenharmony_ci    /// 2. Call `SliceReader::remainder_slice`.
479a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
480a1d56debSopenharmony_ci    #[test]
481a1d56debSopenharmony_ci    fn ut_slice_reader_remainder_data() {
482a1d56debSopenharmony_ci        let slice = "A";
483a1d56debSopenharmony_ci        let slice_reader = SliceReader::new(slice.as_bytes());
484a1d56debSopenharmony_ci        assert_eq!(slice_reader.remainder_data(), slice.as_bytes().to_vec());
485a1d56debSopenharmony_ci    }
486a1d56debSopenharmony_ci
487a1d56debSopenharmony_ci    /// UT test case for `SliceReader::next_n`.
488a1d56debSopenharmony_ci    ///
489a1d56debSopenharmony_ci    /// # Title
490a1d56debSopenharmony_ci    /// ut_slice_reader_next_n
491a1d56debSopenharmony_ci    ///
492a1d56debSopenharmony_ci    /// # Brief
493a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
494a1d56debSopenharmony_ci    /// 2. Call `SliceReader::next_n`.
495a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
496a1d56debSopenharmony_ci    #[test]
497a1d56debSopenharmony_ci    fn ut_slice_reader_next_n() {
498a1d56debSopenharmony_ci        let slice = "ABC";
499a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
500a1d56debSopenharmony_ci        assert_eq!(slice_reader.next_n(2).unwrap(), Some("AB".as_bytes()));
501a1d56debSopenharmony_ci        assert_eq!(slice_reader.next_n(2).unwrap(), None);
502a1d56debSopenharmony_ci    }
503a1d56debSopenharmony_ci
504a1d56debSopenharmony_ci    /// UT test case for `SliceReader::peek_n`.
505a1d56debSopenharmony_ci    ///
506a1d56debSopenharmony_ci    /// # Title
507a1d56debSopenharmony_ci    /// ut_slice_reader_peek_n
508a1d56debSopenharmony_ci    ///
509a1d56debSopenharmony_ci    /// # Brief
510a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
511a1d56debSopenharmony_ci    /// 2. Call `SliceReader::peek_n`.
512a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
513a1d56debSopenharmony_ci    #[test]
514a1d56debSopenharmony_ci    fn ut_slice_reader_peek_n() {
515a1d56debSopenharmony_ci        let slice = "ABC";
516a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
517a1d56debSopenharmony_ci        assert_eq!(slice_reader.peek_n(2).unwrap(), Some("AB".as_bytes()));
518a1d56debSopenharmony_ci        assert_eq!(slice_reader.peek_n(4).unwrap(), None);
519a1d56debSopenharmony_ci    }
520a1d56debSopenharmony_ci
521a1d56debSopenharmony_ci    /// UT test case for `SliceReader::discard_n`.
522a1d56debSopenharmony_ci    ///
523a1d56debSopenharmony_ci    /// # Title
524a1d56debSopenharmony_ci    /// ut_slice_reader_discard_n
525a1d56debSopenharmony_ci    ///
526a1d56debSopenharmony_ci    /// # Brief
527a1d56debSopenharmony_ci    /// 1. Create a `SliceReader`.
528a1d56debSopenharmony_ci    /// 2. Call `SliceReader::discard_n`.
529a1d56debSopenharmony_ci    /// 3. Check if the return value is correct.
530a1d56debSopenharmony_ci    #[test]
531a1d56debSopenharmony_ci    fn ut_slice_reader_discard_n() {
532a1d56debSopenharmony_ci        let slice = "ABC";
533a1d56debSopenharmony_ci        let mut slice_reader = SliceReader::new(slice.as_bytes());
534a1d56debSopenharmony_ci        slice_reader.discard_n(2);
535a1d56debSopenharmony_ci        assert_eq!(slice_reader.next().unwrap(), Some(b'C'));
536a1d56debSopenharmony_ci    }
537a1d56debSopenharmony_ci}
538