Skip to main content

qubit_text_io/adapters/
str_text_reader.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::convert::Infallible;
11
12use crate::{
13    TextLineRead,
14    TextRead,
15    adapters::text_cursor::{
16        read_char_at,
17        read_chars_at,
18        read_line_at,
19        read_to_string_at,
20    },
21};
22
23/// Text reader over a borrowed string slice.
24#[derive(Debug)]
25pub struct StrTextReader<'a> {
26    text: &'a str,
27    position: usize,
28}
29
30impl<'a> StrTextReader<'a> {
31    /// Creates a reader over `text`.
32    ///
33    /// # Parameters
34    /// - `text`: Borrowed text to read.
35    ///
36    /// # Returns
37    /// A reader positioned at the start of the text.
38    #[must_use]
39    pub const fn new(text: &'a str) -> Self {
40        Self { text, position: 0 }
41    }
42
43    /// Returns the current byte position in the underlying string slice.
44    ///
45    /// # Returns
46    /// The current byte position.
47    #[must_use]
48    pub const fn position(&self) -> usize {
49        self.position
50    }
51}
52
53impl TextRead for StrTextReader<'_> {
54    type Error = Infallible;
55
56    #[inline]
57    fn read_char(&mut self) -> Result<Option<char>, Self::Error> {
58        Ok(read_char_at(self.text, &mut self.position))
59    }
60
61    #[inline]
62    fn read_chars(&mut self, output: &mut Vec<char>, max: usize) -> Result<usize, Self::Error> {
63        Ok(read_chars_at(self.text, &mut self.position, output, max))
64    }
65
66    #[inline]
67    fn read_to_string(&mut self, output: &mut String) -> Result<usize, Self::Error> {
68        Ok(read_to_string_at(self.text, &mut self.position, output))
69    }
70}
71
72impl TextLineRead for StrTextReader<'_> {
73    #[inline]
74    fn read_line(&mut self, output: &mut String) -> Result<bool, Self::Error> {
75        Ok(read_line_at(self.text, &mut self.position, output))
76    }
77}