zerodds_corba_rust/
emitter.rs1use std::collections::HashMap;
6
7use zerodds_idl::ast::types::{Definition, InterfaceDef, Specification};
8
9use crate::error::Result;
10
11pub(crate) type InterfaceRegistry<'a> = HashMap<String, &'a InterfaceDef>;
15
16#[derive(Debug, Clone, Default)]
18pub struct CorbaRustGenOptions {
19 pub header_comment: Option<String>,
22}
23
24pub fn generate_corba_rust_module(
31 spec: &Specification,
32 opts: &CorbaRustGenOptions,
33) -> Result<String> {
34 let mut out = String::new();
35 out.push_str("// SPDX-License-Identifier: Apache-2.0\n");
36 if let Some(c) = &opts.header_comment {
37 for line in c.lines() {
38 out.push_str("// ");
39 out.push_str(line);
40 out.push('\n');
41 }
42 }
43 out.push_str("// Auto-generated by `zerodds-corba-rust`. Do not edit by hand.\n\n");
44 out.push_str("#![allow(clippy::too_many_lines)]\n");
45 out.push_str("#![allow(unused_imports, unused_variables)]\n\n");
46
47 let mut registry: InterfaceRegistry<'_> = HashMap::new();
48 collect_interfaces(spec, &mut registry);
49
50 for def in &spec.definitions {
51 emit_definition(&mut out, def, ®istry)?;
52 }
53 Ok(out)
54}
55
56fn collect_interfaces<'a>(spec: &'a Specification, reg: &mut InterfaceRegistry<'a>) {
58 for def in &spec.definitions {
59 collect_from_def(def, reg);
60 }
61}
62
63fn collect_from_def<'a>(def: &'a Definition, reg: &mut InterfaceRegistry<'a>) {
65 use zerodds_idl::ast::types::InterfaceDcl;
66 match def {
67 Definition::Interface(InterfaceDcl::Def(d)) => {
68 reg.insert(d.name.text.clone(), d);
69 }
70 Definition::Module(m) => {
71 for inner in &m.definitions {
72 collect_from_def(inner, reg);
73 }
74 }
75 _ => {}
76 }
77}
78
79fn emit_definition(
83 out: &mut String,
84 def: &Definition,
85 registry: &InterfaceRegistry<'_>,
86) -> Result<()> {
87 match def {
88 Definition::Module(m) => emit_module(out, m, registry)?,
89 Definition::Interface(i_dcl) => {
90 use zerodds_idl::ast::types::InterfaceDcl;
91 match i_dcl {
92 InterfaceDcl::Def(def) => {
93 crate::interface_emit::emit_interface(out, def, registry)?;
94 out.push('\n');
95 }
96 InterfaceDcl::Forward(_) => {}
97 }
98 }
99 Definition::ValueDef(v) => {
100 crate::valuetype_emit::emit_valuetype(out, v)?;
101 out.push('\n');
102 }
103 Definition::Component(c) => {
104 crate::component_emit::emit_component(out, c)?;
105 out.push('\n');
106 }
107 Definition::Home(h) => {
108 crate::component_emit::emit_home(out, h)?;
109 out.push('\n');
110 }
111 _ => {}
114 }
115 Ok(())
116}
117
118fn emit_module(
120 out: &mut String,
121 m: &zerodds_idl::ast::types::ModuleDef,
122 registry: &InterfaceRegistry<'_>,
123) -> Result<()> {
124 out.push_str("pub mod ");
125 out.push_str(&m.name.text);
126 out.push_str(" {\n");
127 for inner in &m.definitions {
128 let mut inner_out = String::new();
129 emit_definition(&mut inner_out, inner, registry)?;
130 for line in inner_out.lines() {
131 if line.is_empty() {
132 out.push('\n');
133 } else {
134 out.push_str(" ");
135 out.push_str(line);
136 out.push('\n');
137 }
138 }
139 }
140 out.push_str("}\n\n");
141 Ok(())
142}