baobao_codegen/
file_builder.rs1use crate::{CodeBuilder, ImportCollector, Indent};
4
5#[derive(Debug, Clone)]
22pub struct FileBuilder {
23 pub imports: ImportCollector,
25 pub code: CodeBuilder,
27}
28
29impl FileBuilder {
30 pub fn new(indent: Indent) -> Self {
32 Self {
33 imports: ImportCollector::new(),
34 code: CodeBuilder::new(indent),
35 }
36 }
37
38 pub fn rust() -> Self {
40 Self::new(Indent::RUST)
41 }
42
43 pub fn typescript() -> Self {
45 Self::new(Indent::TYPESCRIPT)
46 }
47
48 pub fn go() -> Self {
50 Self::new(Indent::GO)
51 }
52
53 pub fn add_import(mut self, module: &str, symbol: &str) -> Self {
55 self.imports.add(module, symbol);
56 self
57 }
58
59 pub fn add_module(mut self, module: &str) -> Self {
61 self.imports.add_module(module);
62 self
63 }
64
65 pub fn with_code<F>(mut self, f: F) -> Self
67 where
68 F: FnOnce(CodeBuilder) -> CodeBuilder,
69 {
70 self.code = f(self.code);
71 self
72 }
73
74 pub fn has_imports(&self) -> bool {
76 !self.imports.is_empty()
77 }
78
79 pub fn into_parts(self) -> (ImportCollector, CodeBuilder) {
81 (self.imports, self.code)
82 }
83}
84
85impl Default for FileBuilder {
86 fn default() -> Self {
87 Self::rust()
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_file_builder_basic() {
97 let builder = FileBuilder::rust()
98 .add_import("std::io", "Read")
99 .add_import("std::io", "Write")
100 .with_code(|c| c.line("fn main() {}"));
101
102 assert!(builder.imports.has_symbol("std::io", "Read"));
103 assert!(builder.imports.has_symbol("std::io", "Write"));
104 assert!(builder.code.as_str().contains("fn main()"));
105 }
106
107 #[test]
108 fn test_file_builder_fluent() {
109 let builder = FileBuilder::rust()
110 .add_import("clap", "Parser")
111 .add_import("clap", "Subcommand")
112 .with_code(|c| c.line("#[derive(Parser)]").line("struct Cli {}"));
113
114 assert!(builder.imports.has_module("clap"));
115 assert!(builder.code.as_str().contains("#[derive(Parser)]"));
116 }
117}