code_generator/lib.rs
1//! This generator is designed to allow easy reuse of code generation
2//!
3//! # Example
4//!
5//! This example shows how the same structure can be generated into two
6//! different formats.
7//!
8//! ```
9//! # use code_generator::CodeStyle;
10//! # use code_generator::DisplayExt;
11//! # use code_generator::CodeGenerationInfo;
12//! # use code_generator::FunctionSignature;
13//! # use code_generator::Name;
14//! # use code_generator::NewLineType;
15//! # use code_generator::CodeBody;
16//! # use code_generator::IfStatement;
17//! # use code_generator::NameType;
18//! # use code_generator::ForLoop;
19//! # use code_generator::Function;
20//! # use code_generator::CodeSet;
21//! #
22//! let code = CodeSet::new(vec![
23//! Box::new(String::from("#include \"test.h\"")),
24//! Box::new(String::from("")),
25//! Box::new(String::from("")),
26//! Box::new(Function::new(FunctionSignature::new(
27//! Name::new("MyReturnTypeOne"),
28//! Name::new("MyFunctionNameOne"),
29//! vec![
30//! (Name::new("ParamTypeOne"), Name::new("ParamNameOne")),
31//! (Name::new("ParamTypeTwo"), Name::new("ParamNameTwo")),
32//! (Name::new("ParamTypeThree"), Name::new("ParamNameThree")),
33//! ]
34//! ),
35//! CodeSet::new(vec![
36//! Box::new(IfStatement::new(
37//! Name::new_with_type("ParamNameThree", NameType::Member),
38//! CodeBody::new(vec![
39//! Box::new(ForLoop::new(
40//! String::from("ParamTypeTwo i = 0"),
41//! String::from("i < param_name_two"),
42//! String::from("i++"),
43//! vec![
44//! Box::new(String::from("printf(\"ParamOne: {}\\n\", param_name_one);"))
45//! ]
46//! ))
47//! ])
48//! ))
49//! ])
50//! )),
51//! Box::new(String::from("")),
52//! ]);
53//!
54//! let mut info = CodeGenerationInfo::from_style(CodeStyle::KnR);
55//! info.set_new_line_type(NewLineType::Nl);
56//! assert_eq!(
57//! "#include \"test.h\"
58//!
59//!
60//! MyReturnTypeOne my_function_name_one(ParamTypeOne param_name_one, ParamTypeTwo param_name_two, ParamTypeThree param_name_three) {
61//! if (param_name_three) {
62//! for (ParamTypeTwo i = 0; i < param_name_two; i++) {
63//! printf(\"ParamOne: {}\\n\", param_name_one);
64//! }
65//! }
66//! }
67//! ", format!("{}", code.display(info)));
68//!
69//! let mut info = CodeGenerationInfo::from_style(CodeStyle::Allman);
70//! info.set_new_line_type(NewLineType::Nl);
71//! assert_eq!(
72//! "#include \"test.h\"
73//!
74//!
75//! MyReturnTypeOne my_function_name_one(ParamTypeOne param_name_one, ParamTypeTwo param_name_two, ParamTypeThree param_name_three)
76//! {
77//! if (param_name_three)
78//! {
79//! for (ParamTypeTwo i = 0; i < param_name_two; i++)
80//! {
81//! printf(\"ParamOne: {}\\n\", param_name_one);
82//! }
83//! }
84//! }
85//! ", format!("{}", code.display(info)));
86//!
87//!
88//!
89//! ```
90//!
91//! Because the output format is not dependent on the input data structure, it
92//! is very easy to make code generation modular. Any pieces of generated code
93//! that share structure, can share a generator.
94
95mod building_block_generators;
96mod setup;
97mod flow_control_generators;
98mod data_type_generators;
99mod as_case;
100
101pub use building_block_generators::*;
102pub use setup::*;
103pub use flow_control_generators::*;
104pub use data_type_generators::*;
105
106
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn name_camel_case() {
114 let default_gen_info: CodeGenerationInfo = CodeGenerationInfo::from_style(CodeStyle::KnR);
115 let case = NameType::FixedCase(CaseType::CamelCase);
116 let name = Name::new_with_type("testName", case);
117 let result = format!("{}", name.display(default_gen_info));
118 assert_eq!(result, "testName");
119 }
120}