oo_bindgen/backend/c/cpp/conversion/
to_native_function_argument.rs

1use crate::model::*;
2
3use crate::backend::c::cpp::conversion::{CoreCppType, ToNative};
4use crate::backend::c::cpp::formatting::FriendClass;
5
6pub(crate) trait ToNativeFunctionArgument {
7    fn to_native_function_argument(&self, expr: String) -> String;
8
9    // some function arguments cannot be converted at the call site
10    // and require a shadow parameter. The shadow parameter itself
11    // map require some mapping at the call site.
12    fn shadow_parameter_mapping(&self) -> Option<Box<dyn Fn(String) -> String>>;
13
14    fn requires_shadow_parameter(&self) -> bool {
15        self.shadow_parameter_mapping().is_some()
16    }
17}
18
19impl ToNativeFunctionArgument for FunctionArgument {
20    fn to_native_function_argument(&self, expr: String) -> String {
21        match self {
22            FunctionArgument::Basic(x) => x.to_native(expr),
23            FunctionArgument::String(x) => x.to_native(expr),
24            FunctionArgument::Collection(x) => {
25                format!("{}({})", x.collection_class.core_cpp_type(), expr)
26            }
27            FunctionArgument::Struct(_) => {
28                format!("::convert::to_native({expr})")
29            }
30            FunctionArgument::StructRef(_) => {
31                format!("::convert::to_native({expr})")
32            }
33            FunctionArgument::ClassRef(x) => {
34                format!("{}::get({})", x.friend_class(), expr)
35            }
36            FunctionArgument::Interface(x) => match x.mode {
37                InterfaceCategory::Synchronous => {
38                    format!("::convert::to_native({expr})")
39                }
40                InterfaceCategory::Asynchronous => {
41                    format!("::convert::to_native(std::move({expr}))")
42                }
43                InterfaceCategory::Future => {
44                    format!("::convert::to_native(std::move({expr}))")
45                }
46            },
47        }
48    }
49
50    fn shadow_parameter_mapping(&self) -> Option<Box<dyn Fn(String) -> String>> {
51        match self {
52            FunctionArgument::Basic(_) => None,
53            FunctionArgument::String(_) => None,
54            FunctionArgument::Collection(x) => {
55                let friend_class = x.collection_class.friend_class();
56                Some(Box::new(move |e| format!("{friend_class}::get({e})")))
57            }
58            FunctionArgument::Struct(_) => None,
59            FunctionArgument::StructRef(_) => Some(Box::new(|e| format!("&{e}"))),
60            FunctionArgument::ClassRef(_) => None,
61            FunctionArgument::Interface(_) => None,
62        }
63    }
64}