protobuf_dbml/generator/
mod.rs1#[derive(Debug, PartialEq, Clone)]
2pub struct Codegen {
3 root_block: Block,
4}
5
6impl Codegen {
7 pub fn new() -> Self {
8 let codegen = Self {
9 root_block: Block::root(),
10 };
11
12 codegen
13 }
14
15 pub fn line(mut self, line_content: impl ToString) -> Self {
16 self.root_block = self.root_block.line(line_content);
17
18 self
19 }
20
21 pub fn line_cond(mut self, cond: bool, line_content: impl ToString) -> Self {
22 self.root_block = self.root_block.line_cond(cond, line_content);
23
24 self
25 }
26
27 pub fn line_skip(mut self, line_count: usize) -> Self {
28 self.root_block = self.root_block.line_skip(line_count);
29
30 self
31 }
32
33 pub fn block(mut self, block: Block) -> Self {
34 self.root_block = self.root_block.block(block);
35
36 self
37 }
38
39 pub fn block_vec(mut self, block_vec: Vec<Block>) -> Self {
40 self.root_block = self.root_block.block_vec(block_vec);
41
42 self
43 }
44}
45
46impl ToString for Codegen {
47 fn to_string(&self) -> String {
48 self.root_block.to_string()
49 }
50}
51
52#[derive(Debug, PartialEq, Clone, Default)]
53pub struct Block {
54 level: usize,
56 content_before_block: Option<String>,
58 content: String,
60}
61
62impl Block {
63 fn root() -> Self {
64 Self {
65 level: 0,
66 content_before_block: None,
67 content: String::new(),
68 }
69 }
70
71 pub fn new(level: usize, before_block_content: Option<impl ToString>) -> Self {
72 let content = if let Some(impl_string) = before_block_content {
73 Some(impl_string.to_string())
74 } else {
75 None
76 };
77
78 Self {
79 level,
80 content_before_block: content,
81 content: String::new(),
82 }
83 }
84
85 pub fn line(mut self, line_content: impl ToString) -> Self {
87 let indent = "\t".repeat(self.level);
88
89 let new_content = format!("{}{}", indent, line_content.to_string());
90
91 self.content = format!("{}{}\n", self.content, new_content);
92
93 self
94 }
95
96 pub fn line_cond(mut self, cond: bool, line_content: impl ToString) -> Self {
98 if !cond {
99 return self;
100 }
101
102 let indent = "\t".repeat(self.level);
103
104 let new_content = format!("{}{}", indent, line_content.to_string());
105
106 self.content = format!("{}{}\n", self.content, new_content);
107
108 self
109 }
110
111 pub fn line_skip(mut self, line_count: usize) -> Self {
113 let line_string = "\n".repeat(line_count);
114
115 self.content = format!("{}{}", self.content, line_string);
116
117 self
118 }
119
120 pub fn block(mut self, block: Block) -> Self {
122 self.content = format!("{}{}\n", self.content, block.to_string());
123
124 self
125 }
126
127 pub fn block_vec(mut self, block_vec: Vec<Block>) -> Self {
129 for block in block_vec.into_iter() {
130 self.content = format!("{}\n{}\n", self.content, block.to_string());
131 }
132
133 self
134 }
135}
136
137impl ToString for Block {
138 fn to_string(&self) -> String {
139 let out = if self.level == 0 {
140 format!("{}", self.content.clone())
141 } else {
142 let block_indent = if self.level == 1 {
143 String::new()
144 } else {
145 "\t".repeat(self.level - 1)
146 };
147
148 let upper_block = if let Some(content_before_block) = self.content_before_block.clone() {
149 format!("{}{} {}", block_indent, content_before_block, "{")
150 } else {
151 format!("{}{}", block_indent, "{")
152 };
153
154 if self.content.is_empty() {
155 format!("{}{}", upper_block, "}")
156 } else {
157 let lower_block = format!("{}{}", block_indent, "}");
158
159 format!("{}\n{}{}", upper_block, self.content.clone(), lower_block)
160 }
161 };
162
163 out
164 }
165}