1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::fmt;
use std::iter;
use super::*;

pub struct ElementFormatter<'a, W>
    where W: fmt::Write + 'a
{
    write: &'a mut W,
    // if last line was empty.
    last_line_empty: bool,
    // Current indentation level.
    indent: usize,
    // Holds the current indentation level as a string.
    indent_buffer: String,
}

impl<'a, W> ElementFormatter<'a, W>
    where W: fmt::Write
{
    pub fn new(write: &mut W) -> ElementFormatter<W> {
        ElementFormatter {
            write: write,
            last_line_empty: true,
            indent: 0usize,
            indent_buffer: String::from("  "),
        }
    }

    fn check_indent(&mut self) -> fmt::Result {
        if self.last_line_empty {
            self.write.write_str(&self.indent_buffer[0..self.indent * 2])?;
        }

        self.last_line_empty = false;
        Ok(())
    }
}

impl<'a, W> fmt::Write for ElementFormatter<'a, W>
    where W: fmt::Write
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.check_indent()?;
        self.write.write_str(s)
    }

    fn write_char(&mut self, c: char) -> fmt::Result {
        self.check_indent()?;
        self.write.write_char(c)
    }

    fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
        self.check_indent()?;
        self.write.write_fmt(args)
    }
}

impl<'a, W> ElementFormat for ElementFormatter<'a, W>
    where W: fmt::Write
{
    fn new_line(&mut self) -> Result<()> {
        self.write.write_char('\n')?;
        self.last_line_empty = true;
        Ok(())
    }

    fn new_line_unless_empty(&mut self) -> Result<()> {
        if !self.last_line_empty {
            self.write.write_char('\n')?;
            self.last_line_empty = true;
        }

        Ok(())
    }

    fn indent(&mut self) {
        self.indent += 1;

        // check that buffer contains the current indentation.
        if self.indent_buffer.len() < self.indent * 2 {
            // double the buffer
            for c in iter::repeat(' ').take(self.indent_buffer.len()) {
                self.indent_buffer.push(c);
            }
        }
    }

    fn unindent(&mut self) {
        self.indent = self.indent.saturating_sub(1);
    }
}