Skip to main content

qubit_text_io/adapters/
string_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 an owned string.
24#[derive(Debug)]
25pub struct StringTextReader {
26    text: String,
27    position: usize,
28}
29
30impl StringTextReader {
31    /// Creates a reader over owned text.
32    ///
33    /// # Parameters
34    /// - `text`: Text to own and read.
35    ///
36    /// # Returns
37    /// A reader positioned at the start of the text.
38    #[must_use]
39    pub const fn new(text: String) -> Self {
40        Self { text, position: 0 }
41    }
42
43    /// Returns the current byte position in the underlying string.
44    ///
45    /// # Returns
46    /// The current byte position.
47    #[must_use]
48    pub const fn position(&self) -> usize {
49        self.position
50    }
51
52    /// Returns the owned string.
53    ///
54    /// # Returns
55    /// The original string owned by this reader.
56    #[must_use]
57    pub fn into_inner(self) -> String {
58        self.text
59    }
60}
61
62impl TextRead for StringTextReader {
63    type Error = Infallible;
64
65    #[inline]
66    fn read_char(&mut self) -> Result<Option<char>, Self::Error> {
67        Ok(read_char_at(&self.text, &mut self.position))
68    }
69
70    #[inline]
71    fn read_chars(&mut self, output: &mut Vec<char>, max: usize) -> Result<usize, Self::Error> {
72        Ok(read_chars_at(&self.text, &mut self.position, output, max))
73    }
74
75    #[inline]
76    fn read_to_string(&mut self, output: &mut String) -> Result<usize, Self::Error> {
77        Ok(read_to_string_at(&self.text, &mut self.position, output))
78    }
79}
80
81impl TextLineRead for StringTextReader {
82    #[inline]
83    fn read_line(&mut self, output: &mut String) -> Result<bool, Self::Error> {
84        Ok(read_line_at(&self.text, &mut self.position, output))
85    }
86}