marine/
marine_interface.rs1use super::IRecordType;
18use super::itype_text_view;
19use crate::MarineModuleInterface;
20
21use itertools::Itertools;
22use serde::Serialize;
23
24use std::fmt;
25use std::collections::HashMap;
26
27#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
28pub struct MarineInterface<'a> {
29 pub modules: HashMap<&'a str, MarineModuleInterface<'a>>,
30}
31
32impl<'a> fmt::Display for MarineInterface<'a> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 print_record_types(self.modules.values(), f)?;
35 print_functions_sign(self.modules.iter(), f)
36 }
37}
38
39fn print_record_types<'r>(
40 modules: impl Iterator<Item = &'r MarineModuleInterface<'r>>,
41 f: &mut fmt::Formatter<'_>,
42) -> fmt::Result {
43 use std::collections::HashSet;
44 writeln!(f, "exported data types (combined from all modules):")?;
45 let mut printed_record_types: HashSet<&IRecordType> = HashSet::new();
46
47 for module in modules {
48 for (_, record_type) in module.record_types.iter() {
49 if !printed_record_types.insert(record_type) {
50 continue;
52 }
53
54 writeln!(f, "data {}:", record_type.name)?;
55
56 for field in record_type.fields.iter() {
57 writeln!(
58 f,
59 " {}: {}",
60 field.name,
61 itype_text_view(&field.ty, module.record_types)
62 )?;
63 }
64 }
65 }
66
67 if printed_record_types.is_empty() {
68 writeln!(f, "<no exported data types>")?;
69 }
70
71 writeln!(f)
72}
73
74fn print_functions_sign<'r>(
75 modules: impl Iterator<Item = (&'r &'r str, &'r MarineModuleInterface<'r>)>,
76 f: &mut fmt::Formatter<'_>,
77) -> fmt::Result {
78 let modules = modules.sorted_by(|lhs, rhs| lhs.0.cmp(rhs.0));
79 writeln!(f, "exported functions:")?;
80 for (name, module_interface) in modules {
81 writeln!(f, "{}:", *name)?;
82 if module_interface.function_signatures.is_empty() {
83 writeln!(f, "<no exported functions>")?;
84 continue;
85 }
86
87 for function_signature in module_interface.function_signatures.iter() {
88 write!(f, " func {}(", function_signature.name)?;
89
90 let args = function_signature
91 .arguments
92 .iter()
93 .map(|arg| {
94 format!(
95 "{}: {}",
96 arg.name,
97 itype_text_view(&arg.ty, module_interface.record_types)
98 )
99 })
100 .join(", ");
101
102 let outputs = &function_signature.outputs;
103 if outputs.is_empty() {
104 writeln!(f, "{})", args)?;
105 } else if outputs.len() == 1 {
106 writeln!(
107 f,
108 "{}) -> {}",
109 args,
110 itype_text_view(&outputs[0], module_interface.record_types)
111 )?;
112 } else {
113 unimplemented!()
115 }
116 }
117 }
118
119 Ok(())
120}