witx_codegen/
pretty_writer.rs1use std::cell::RefCell;
2use std::convert::Into;
3use std::io::prelude::*;
4use std::rc::Rc;
5
6use super::Error;
7
8pub struct PrettyWriter<W: Write> {
9 writer: Rc<RefCell<W>>,
10 indent: u32,
11 indent_bytes: &'static str,
12 continuation_bytes: &'static str,
13}
14
15impl<W: Write> Clone for PrettyWriter<W> {
16 fn clone(&self) -> Self {
17 PrettyWriter {
18 writer: self.writer.clone(),
19 indent: self.indent,
20 indent_bytes: self.indent_bytes,
21 continuation_bytes: DEFAULT_CONTINUATION_BYTES,
22 }
23 }
24}
25
26const DEFAULT_CONTINUATION_BYTES: &str = " ";
27
28impl<W: Write> PrettyWriter<W> {
29 pub fn new_with_indent(writer: W, indent: u32, indent_bytes: &'static str) -> Self {
31 PrettyWriter {
32 writer: Rc::new(RefCell::new(writer)),
33 indent,
34 indent_bytes,
35 continuation_bytes: DEFAULT_CONTINUATION_BYTES,
36 }
37 }
38
39 pub fn new(writer: W, indent_bytes: &'static str) -> Self {
41 PrettyWriter::new_with_indent(writer, 0, indent_bytes)
42 }
43
44 #[allow(dead_code)]
46 pub fn new_from_writer(&mut self) -> Self {
47 PrettyWriter {
48 writer: self.writer.clone(),
49 indent: 0,
50 indent_bytes: self.indent_bytes,
51 continuation_bytes: DEFAULT_CONTINUATION_BYTES,
52 }
53 }
54
55 pub fn new_block(&mut self) -> Self {
57 PrettyWriter {
58 writer: self.writer.clone(),
59 indent: self.indent + 1,
60 indent_bytes: self.indent_bytes,
61 continuation_bytes: DEFAULT_CONTINUATION_BYTES,
62 }
63 }
64
65 fn _write_all<T: AsRef<[u8]>>(writer: &mut W, buf: T) -> Result<(), Error> {
66 let buf = buf.as_ref();
67 writer.write_all(buf).map_err(Into::into)
68 }
69
70 #[allow(dead_code)]
72 pub fn indent_level(&self) -> u32 {
73 self.indent
74 }
75
76 pub fn indent(&mut self) -> Result<&mut Self, Error> {
78 let indent_bytes = &self.indent_bytes;
79 {
80 let mut writer = self.writer.borrow_mut();
81 for _ in 0..self.indent {
82 Self::_write_all(&mut writer, indent_bytes)?
83 }
84 }
85 Ok(self)
86 }
87
88 #[allow(dead_code)]
90 pub fn space(&mut self) -> Result<&mut Self, Error> {
91 Self::_write_all(&mut self.writer.borrow_mut(), b" ")?;
92 Ok(self)
93 }
94
95 pub fn eol(&mut self) -> Result<&mut Self, Error> {
97 Self::_write_all(&mut self.writer.borrow_mut(), b"\n")?;
98 Ok(self)
99 }
100
101 pub fn eob(&mut self) -> Result<&mut Self, Error> {
103 self.eol()
104 }
105
106 pub fn continuation(&mut self) -> Result<&mut Self, Error> {
108 self.indent()?;
109 let continuation_bytes = &self.continuation_bytes;
110 Self::_write_all(&mut self.writer.borrow_mut(), continuation_bytes)?;
111 Ok(self)
112 }
113
114 pub fn write<T: AsRef<[u8]>>(&mut self, buf: T) -> Result<&mut Self, Error> {
116 let buf = buf.as_ref();
117 Self::_write_all(&mut self.writer.borrow_mut(), buf)?;
118 Ok(self)
119 }
120
121 pub fn write_line<T: AsRef<[u8]>>(&mut self, buf: T) -> Result<&mut Self, Error> {
123 let buf = buf.as_ref();
124 self.indent()?.write(buf)?.eol()
125 }
126
127 pub fn write_lines<T: AsRef<[u8]>>(&mut self, buf: T) -> Result<&mut Self, Error> {
129 let buf = buf.as_ref();
130 for line in buf.lines().flatten() {
131 self.write_line(line)?;
132 }
133 Ok(self)
134 }
135
136 pub fn write_line_continued<T: AsRef<[u8]>>(&mut self, buf: T) -> Result<&mut Self, Error> {
139 let buf = buf.as_ref();
140 self.continuation()?.write(buf)?.eol()
141 }
142}