pad_adapter/
lib.rs

1#![no_std]
2
3use core::fmt::{self, Formatter, Write};
4
5/// Pad adapter inserts the padding after each newline except the last.
6///
7/// The default padding is `    `.
8pub struct PadAdapter<'a, 'b: 'a, 'c> {
9    fmt: &'a mut Formatter<'b>,
10    padding: &'c str,
11    state: State,
12}
13
14impl<'a, 'b: 'a, 'c> PadAdapter<'a, 'b, 'c> {
15    /// Creates a new pad adapter with default padding.
16    pub fn new(fmt: &'a mut Formatter<'b>) -> Self {
17        Self {
18            fmt,
19            padding: "    ",
20            state: Default::default(),
21        }
22    }
23
24    /// Creates a new pad adapter with the padding.
25    pub fn with_padding(fmt: &'a mut Formatter<'b>, padding: &'c str) -> Self {
26        Self {
27            fmt,
28            padding,
29            state: Default::default(),
30        }
31    }
32}
33
34impl Write for PadAdapter<'_, '_, '_> {
35    fn write_str(&mut self, mut s: &str) -> fmt::Result {
36        while !s.is_empty() {
37            if self.state.on_newline {
38                self.fmt.write_str(self.padding)?;
39            }
40            let split = match s.find('\n') {
41                Some(pos) => {
42                    self.state.on_newline = true;
43                    pos + 1
44                }
45                None => {
46                    self.state.on_newline = false;
47                    s.len()
48                }
49            };
50            self.fmt.write_str(&s[..split])?;
51            s = &s[split..];
52        }
53        Ok(())
54    }
55}
56
57struct State {
58    on_newline: bool,
59}
60
61impl Default for State {
62    fn default() -> Self {
63        Self { on_newline: true }
64    }
65}