1#![deny(missing_docs)]
9#![deny(warnings)]
10#![no_std]
11
12use core::{convert::Infallible, fmt, str};
13
14use heapless::String;
15use ufmt_write::uWrite;
16
17macro_rules! assume_unreachable {
18 () => {
19 if cfg!(debug_assertions) {
20 panic!()
21 } else {
22 core::hint::unreachable_unchecked()
23 }
24 };
25}
26
27pub struct Ignore<W>
29where
30 W: uWrite,
31{
32 writer: W,
33}
34
35impl<W> Ignore<W>
36where
37 W: uWrite,
38{
39 pub fn new(writer: W) -> Self {
41 Self { writer }
42 }
43
44 pub fn free(self) -> W {
46 self.writer
47 }
48}
49
50impl<W> uWrite for Ignore<W>
51where
52 W: uWrite,
53{
54 type Error = Infallible;
55
56 fn write_str(&mut self, s: &str) -> Result<(), Infallible> {
57 let _ = self.writer.write_str(s);
58 Ok(())
59 }
60}
61
62pub struct LineBuffered<W, const N: usize>
64where
65 W: uWrite,
66{
67 buffer: String<N>,
68 writer: W,
69}
70
71impl<W, const N: usize> LineBuffered<W, N>
72where
73 W: uWrite,
74{
75 pub fn new(writer: W) -> Self {
77 Self {
78 buffer: String::new(),
79 writer,
80 }
81 }
82
83 pub fn flush(&mut self) -> Result<(), W::Error> {
85 let ret = self.writer.write_str(&self.buffer);
86 self.buffer.clear();
87 ret
88 }
89
90 pub fn free(self) -> W {
92 self.writer
93 }
94
95 fn push_str(&mut self, s: &str) -> Result<(), W::Error> {
96 let len = s.as_bytes().len();
97 if self.buffer.len() + len > self.buffer.capacity() {
98 self.flush()?;
99 }
100
101 if len > self.buffer.capacity() {
102 self.writer.write_str(s)?;
103 } else {
104 self.buffer
105 .push_str(s)
106 .unwrap_or_else(|_| unsafe { assume_unreachable!() })
107 }
108
109 Ok(())
110 }
111}
112
113impl<W, const N: usize> uWrite for LineBuffered<W, N>
114where
115 W: uWrite,
116{
117 type Error = W::Error;
118
119 fn write_str(&mut self, mut s: &str) -> Result<(), W::Error> {
120 while let Some(pos) = s.as_bytes().iter().position(|b| *b == b'\n') {
121 let line = s
122 .get(..pos + 1)
123 .unwrap_or_else(|| unsafe { assume_unreachable!() });
124
125 self.push_str(line)?;
126 self.flush()?;
127
128 s = s
129 .get(pos + 1..)
130 .unwrap_or_else(|| unsafe { assume_unreachable!() });
131 }
132
133 self.push_str(s)
134 }
135}
136
137pub struct WriteAdapter<W>(pub W)
152where
153 W: fmt::Write;
154
155impl<W> uWrite for WriteAdapter<W>
156where
157 W: fmt::Write,
158{
159 type Error = fmt::Error;
160
161 fn write_char(&mut self, c: char) -> Result<(), Self::Error> {
162 self.0.write_char(c)
163 }
164
165 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
166 self.0.write_str(s)
167 }
168}