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("#![allow(dead_code, unused_imports, clippy::too_many_arguments)]\n");
54 output.push('\n');
55 output.push_str("use ironsbe_core::{\n");
56 output.push_str(" buffer::{ReadBuffer, WriteBuffer},\n");
57 output.push_str(" header::{MessageHeader, GroupHeader, VarDataHeader},\n");
58 output.push_str(" decoder::{SbeDecoder, DecodeError},\n");
59 output.push_str(" encoder::SbeEncoder,\n");
60 output.push_str("};\n");
61 output.push('\n');
62 }
63
64 fn generate_constants(&self, output: &mut String) {
66 output.push_str(&format!(
67 "/// Schema ID for this protocol.\n\
68 pub const SCHEMA_ID: u16 = {};\n",
69 self.ir.schema_id
70 ));
71 output.push_str(&format!(
72 "/// Schema version for this protocol.\n\
73 pub const SCHEMA_VERSION: u16 = {};\n",
74 self.ir.schema_version
75 ));
76 output.push('\n');
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use ironsbe_schema::parse_schema;
84
85 #[test]
86 fn test_generate_simple_schema() {
87 let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
88<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
89 package="test" id="1" version="1" byteOrder="littleEndian">
90 <types>
91 <type name="uint64" primitiveType="uint64"/>
92 </types>
93 <sbe:message name="TestMessage" id="1" blockLength="8">
94 <field name="value" id="1" type="uint64" offset="0"/>
95 </sbe:message>
96</sbe:messageSchema>"#;
97
98 let schema = parse_schema(xml).expect("Failed to parse");
99 let ir = SchemaIr::from_schema(&schema);
100 let generator = Generator::new(&ir);
101 let code = generator.generate();
102
103 assert!(code.contains("SCHEMA_ID: u16 = 1"));
104 assert!(code.contains("SCHEMA_VERSION: u16 = 1"));
105 assert!(code.contains("TestMessageDecoder"));
106 assert!(code.contains("TestMessageEncoder"));
107 }
108}