rusty_bind_parser/cpp/
externs.rs

1//
2// Wildland Project
3//
4// Copyright © 2022 Golem Foundation,
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License version 3 as published by
8// the Free Software Foundation.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18use crate::binding_types::{ExternFunction, RustWrapperType, WrapperType};
19use crate::extern_module_translator::Exceptions;
20
21pub fn create_extern_imports(extern_functions: &[ExternFunction]) -> String {
22    extern_functions
23        .iter()
24        .map(|function| {
25            let args = function
26                .arguments
27                .iter()
28                .map(|arg| match arg {
29                    WrapperType {
30                        wrapper_name,
31                        rust_type: RustWrapperType::Primitive,
32                        reference_parameters: None,
33                        ..
34                    } => wrapper_name.clone(),
35                    WrapperType {
36                        wrapper_name,
37                        rust_type:
38                            RustWrapperType::FieldlessEnum
39                            | RustWrapperType::Exceptions(Exceptions::Primitive(_)),
40                        reference_parameters: None,
41                        ..
42                    } => format!("enum {}", wrapper_name.clone()),
43                    _ => "void*".to_owned(),
44                })
45                .collect::<Vec<String>>()
46                .join(", ");
47            let function_name = &function.name;
48            let return_type = match &function.return_type {
49                Some(WrapperType {
50                    wrapper_name,
51                    rust_type: RustWrapperType::Primitive,
52                    reference_parameters: None,
53                    ..
54                }) => wrapper_name.clone(),
55                Some(WrapperType {
56                    wrapper_name,
57                    rust_type: RustWrapperType::FieldlessEnum,
58                    reference_parameters: None,
59                    ..
60                }) => format!("enum {}", wrapper_name.clone()),
61                Some(WrapperType { .. }) => "void*".to_owned(),
62                _ => "void".to_owned(),
63            };
64            format!("{return_type} {function_name}({args});\n")
65        })
66        .collect::<String>()
67}
68
69#[cfg(test)]
70
71mod tests {
72    use pretty_assertions::assert_eq;
73    use syn::parse_quote;
74
75    use super::*;
76
77    #[test]
78    fn should_create_function_returning_void() {
79        let function_without_return_type = ExternFunction {
80            arguments: vec![],
81            return_type: None,
82            name: "foo".to_owned(),
83            tokens: parse_quote!(
84                fn foo();
85            ),
86        };
87        let result = create_extern_imports(&[function_without_return_type]);
88        let expected = "void foo();\n";
89        assert_eq!(result, expected);
90    }
91
92    #[test]
93    fn should_create_function_returning_primitive() {
94        let function_returning_primitive = ExternFunction {
95            arguments: vec![],
96            return_type: Some(WrapperType {
97                original_type_name: parse_quote!(u32),
98                wrapper_name: "u32".to_string(),
99                rust_type: RustWrapperType::Primitive,
100                reference_parameters: None,
101                impl_traits: vec![],
102            }),
103            name: "foo".to_owned(),
104            tokens: parse_quote!(
105                fn foo();
106            ),
107        };
108        let result = create_extern_imports(&[function_returning_primitive]);
109        let expected = "u32 foo();\n";
110        assert_eq!(result, expected);
111    }
112
113    #[test]
114    fn should_create_function_returning_fieldless_enum() {
115        let function_returning_fieldless_enum = ExternFunction {
116            arguments: vec![],
117            return_type: Some(WrapperType {
118                original_type_name: parse_quote!(SomeEnum),
119                wrapper_name: "SomeEnum".to_string(),
120                rust_type: RustWrapperType::FieldlessEnum,
121                reference_parameters: None,
122                impl_traits: vec![],
123            }),
124            name: "foo".to_owned(),
125            tokens: parse_quote!(
126                fn foo() -> SomeEnum;
127            ),
128        };
129        let result = create_extern_imports(&[function_returning_fieldless_enum]);
130        let expected = "enum SomeEnum foo();\n";
131        assert_eq!(result, expected);
132    }
133
134    #[test]
135    fn should_create_function_returning_data_enum() {
136        let function_returning_data_enum = ExternFunction {
137            arguments: vec![],
138            return_type: Some(WrapperType {
139                original_type_name: parse_quote!(SomeDataEnum),
140                wrapper_name: "SomeDataEnum".to_string(),
141                rust_type: RustWrapperType::DataEnum,
142                reference_parameters: None,
143                impl_traits: vec![],
144            }),
145            name: "foo".to_owned(),
146            tokens: parse_quote!(
147                fn foo() -> SomeDataEnum;
148            ),
149        };
150        let result = create_extern_imports(&[function_returning_data_enum]);
151        let expected = "void* foo();\n";
152        assert_eq!(result, expected);
153    }
154
155    #[test]
156    fn should_create_function_returning_custom_type() {
157        let function_returning_custom_type = ExternFunction {
158            arguments: vec![],
159            return_type: Some(WrapperType {
160                original_type_name: parse_quote!(SomeCustomType),
161                wrapper_name: "SomeCustomType".to_string(),
162                rust_type: RustWrapperType::Custom,
163                reference_parameters: None,
164                impl_traits: vec![],
165            }),
166            name: "foo".to_owned(),
167            tokens: parse_quote!(
168                fn foo() -> SomeCustomType;
169            ),
170        };
171        let result = create_extern_imports(&[function_returning_custom_type]);
172        let expected = "void* foo();\n";
173        assert_eq!(result, expected);
174    }
175}