cppstreams/
stringstream.rs

1use std::fmt::Display;
2use std::io::{Read, Write};
3use std::ops::{Shl, Shr};
4use std::str::FromStr;
5
6use crate::istream::istream_impl;
7use crate::ostream::ostream_impl;
8use crate::{IStream, OStream};
9
10pub struct StringStream(String);
11
12impl Default for StringStream {
13    #[inline]
14    fn default() -> Self {
15        StringStream(String::new())
16    }
17}
18
19impl Display for StringStream {
20    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        write!(fmt, "{}", self.0)
22    }
23}
24
25impl std::fmt::Debug for StringStream {
26    #[inline]
27    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        write!(fmt, "{:?}", self.0)
29    }
30}
31
32impl From<String> for StringStream {
33    #[inline]
34    fn from(value: String) -> Self {
35        Self(value)
36    }
37}
38
39impl Write for StringStream {
40    #[inline]
41    fn write(&mut self, mut buf: &[u8]) -> std::io::Result<usize> {
42        buf.read_to_string(&mut self.0)
43    }
44
45    #[inline]
46    fn flush(&mut self) -> std::io::Result<()> {
47        Ok(())
48    }
49}
50
51impl Read for StringStream {
52    /// Has bad performance
53    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
54        let data = self.0.as_bytes();
55        match data.len().cmp(&buf.len()) {
56            std::cmp::Ordering::Less => {
57                let read = data.len();
58                buf[..read].copy_from_slice(data);
59                self.0.clear();
60                Ok(read)
61            }
62            std::cmp::Ordering::Equal => {
63                buf.copy_from_slice(data);
64                let read = data.len();
65                self.0.clear();
66                Ok(read)
67            }
68            std::cmp::Ordering::Greater => {
69                let mut i = buf.len();
70                loop {
71                    if self.0.is_char_boundary(i) {
72                        buf.copy_from_slice(&data[..i]);
73                        let char_count = data[..i].utf8_chunks().count();
74                        for _ in 0..char_count {
75                            self.0.remove(0);
76                        }
77                        break Ok(i);
78                    }
79                    i -= 1;
80                }
81            }
82        }
83    }
84}
85
86impl From<StringStream> for IStream<StringStream> {
87    #[inline]
88    fn from(value: StringStream) -> Self {
89        Self::new(value)
90    }
91}
92
93impl<T: FromStr> Shr<&mut T> for StringStream {
94    type Output = Result<crate::istream::Status, T::Err>;
95
96    #[inline]
97    fn shr(self, rhs: &mut T) -> Self::Output {
98        Into::<IStream<_>>::into(self) >> rhs
99    }
100}
101
102impl<T: FromStr> Shr<&mut T> for &mut StringStream {
103    type Output = Result<crate::istream::Status, T::Err>;
104
105    #[inline]
106    fn shr(self, rhs: &mut T) -> Self::Output {
107        istream_impl(self, rhs)
108    }
109}
110
111impl From<StringStream> for OStream<StringStream> {
112    #[inline]
113    fn from(value: StringStream) -> Self {
114        OStream::new(value)
115    }
116}
117
118impl<T: Display> Shl<T> for StringStream {
119    type Output = OStream<StringStream>;
120
121    #[inline]
122    fn shl(self, _rhs: T) -> Self::Output {
123        Into::<OStream<_>>::into(self) << _rhs
124    }
125}
126
127impl<T: Display> Shl<T> for &mut StringStream {
128    type Output = Self;
129
130    #[inline]
131    fn shl(self, _rhs: T) -> Self::Output {
132        ostream_impl(self, _rhs);
133        self
134    }
135}