blob: 506ce6c8f7490a54e312e4308d80cf8564a79bcd [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 Tolnay9ad1fbc2020-03-01 14:01:24 -08008 blocks_pending: Vec<&'static str>,
David Tolnay7db73692019-10-20 14:51:12 -04009}
10
11impl OutFile {
12 pub fn new(namespace: Vec<String>, header: bool) -> Self {
13 OutFile {
14 namespace,
15 header,
16 content: Vec::new(),
17 section_pending: false,
David Tolnay9ad1fbc2020-03-01 14:01:24 -080018 blocks_pending: Vec::new(),
David Tolnay7db73692019-10-20 14:51:12 -040019 }
20 }
21
22 // Write a blank line if the preceding section had any contents.
23 pub fn next_section(&mut self) {
24 self.section_pending = true;
25 }
26
27 pub fn begin_block(&mut self, block: &'static str) {
David Tolnay9ad1fbc2020-03-01 14:01:24 -080028 self.blocks_pending.push(block);
David Tolnay7db73692019-10-20 14:51:12 -040029 }
30
David Tolnay9ad1fbc2020-03-01 14:01:24 -080031 pub fn end_block(&mut self, block: &'static str) {
32 if self.blocks_pending.pop().is_none() {
David Tolnay7db73692019-10-20 14:51:12 -040033 self.content.extend_from_slice(b"} // ");
David Tolnay9ad1fbc2020-03-01 14:01:24 -080034 self.content.extend_from_slice(block.as_bytes());
David Tolnay7db73692019-10-20 14:51:12 -040035 self.content.push(b'\n');
David Tolnay7db73692019-10-20 14:51:12 -040036 self.section_pending = true;
37 }
38 }
39
40 pub fn write_fmt(&mut self, args: Arguments) {
41 Write::write_fmt(self, args).unwrap();
42 }
43}
44
45impl Write for OutFile {
46 fn write_str(&mut self, s: &str) -> fmt::Result {
47 if !s.is_empty() {
David Tolnay9ad1fbc2020-03-01 14:01:24 -080048 if !self.blocks_pending.is_empty() {
David Tolnay7db73692019-10-20 14:51:12 -040049 self.content.push(b'\n');
David Tolnay9ad1fbc2020-03-01 14:01:24 -080050 for block in self.blocks_pending.drain(..) {
David Tolnayb92e66f2020-03-01 13:36:55 -080051 self.content.extend_from_slice(block.as_bytes());
52 self.content.extend_from_slice(b" {\n");
53 }
David Tolnay7db73692019-10-20 14:51:12 -040054 self.section_pending = false;
55 } else if self.section_pending {
56 self.content.push(b'\n');
57 self.section_pending = false;
58 }
59 self.content.extend_from_slice(s.as_bytes());
60 }
61 Ok(())
62 }
63}
64
65impl AsRef<[u8]> for OutFile {
66 fn as_ref(&self) -> &[u8] {
67 &self.content
68 }
69}