blob: 8d7499b95f2ee80560aedfc4eca096bca5d8036a [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001use std::fmt::{self, Arguments, Write};
2
3pub(crate) struct OutFile {
4 pub namespace: Vec<String>,
5 pub header: bool,
6 content: Vec<u8>,
7 section_pending: bool,
David Tolnayb92e66f2020-03-01 13:36:55 -08008 blocks: Vec<&'static str>,
9 blocks_pending: usize,
David Tolnay7db73692019-10-20 14:51:12 -040010}
11
12impl OutFile {
13 pub fn new(namespace: Vec<String>, header: bool) -> Self {
14 OutFile {
15 namespace,
16 header,
17 content: Vec::new(),
18 section_pending: false,
David Tolnayb92e66f2020-03-01 13:36:55 -080019 blocks: Vec::new(),
20 blocks_pending: 0,
David Tolnay7db73692019-10-20 14:51:12 -040021 }
22 }
23
24 // Write a blank line if the preceding section had any contents.
25 pub fn next_section(&mut self) {
26 self.section_pending = true;
27 }
28
29 pub fn begin_block(&mut self, block: &'static str) {
David Tolnayb92e66f2020-03-01 13:36:55 -080030 self.blocks.push(block);
31 self.blocks_pending += 1;
David Tolnay7db73692019-10-20 14:51:12 -040032 }
33
34 pub fn end_block(&mut self) {
David Tolnayb92e66f2020-03-01 13:36:55 -080035 if self.blocks_pending > 0 {
36 self.blocks_pending -= 1;
David Tolnay7db73692019-10-20 14:51:12 -040037 } else {
38 self.content.extend_from_slice(b"} // ");
David Tolnayb92e66f2020-03-01 13:36:55 -080039 self.content
40 .extend_from_slice(self.blocks.pop().unwrap().as_bytes());
David Tolnay7db73692019-10-20 14:51:12 -040041 self.content.push(b'\n');
David Tolnay7db73692019-10-20 14:51:12 -040042 self.section_pending = true;
43 }
44 }
45
46 pub fn write_fmt(&mut self, args: Arguments) {
47 Write::write_fmt(self, args).unwrap();
48 }
49}
50
51impl Write for OutFile {
52 fn write_str(&mut self, s: &str) -> fmt::Result {
53 if !s.is_empty() {
David Tolnayb92e66f2020-03-01 13:36:55 -080054 if self.blocks_pending > 0 {
David Tolnay7db73692019-10-20 14:51:12 -040055 self.content.push(b'\n');
David Tolnayb92e66f2020-03-01 13:36:55 -080056 for block in &self.blocks[self.blocks.len() - self.blocks_pending..] {
57 self.content.extend_from_slice(block.as_bytes());
58 self.content.extend_from_slice(b" {\n");
59 }
60 self.blocks_pending = 0;
David Tolnay7db73692019-10-20 14:51:12 -040061 self.section_pending = false;
62 } else if self.section_pending {
63 self.content.push(b'\n');
64 self.section_pending = false;
65 }
66 self.content.extend_from_slice(s.as_bytes());
67 }
68 Ok(())
69 }
70}
71
72impl AsRef<[u8]> for OutFile {
73 fn as_ref(&self) -> &[u8] {
74 &self.content
75 }
76}