prettyless/render/
write.rs

1use std::{fmt, io};
2
3use crate::text::SPACES;
4
5use super::Render;
6
7/// Writes to something implementing `std::io::Write`
8pub struct IoWrite<W> {
9    upstream: W,
10}
11
12impl<W> IoWrite<W> {
13    pub fn new(upstream: W) -> IoWrite<W> {
14        IoWrite { upstream }
15    }
16}
17
18impl<W> Render for IoWrite<W>
19where
20    W: io::Write,
21{
22    type Error = io::Error;
23
24    fn write_str(&mut self, s: &str) -> io::Result<usize> {
25        self.upstream.write(s.as_bytes())
26    }
27
28    fn write_str_all(&mut self, s: &str) -> io::Result<()> {
29        self.upstream.write_all(s.as_bytes())
30    }
31
32    fn fail_doc(&self) -> Self::Error {
33        io::Error::other("Document failed to render")
34    }
35}
36
37/// Writes to something implementing `std::fmt::Write`
38pub struct FmtWrite<W> {
39    upstream: W,
40}
41
42impl<W> FmtWrite<W> {
43    pub fn new(upstream: W) -> FmtWrite<W> {
44        FmtWrite { upstream }
45    }
46}
47
48impl<W> Render for FmtWrite<W>
49where
50    W: fmt::Write,
51{
52    type Error = fmt::Error;
53
54    fn write_str(&mut self, s: &str) -> Result<usize, fmt::Error> {
55        self.write_str_all(s).map(|_| s.len())
56    }
57
58    fn write_str_all(&mut self, s: &str) -> fmt::Result {
59        self.upstream.write_str(s)
60    }
61
62    fn fail_doc(&self) -> Self::Error {
63        fmt::Error
64    }
65}
66
67pub(super) struct BufferWrite {
68    buffer: String,
69}
70
71impl BufferWrite {
72    pub(super) fn new() -> Self {
73        BufferWrite {
74            buffer: String::new(),
75        }
76    }
77
78    pub(super) fn render<W>(&mut self, render: &mut W) -> Result<(), W::Error>
79    where
80        W: ?Sized + Render,
81    {
82        render.write_str_all(&self.buffer)?;
83        Ok(())
84    }
85}
86
87impl Render for BufferWrite {
88    type Error = ();
89
90    fn write_str(&mut self, s: &str) -> Result<usize, Self::Error> {
91        self.buffer.push_str(s);
92        Ok(s.len())
93    }
94
95    fn write_str_all(&mut self, s: &str) -> Result<(), Self::Error> {
96        self.buffer.push_str(s);
97        Ok(())
98    }
99
100    fn fail_doc(&self) -> Self::Error {}
101}
102
103pub(super) fn write_newline<W>(ind: usize, out: &mut W) -> Result<(), W::Error>
104where
105    W: ?Sized + Render,
106{
107    out.write_str_all("\n")?;
108    write_spaces(ind, out)
109}
110
111pub(super) fn write_spaces<W>(spaces: usize, out: &mut W) -> Result<(), W::Error>
112where
113    W: ?Sized + Render,
114{
115    let mut inserted = 0;
116    while inserted < spaces {
117        let insert = SPACES.len().min(spaces - inserted);
118        inserted += out.write_str(&SPACES[..insert])?;
119    }
120
121    Ok(())
122}