ironsbe_codegen/
generator.rs1use ironsbe_schema::ir::SchemaIr;
4
5use crate::rust::{EnumGenerator, MessageGenerator, TypeGenerator};
6
7pub struct Generator<'a> {
9 ir: &'a SchemaIr,
10}
11
12impl<'a> Generator<'a> {
13 #[must_use]
15 pub fn new(ir: &'a SchemaIr) -> Self {
16 Self { ir }
17 }
18
19 #[must_use]
21 pub fn generate(&self) -> String {
22 let mut output = String::with_capacity(64 * 1024);
23
24 self.generate_header(&mut output);
26
27 self.generate_constants(&mut output);
29
30 let type_gen = TypeGenerator::new(self.ir);
32 output.push_str(&type_gen.generate());
33
34 let enum_gen = EnumGenerator::new(self.ir);
36 output.push_str(&enum_gen.generate());
37
38 let msg_gen = MessageGenerator::new(self.ir);
40 output.push_str(&msg_gen.generate());
41
42 output
43 }
44
45 fn generate_header(&self, output: &mut String) {
47 output.push_str("// Generated by IronSBE codegen - DO NOT EDIT\n");
48 output.push_str(&format!(
49 "// Schema: {} v{}\n",
50 self.ir.package, self.ir.schema_version
51 ));
52 output.push('\n');
53 output.push_str("use ironsbe_core::{\n");
54 output.push_str(" buffer::{ReadBuffer, WriteBuffer},\n");
55 output.push_str(" header::{MessageHeader, GroupHeader, VarDataHeader},\n");
56 output.push_str(" decoder::{SbeDecoder, DecodeError},\n");
57 output.push_str(" encoder::SbeEncoder,\n");
58 output.push_str("};\n");
59 output.push('\n');
60 }
61
62 fn generate_constants(&self, output: &mut String) {
64 output.push_str(&format!(
65 "/// Schema ID for this protocol.\n\
66 pub const SCHEMA_ID: u16 = {};\n",
67 self.ir.schema_id
68 ));
69 output.push_str(&format!(
70 "/// Schema version for this protocol.\n\
71 pub const SCHEMA_VERSION: u16 = {};\n",
72 self.ir.schema_version
73 ));
74 output.push('\n');
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use ironsbe_schema::parse_schema;
82
83 #[test]
84 fn test_generate_simple_schema() {
85 let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
86<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
87 package="test" id="1" version="1" byteOrder="littleEndian">
88 <types>
89 <type name="uint64" primitiveType="uint64"/>
90 </types>
91 <sbe:message name="TestMessage" id="1" blockLength="8">
92 <field name="value" id="1" type="uint64" offset="0"/>
93 </sbe:message>
94</sbe:messageSchema>"#;
95
96 let schema = parse_schema(xml).expect("Failed to parse");
97 let ir = SchemaIr::from_schema(&schema);
98 let generator = Generator::new(&ir);
99 let code = generator.generate();
100
101 assert!(code.contains("SCHEMA_ID: u16 = 1"));
102 assert!(code.contains("SCHEMA_VERSION: u16 = 1"));
103 assert!(code.contains("TestMessageDecoder"));
104 assert!(code.contains("TestMessageEncoder"));
105 }
106}