Skip to main content

qubit_text_io/adapters/
string_text_writer.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    LineEnding,
14    TextWrite,
15};
16
17/// Text writer over a borrowed [`String`] with configurable line endings.
18#[derive(Debug)]
19pub struct StringTextWriter<'a> {
20    output: &'a mut String,
21    line_ending: LineEnding,
22}
23
24impl<'a> StringTextWriter<'a> {
25    /// Creates a writer over `output`.
26    ///
27    /// # Parameters
28    /// - `output`: Destination string.
29    ///
30    /// # Returns
31    /// A string text writer using LF line endings.
32    #[must_use]
33    pub const fn new(output: &'a mut String) -> Self {
34        Self {
35            output,
36            line_ending: LineEnding::Lf,
37        }
38    }
39
40    /// Sets the line ending for this writer.
41    ///
42    /// # Parameters
43    /// - `line_ending`: Line ending to use for subsequent lines.
44    ///
45    /// # Returns
46    /// This writer with the configured line ending.
47    #[must_use]
48    pub const fn with_line_ending(mut self, line_ending: LineEnding) -> Self {
49        self.line_ending = line_ending;
50        self
51    }
52
53    /// Returns the wrapped string.
54    ///
55    /// # Returns
56    /// A shared reference to the destination string.
57    #[must_use]
58    pub fn get_ref(&self) -> &String {
59        self.output
60    }
61
62    /// Returns the wrapped string mutably.
63    ///
64    /// # Returns
65    /// A mutable reference to the destination string.
66    pub fn get_mut(&mut self) -> &mut String {
67        self.output
68    }
69}
70
71impl TextWrite for StringTextWriter<'_> {
72    type Error = Infallible;
73
74    #[inline]
75    fn line_ending(&self) -> LineEnding {
76        self.line_ending
77    }
78
79    #[inline]
80    fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
81        self.output.push(ch);
82        Ok(())
83    }
84
85    #[inline]
86    fn write_chars(&mut self, chars: &[char]) -> Result<(), Self::Error> {
87        self.output.extend(chars.iter().copied());
88        Ok(())
89    }
90
91    #[inline]
92    fn write_str(&mut self, text: &str) -> Result<(), Self::Error> {
93        self.output.push_str(text);
94        Ok(())
95    }
96
97    #[inline]
98    fn write_line(&mut self, line: &str) -> Result<(), Self::Error> {
99        self.output.push_str(line);
100        self.output.push_str(self.line_ending.as_str());
101        Ok(())
102    }
103
104    #[inline]
105    fn flush(&mut self) -> Result<(), Self::Error> {
106        Ok(())
107    }
108}
109
110impl TextWrite for String {
111    type Error = Infallible;
112
113    #[inline]
114    fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
115        self.push(ch);
116        Ok(())
117    }
118
119    #[inline]
120    fn write_chars(&mut self, chars: &[char]) -> Result<(), Self::Error> {
121        self.extend(chars.iter().copied());
122        Ok(())
123    }
124
125    #[inline]
126    fn write_str(&mut self, text: &str) -> Result<(), Self::Error> {
127        self.push_str(text);
128        Ok(())
129    }
130
131    #[inline]
132    fn write_line(&mut self, line: &str) -> Result<(), Self::Error> {
133        self.push_str(line);
134        self.push_str(self.line_ending().as_str());
135        Ok(())
136    }
137
138    #[inline]
139    fn flush(&mut self) -> Result<(), Self::Error> {
140        Ok(())
141    }
142}