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