witx_codegen/cpp/
function.rs1use super::*;
2use std::io::Write;
3
4impl CppGenerator {
5 pub fn define_func<T: Write>(
6 w: &mut PrettyWriter<T>,
7 func_witx: &witx::Function,
9 ) -> Result<(), Error> {
10 assert_eq!(func_witx.abi, witx::Abi::Preview1);
11 let name = func_witx.name.as_str().to_string();
12 let params_witx = &func_witx.params;
13 let mut params = vec![];
14 for param_witx in params_witx {
15 let param_name = param_witx.name.as_str();
16 let param_type = ASType::from(¶m_witx.tref);
17 params.push((param_name.to_string(), param_type));
18 }
19
20 let results_witx = &func_witx.results;
21 assert_eq!(results_witx.len(), 1);
22 let result_witx = &results_witx[0];
23 let result = ASType::from(&result_witx.tref);
24 let result = match result {
25 ASType::Result(result) => result,
26 _ => unreachable!(),
27 };
28
29 let ok_type = result.ok_type.clone();
30
31 let docs = &func_witx.docs;
32 if !docs.is_empty() {
33 Self::write_docs(w, docs)?;
34 }
35
36 let mut params_decomposed = vec![];
37
38 for param in ¶ms {
39 let mut decomposed = param.1.decompose(¶m.0, false);
40 params_decomposed.append(&mut decomposed);
41 }
42
43 let mut results = vec![];
44 if let ASType::Tuple(tuple_members) = ok_type.as_ref().leaf() {
46 for (i, tuple_member) in tuple_members.iter().enumerate() {
47 let name = format!("result{}_ptr", i);
48 results.push((name, tuple_member.type_.clone()));
49 }
50 } else {
51 let name = "result_ptr";
52 results.push((name.to_string(), ok_type));
53 }
54
55 let mut results_decomposed = vec![];
56 for result in &results {
57 let mut decomposed = result.1.decompose(&result.0, true);
58 results_decomposed.append(&mut decomposed);
59 }
60
61 let results_decomposed_deref = results_decomposed
62 .iter()
63 .map(|result_ptr_type| match result_ptr_type.type_.as_ref() {
64 ASType::MutPtr(result_type) => ASTypeDecomposed {
65 name: result_ptr_type.name.clone(),
66 type_: result_type.clone(),
67 },
68 _ => panic!("Result type is not a pointer"),
69 })
70 .collect::<Vec<_>>();
71 let results_set = results_decomposed_deref
72 .iter()
73 .map(|result| result.type_.as_lang())
74 .collect::<Vec<_>>();
75 let rust_fn_result_str = match results_set.len() {
76 0 => "std::monostate".to_string(),
77 1 => results_set[0].clone(),
78 _ => format!("std::tuple<{}>", results_set.join(", ")),
79 };
80
81 w.indent()?.write(format!(
82 "Expected<{}, {}> {}(",
83 rust_fn_result_str,
84 result.error_type.as_lang(),
85 name.as_fn()
86 ))?;
87
88 if !params_decomposed.is_empty() || !results.is_empty() {
89 w.eol()?;
90 }
91 for (i, param) in params_decomposed.iter().enumerate() {
92 let eol = if i + 1 == params_decomposed.len() {
93 ""
94 } else {
95 ","
96 };
97 w.write_line_continued(format!(
98 "{} {}{}",
99 param.type_.as_lang(),
100 param.name.as_var(),
101 eol
102 ))?;
103 }
104
105 w.write_line(");")?;
106 w.eob()?;
107
108 let signature_witx = func_witx.wasm_signature(witx::CallMode::DefinedImport);
109 let params_count_witx = signature_witx.params.len() + signature_witx.results.len();
110 assert_eq!(
111 params_count_witx,
112 params_decomposed.len() + results_decomposed.len() + 1
113 );
114
115 Ok(())
116 }
117}