zerodds_dlrl_codegen/
cpp.rs1use alloc::format;
7use alloc::string::String;
8
9use crate::DlrlTypeInfo;
10
11#[allow(clippy::format_collect)]
14#[must_use]
15pub fn generate_cpp_object(info: &DlrlTypeInfo) -> String {
16 let cls = simple_name(&info.name);
17 let mut out = format!(
18 "// Generated DLRL Object — Spec §B.6\n\
19class {cls} : public DLRL::ObjectRoot {{\npublic:\n"
20 );
21 for k in &info.keys {
22 out.push_str(&format!(" DDS::Long {k}_;\n"));
23 out.push_str(&format!(
24 " DDS::Long get_{k}() const {{ return {k}_; }}\n"
25 ));
26 }
27 for (rel, target) in &info.relations {
28 let target_cls = simple_name(target);
29 out.push_str(&format!(
30 " DLRL::RefList< {target_cls}* > {rel}_;\n\
31 DLRL::RefList< {target_cls}* >& {rel}() {{ return {rel}_; }}\n"
32 ));
33 }
34 out.push_str("};\n");
35 out
36}
37
38#[must_use]
40pub fn generate_cpp_home(info: &DlrlTypeInfo) -> String {
41 let cls = simple_name(&info.name);
42 format!(
43 "// Generated DLRL Home — Spec §B.3\n\
44class {cls}Home : public DLRL::HomeBase {{\npublic:\n\
45 {cls}* create();\n\
46 void destroy({cls}* obj);\n\
47 {cls}* find_by_key(/* key fields */);\n\
48}};\n"
49 )
50}
51
52fn simple_name(scoped: &str) -> &str {
53 scoped.rsplit("::").next().unwrap_or(scoped)
54}
55
56#[cfg(test)]
57#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
58mod tests {
59 use super::*;
60
61 fn trade_info() -> DlrlTypeInfo {
62 DlrlTypeInfo {
63 name: "demo::Trade".into(),
64 keys: alloc::vec!["symbol".into()],
65 relations: alloc::vec![("quotes".into(), "demo::Quote".into())],
66 }
67 }
68
69 #[test]
70 fn cpp_object_inherits_object_root() {
71 let s = generate_cpp_object(&trade_info());
72 assert!(s.contains("class Trade : public DLRL::ObjectRoot"));
73 assert!(s.contains("symbol_"));
74 assert!(s.contains("get_symbol"));
75 assert!(s.contains("RefList< Quote* > quotes_"));
76 }
77
78 #[test]
79 fn cpp_home_inherits_home_base() {
80 let s = generate_cpp_home(&trade_info());
81 assert!(s.contains("class TradeHome : public DLRL::HomeBase"));
82 assert!(s.contains("Trade* create();"));
83 assert!(s.contains("void destroy(Trade* obj);"));
84 }
85
86 #[test]
87 fn simple_name_strips_scope() {
88 assert_eq!(simple_name("a::b::C"), "C");
89 assert_eq!(simple_name("Foo"), "Foo");
90 }
91}