cppstreams/
stringstream.rs1use 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 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}