blob: 35f2cd76b65983d21fe99e8d2d9638ff7dcf7c15 [file] [log] [blame]
David Tolnay9c68b1a2020-03-06 11:12:55 -08001use crate::gen::include::Includes;
David Tolnay754e21c2020-03-29 20:58:46 -07002use crate::gen::namespace::Namespace;
David Tolnay7ece56f2020-03-29 21:21:38 -07003use std::cell::RefCell;
David Tolnay7db73692019-10-20 14:51:12 -04004use std::fmt::{self, Arguments, Write};
5
6pub(crate) struct OutFile {
David Tolnay754e21c2020-03-29 20:58:46 -07007 pub namespace: Namespace,
David Tolnay7db73692019-10-20 14:51:12 -04008 pub header: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -08009 pub include: Includes,
David Tolnay7ece56f2020-03-29 21:21:38 -070010 content: RefCell<Content>,
11}
12
13struct Content {
14 bytes: Vec<u8>,
David Tolnay7db73692019-10-20 14:51:12 -040015 section_pending: bool,
David Tolnay9ad1fbc2020-03-01 14:01:24 -080016 blocks_pending: Vec<&'static str>,
David Tolnay7db73692019-10-20 14:51:12 -040017}
18
19impl OutFile {
David Tolnay754e21c2020-03-29 20:58:46 -070020 pub fn new(namespace: Namespace, header: bool) -> Self {
David Tolnay7db73692019-10-20 14:51:12 -040021 OutFile {
22 namespace,
23 header,
David Tolnay9c68b1a2020-03-06 11:12:55 -080024 include: Includes::new(),
David Tolnay7ece56f2020-03-29 21:21:38 -070025 content: RefCell::new(Content {
26 bytes: Vec::new(),
27 section_pending: false,
28 blocks_pending: Vec::new(),
29 }),
David Tolnay7db73692019-10-20 14:51:12 -040030 }
31 }
32
33 // Write a blank line if the preceding section had any contents.
34 pub fn next_section(&mut self) {
David Tolnay7ece56f2020-03-29 21:21:38 -070035 let content = self.content.get_mut();
36 content.section_pending = true;
David Tolnay7db73692019-10-20 14:51:12 -040037 }
38
39 pub fn begin_block(&mut self, block: &'static str) {
David Tolnay7ece56f2020-03-29 21:21:38 -070040 let content = self.content.get_mut();
41 content.blocks_pending.push(block);
David Tolnay7db73692019-10-20 14:51:12 -040042 }
43
David Tolnay9ad1fbc2020-03-01 14:01:24 -080044 pub fn end_block(&mut self, block: &'static str) {
David Tolnay7ece56f2020-03-29 21:21:38 -070045 let content = self.content.get_mut();
46 if content.blocks_pending.pop().is_none() {
47 content.bytes.extend_from_slice(b"} // ");
48 content.bytes.extend_from_slice(block.as_bytes());
49 content.bytes.push(b'\n');
50 content.section_pending = true;
David Tolnay7db73692019-10-20 14:51:12 -040051 }
52 }
53
David Tolnay9c68b1a2020-03-06 11:12:55 -080054 pub fn prepend(&mut self, section: String) {
David Tolnay7ece56f2020-03-29 21:21:38 -070055 let content = self.content.get_mut();
56 content.bytes.splice(..0, section.into_bytes());
David Tolnay9c68b1a2020-03-06 11:12:55 -080057 }
58
David Tolnay7ece56f2020-03-29 21:21:38 -070059 pub fn write_fmt(&self, args: Arguments) {
60 let content = &mut *self.content.borrow_mut();
61 Write::write_fmt(content, args).unwrap();
62 }
63
64 pub fn content(&self) -> Vec<u8> {
65 self.content.borrow().bytes.clone()
David Tolnay7db73692019-10-20 14:51:12 -040066 }
67}
68
David Tolnay7ece56f2020-03-29 21:21:38 -070069impl Write for Content {
David Tolnay7db73692019-10-20 14:51:12 -040070 fn write_str(&mut self, s: &str) -> fmt::Result {
71 if !s.is_empty() {
David Tolnay9ad1fbc2020-03-01 14:01:24 -080072 if !self.blocks_pending.is_empty() {
David Tolnay7ece56f2020-03-29 21:21:38 -070073 if !self.bytes.is_empty() {
74 self.bytes.push(b'\n');
David Tolnay3577d452020-03-17 21:48:13 -070075 }
David Tolnay9ad1fbc2020-03-01 14:01:24 -080076 for block in self.blocks_pending.drain(..) {
David Tolnay7ece56f2020-03-29 21:21:38 -070077 self.bytes.extend_from_slice(block.as_bytes());
78 self.bytes.extend_from_slice(b" {\n");
David Tolnayb92e66f2020-03-01 13:36:55 -080079 }
David Tolnay7db73692019-10-20 14:51:12 -040080 self.section_pending = false;
81 } else if self.section_pending {
David Tolnay7ece56f2020-03-29 21:21:38 -070082 if !self.bytes.is_empty() {
83 self.bytes.push(b'\n');
David Tolnay3577d452020-03-17 21:48:13 -070084 }
David Tolnay7db73692019-10-20 14:51:12 -040085 self.section_pending = false;
86 }
David Tolnay7ece56f2020-03-29 21:21:38 -070087 self.bytes.extend_from_slice(s.as_bytes());
David Tolnay7db73692019-10-20 14:51:12 -040088 }
89 Ok(())
90 }
91}