use crate::binding_types::{ExternFunction, RustWrapperType, WrapperType};
use crate::extern_module_translator::Exceptions;
pub fn create_extern_imports(extern_functions: &[ExternFunction]) -> String {
extern_functions
.iter()
.map(|function| {
let args = function
.arguments
.iter()
.map(|arg| match arg {
WrapperType {
wrapper_name,
rust_type: RustWrapperType::Primitive,
reference_parameters: None,
..
} => wrapper_name.clone(),
WrapperType {
wrapper_name,
rust_type:
RustWrapperType::FieldlessEnum
| RustWrapperType::Exceptions(Exceptions::Primitive(_)),
reference_parameters: None,
..
} => format!("enum {}", wrapper_name.clone()),
_ => "void*".to_owned(),
})
.collect::<Vec<String>>()
.join(", ");
let function_name = &function.name;
let return_type = match &function.return_type {
Some(WrapperType {
wrapper_name,
rust_type: RustWrapperType::Primitive,
reference_parameters: None,
..
}) => wrapper_name.clone(),
Some(WrapperType {
wrapper_name,
rust_type: RustWrapperType::FieldlessEnum,
reference_parameters: None,
..
}) => format!("enum {}", wrapper_name.clone()),
Some(WrapperType { .. }) => "void*".to_owned(),
_ => "void".to_owned(),
};
format!("{return_type} {function_name}({args});\n")
})
.collect::<String>()
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use syn::parse_quote;
use super::*;
#[test]
fn should_create_function_returning_void() {
let function_without_return_type = ExternFunction {
arguments: vec![],
return_type: None,
name: "foo".to_owned(),
tokens: parse_quote!(
fn foo();
),
};
let result = create_extern_imports(&[function_without_return_type]);
let expected = "void foo();\n";
assert_eq!(result, expected);
}
#[test]
fn should_create_function_returning_primitive() {
let function_returning_primitive = ExternFunction {
arguments: vec![],
return_type: Some(WrapperType {
original_type_name: parse_quote!(u32),
wrapper_name: "u32".to_string(),
rust_type: RustWrapperType::Primitive,
reference_parameters: None,
}),
name: "foo".to_owned(),
tokens: parse_quote!(
fn foo();
),
};
let result = create_extern_imports(&[function_returning_primitive]);
let expected = "u32 foo();\n";
assert_eq!(result, expected);
}
#[test]
fn should_create_function_returning_fieldless_enum() {
let function_returning_fieldless_enum = ExternFunction {
arguments: vec![],
return_type: Some(WrapperType {
original_type_name: parse_quote!(SomeEnum),
wrapper_name: "SomeEnum".to_string(),
rust_type: RustWrapperType::FieldlessEnum,
reference_parameters: None,
}),
name: "foo".to_owned(),
tokens: parse_quote!(
fn foo() -> SomeEnum;
),
};
let result = create_extern_imports(&[function_returning_fieldless_enum]);
let expected = "enum SomeEnum foo();\n";
assert_eq!(result, expected);
}
#[test]
fn should_create_function_returning_data_enum() {
let function_returning_data_enum = ExternFunction {
arguments: vec![],
return_type: Some(WrapperType {
original_type_name: parse_quote!(SomeDataEnum),
wrapper_name: "SomeDataEnum".to_string(),
rust_type: RustWrapperType::DataEnum,
reference_parameters: None,
}),
name: "foo".to_owned(),
tokens: parse_quote!(
fn foo() -> SomeDataEnum;
),
};
let result = create_extern_imports(&[function_returning_data_enum]);
let expected = "void* foo();\n";
assert_eq!(result, expected);
}
#[test]
fn should_create_function_returning_custom_type() {
let function_returning_custom_type = ExternFunction {
arguments: vec![],
return_type: Some(WrapperType {
original_type_name: parse_quote!(SomeCustomType),
wrapper_name: "SomeCustomType".to_string(),
rust_type: RustWrapperType::Custom,
reference_parameters: None,
}),
name: "foo".to_owned(),
tokens: parse_quote!(
fn foo() -> SomeCustomType;
),
};
let result = create_extern_imports(&[function_returning_custom_type]);
let expected = "void* foo();\n";
assert_eq!(result, expected);
}
}