use super::*;
pub fn ffi_clone_name(interface_name: &str, context: &Context) -> Result<RustFfiFunctionName> {
Ok(RustFfiFunctionName(uniffi_meta::clone_fn_symbol_name(
&context.crate_name()?,
interface_name,
)))
}
pub fn ffi_free_name(interface_name: &str, context: &Context) -> Result<RustFfiFunctionName> {
Ok(RustFfiFunctionName(uniffi_meta::free_fn_symbol_name(
&context.crate_name()?,
interface_name,
)))
}
pub fn ffi_definitions(
namespace: &initial::Namespace,
context: &Context,
) -> Result<Vec<FfiDefinition>> {
let namespace_name = &namespace.name;
let mut ffi_defs = vec![];
namespace.try_visit(|int: &initial::Interface| {
ffi_defs.push(FfiDefinition::RustFunction(FfiFunction {
name: ffi_clone_name(&int.name, context)?,
async_data: None,
arguments: vec![FfiArgument {
name: "ptr".to_string(),
ty: FfiType::Handle(if int.imp.has_struct() {
HandleKind::StructInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
} else {
HandleKind::TraitInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
}),
}],
return_type: FfiReturnType {
ty: Some(FfiType::Handle(if int.imp.has_struct() {
HandleKind::StructInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
} else {
HandleKind::TraitInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
})),
},
has_rust_call_status_arg: true,
kind: FfiFunctionKind::ObjectClone,
}));
ffi_defs.push(FfiDefinition::RustFunction(FfiFunction {
name: ffi_free_name(&int.name, context)?,
async_data: None,
arguments: vec![FfiArgument {
name: "ptr".to_string(),
ty: FfiType::Handle(if int.imp.has_struct() {
HandleKind::StructInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
} else {
HandleKind::TraitInterface {
namespace: namespace_name.clone(),
interface_name: int.name.to_string(),
}
}),
}],
return_type: FfiReturnType { ty: None },
has_rust_call_status_arg: true,
kind: FfiFunctionKind::ObjectFree,
}));
Ok(())
})?;
Ok(ffi_defs)
}
pub fn constructors(
constructors: Vec<initial::Constructor>,
context: &Context,
) -> Result<Vec<Constructor>> {
constructors
.into_iter()
.filter_map(
|cons| match exclude::should_exclude_method(&cons.name, context) {
Err(e) => Some(Err(e)),
Ok(true) => None,
Ok(false) => Some(cons.map_node(context)),
},
)
.collect()
}
pub fn methods_with_kind(
methods: Vec<initial::Method>,
kind: CallableKind,
context: &Context,
) -> Result<Vec<Method>> {
let mut mapped = Vec::with_capacity(methods.len());
for meth in methods {
if exclude::should_exclude_method(&meth.name, context)? {
continue;
}
mapped.push(Method {
callable: callable::method_callable_with_kind(&meth, kind.clone(), context)?,
docstring: meth.docstring,
})
}
Ok(mapped)
}
pub fn methods(methods: Vec<initial::Method>, context: &Context) -> Result<Vec<Method>> {
let self_type = context.self_type()?;
methods_with_kind(methods, CallableKind::Method { self_type }, context)
}
pub fn interface_methods(methods: Vec<initial::Method>, context: &Context) -> Result<Vec<Method>> {
let self_type = context.self_type()?;
let kind = CallableKind::Method { self_type };
methods_with_kind(methods, kind, context)
}
pub fn callback_interface_methods(
methods: Vec<initial::Method>,
context: &Context,
) -> Result<Vec<Method>> {
let self_type = context.self_type()?;
let kind = CallableKind::VTableMethod {
self_type,
for_callback_interface: true,
};
methods_with_kind(methods, kind, context)
}