use super::*;
use_prev_node!(initial::EnumShape);
use_prev_node!(initial::ObjectImpl);
use_prev_node!(initial::Radix);
use_prev_node!(initial::TraitKind);
use_prev_node!(initial::Type, types::map_type);
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Root))]
#[map_node(root::map_root)]
pub struct Root {
pub cdylib: Option<String>,
pub namespaces: IndexMap<String, Namespace>,
pub builtin_types: BuiltinTypes,
}
#[derive(Debug, Clone, Node)]
pub struct BuiltinTypes {
pub u8: TypeNode,
pub i8: TypeNode,
pub u16: TypeNode,
pub i16: TypeNode,
pub u32: TypeNode,
pub i32: TypeNode,
pub u64: TypeNode,
pub i64: TypeNode,
pub f32: TypeNode,
pub f64: TypeNode,
pub string: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Namespace))]
#[map_node(namespaces::map_namespace)]
pub struct Namespace {
pub name: String,
pub crate_name: String,
pub config_toml: Option<String>,
pub docstring: Option<String>,
pub functions: Vec<Function>,
pub type_definitions: Vec<TypeDefinition>,
pub ffi_definitions: IndexSet<FfiDefinition>,
pub checksums: Vec<Checksum>,
pub ffi_rustbuffer_alloc: RustFfiFunctionName,
pub ffi_rustbuffer_from_bytes: RustFfiFunctionName,
pub ffi_rustbuffer_free: RustFfiFunctionName,
pub ffi_rustbuffer_reserve: RustFfiFunctionName,
pub ffi_uniffi_contract_version: RustFfiFunctionName,
pub correct_contract_version: String,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Function))]
pub struct Function {
#[map_node(callable::function_callable(&self, context)?)]
pub callable: Callable,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::TypeDefinition))]
pub enum TypeDefinition {
Interface(Interface),
CallbackInterface(CallbackInterface),
Record(Record),
Enum(Enum),
Custom(CustomType),
#[map_node(added)]
Simple(TypeNode),
#[map_node(added)]
Box(BoxedType),
#[map_node(added)]
Optional(OptionalType),
#[map_node(added)]
Sequence(SequenceType),
#[map_node(added)]
Map(MapType),
#[map_node(added)]
Set(SetType),
#[map_node(added)]
External(ExternalType),
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Constructor))]
pub struct Constructor {
#[map_node(callable::constructor_callable(&self, context)?)]
pub callable: Callable,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Method))]
pub struct Method {
#[map_node(callable::method_callable(&self, context)?)]
pub callable: Callable,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct Callable {
pub id: u64,
pub name: String,
pub orig_name: String,
pub async_data: Option<AsyncData>,
pub kind: CallableKind,
pub arguments: Vec<Argument>,
pub return_type: ReturnType,
pub throws_type: ThrowsType,
pub checksum: Option<u16>,
pub ffi_func: RustFfiFunctionName,
}
#[derive(Debug, Clone, Node, MapNode)]
pub enum CallableKind {
Function,
Method { self_type: TypeNode },
Constructor { self_type: TypeNode, primary: bool },
VTableMethod {
self_type: TypeNode,
for_callback_interface: bool,
},
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct ReturnType {
pub ty: Option<TypeNode>,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct ThrowsType {
pub ty: Option<TypeNode>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct AsyncData {
pub ffi_rust_future_poll: RustFfiFunctionName,
pub ffi_rust_future_cancel: RustFfiFunctionName,
pub ffi_rust_future_free: RustFfiFunctionName,
pub ffi_rust_future_complete: RustFfiFunctionName,
pub ffi_foreign_future_complete: FfiFunctionTypeName,
pub ffi_foreign_future_result: FfiStructName,
}
#[derive(Debug, Clone, Node)]
pub struct Argument {
pub name: String,
pub orig_name: String,
pub ty: TypeNode,
pub by_ref: bool,
pub optional: bool,
pub default: Option<DefaultValue>,
}
impl Argument {
pub fn is_borrowed_bytes(&self) -> bool {
self.by_ref && matches!(self.ty.ty, Type::Bytes)
}
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::DefaultValue))]
#[map_node(default::map_default_value)]
pub enum DefaultValue {
Literal(Literal),
Default(TypeNode),
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Literal))]
pub enum Literal {
Boolean(bool),
String(String),
UInt(u64, Radix, TypeNode),
Int(i64, Radix, TypeNode),
Float(String, TypeNode),
Enum(String, TypeNode),
EmptySequence,
EmptyMap,
EmptySet,
None,
Some { inner: Box<DefaultValue> },
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Record))]
#[map_node(update_context(context.update_from_record(&self)?))]
pub struct Record {
#[map_node(records::fields_kind(&self.fields))]
pub fields_kind: FieldsKind,
#[map_node(context.self_type()?)]
pub self_type: TypeNode,
pub orig_name: String,
#[map_node(rename::type_(&context.namespace_name()?, self.name, context)?)]
pub name: String,
#[map_node(from(uniffi_traits))]
pub uniffi_trait_methods: UniffiTraitMethods,
pub fields: Vec<Field>,
#[map_node(objects::constructors(self.constructors, context)?)]
pub constructors: Vec<Constructor>,
#[map_node(objects::methods(self.methods, context)?)]
pub methods: Vec<Method>,
pub docstring: Option<String>,
#[map_node(false)]
pub recursive: bool,
}
#[derive(Debug, Clone, Node, MapNode)]
pub enum FieldsKind {
Unit,
Named,
Unnamed,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Field))]
#[map_node(update_context(context.update_from_field(&self)?))]
pub struct Field {
pub orig_name: String,
#[map_node(rename::field(self.name, context)?)]
pub name: String,
pub ty: TypeNode,
pub default: Option<DefaultValue>,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Enum))]
#[map_node(update_context(context.update_from_enum(&self)?))]
pub struct Enum {
#[map_node(enums::is_flat(&self))]
pub is_flat: bool,
#[map_node(context.self_type()?)]
pub self_type: TypeNode,
#[map_node(enums::discr_type(&self, context)?)]
pub discr_type: TypeNode,
#[map_node(enums::map_variants(&self.discr_type, self.variants, context)?)]
pub variants: Vec<Variant>,
pub orig_name: String,
#[map_node(rename::type_(&context.namespace_name()?, self.name, context)?)]
pub name: String,
#[map_node(from(uniffi_traits))]
pub uniffi_trait_methods: UniffiTraitMethods,
pub shape: EnumShape,
#[map_node(objects::constructors(self.constructors, context)?)]
pub constructors: Vec<Constructor>,
#[map_node(objects::methods(self.methods, context)?)]
pub methods: Vec<Method>,
pub docstring: Option<String>,
#[map_node(false)]
pub recursive: bool,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct Variant {
pub name: String,
pub orig_name: String,
pub discr: Literal,
pub fields_kind: FieldsKind,
pub fields: Vec<Field>,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::Interface))]
#[map_node(update_context(context.update_from_interface(&self)?))]
pub struct Interface {
#[map_node(callback_interfaces::vtable_for_interface(&self, context)?)]
pub vtable: Option<VTable>,
#[map_node(context.self_type()?)]
pub self_type: TypeNode,
#[map_node(objects::ffi_clone_name(&self.name, context)?)]
pub ffi_func_clone: RustFfiFunctionName,
#[map_node(objects::ffi_free_name(&self.name, context)?)]
pub ffi_func_free: RustFfiFunctionName,
pub orig_name: String,
#[map_node(rename::type_(&context.namespace_name()?, self.name, context)?)]
pub name: String,
#[map_node(from(uniffi_traits))]
pub uniffi_trait_methods: UniffiTraitMethods,
pub docstring: Option<String>,
#[map_node(objects::constructors(self.constructors, context)?)]
pub constructors: Vec<Constructor>,
#[map_node(objects::interface_methods(self.methods, context)?)]
pub methods: Vec<Method>,
pub trait_impls: Vec<ObjectTraitImpl>,
pub imp: ObjectImpl,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::CallbackInterface))]
#[map_node(update_context(context.update_from_callback_interface(&self)?))]
pub struct CallbackInterface {
#[map_node(callback_interfaces::vtable(&self.methods, context)?)]
pub vtable: VTable,
#[map_node(context.self_type()?)]
pub self_type: TypeNode,
pub orig_name: String,
#[map_node(rename::type_(&context.namespace_name()?, self.name, context)?)]
pub name: String,
pub docstring: Option<String>,
#[map_node(objects::callback_interface_methods(self.methods, context)?)]
pub methods: Vec<Method>,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct VTable {
pub struct_type: FfiType,
pub interface_name: String,
pub init_fn: RustFfiFunctionName,
pub clone_fn_type: FfiFunctionTypeName,
pub free_fn_type: FfiFunctionTypeName,
pub methods: Vec<VTableMethod>,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct VTableMethod {
pub callable: Callable,
pub ffi_type: FfiType,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::ObjectTraitImpl))]
pub struct ObjectTraitImpl {
pub ty: TypeNode,
pub trait_ty: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
#[map_node(from(initial::CustomType))]
#[map_node(update_context(context.update_from_custom_type(&self)?))]
pub struct CustomType {
#[map_node(context.self_type()?)]
pub self_type: TypeNode,
pub orig_name: String,
#[map_node(rename::type_(&context.namespace_name()?, self.name, context)?)]
pub name: String,
pub builtin: TypeNode,
pub docstring: Option<String>,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct BoxedType {
pub inner: TypeNode,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct OptionalType {
pub inner: TypeNode,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct SequenceType {
pub inner: TypeNode,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct MapType {
pub key: TypeNode,
pub value: TypeNode,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct SetType {
pub inner: TypeNode,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct ExternalType {
pub namespace: String,
pub name: String,
pub self_type: TypeNode,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
#[map_node(from(Type))]
#[map_node(types::map_type_node)]
pub struct TypeNode {
pub canonical_name: String,
pub id: u64,
pub is_used_as_error: bool,
pub ffi_type: FfiType,
pub ty: Type,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub enum FfiDefinition {
RustFunction(FfiFunction),
FunctionType(FfiFunctionType),
Struct(FfiStruct),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct RustFfiFunctionName(pub String);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiStructName(pub String);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiFunctionTypeName(pub String);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiFunction {
pub name: RustFfiFunctionName,
pub async_data: Option<AsyncData>,
pub arguments: Vec<FfiArgument>,
pub return_type: FfiReturnType,
pub has_rust_call_status_arg: bool,
pub kind: FfiFunctionKind,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub enum FfiFunctionKind {
Scaffolding,
ObjectClone,
ObjectFree,
RustFuturePoll,
RustFutureComplete,
RustFutureCancel,
RustFutureFree,
RustBufferFromBytes,
RustBufferFree,
RustBufferAlloc,
RustBufferReserve,
RustVtableInit,
UniffiContractVersion,
Checksum,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiFunctionType {
pub name: FfiFunctionTypeName,
pub arguments: Vec<FfiArgument>,
pub return_type: FfiReturnType,
pub has_rust_call_status_arg: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiReturnType {
pub ty: Option<FfiType>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiStruct {
pub name: FfiStructName,
pub fields: Vec<FfiField>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiField {
pub name: String,
pub ty: FfiType,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub struct FfiArgument {
pub name: String,
pub ty: FfiType,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub enum FfiType {
UInt8,
Int8,
UInt16,
Int16,
UInt32,
Int32,
UInt64,
Int64,
Float32,
Float64,
RustBuffer(Option<String>),
ForeignBytes,
Function(FfiFunctionTypeName),
Struct(FfiStructName),
Handle(HandleKind),
RustCallStatus,
Reference(Box<FfiType>),
MutReference(Box<FfiType>),
VoidPointer,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Node, MapNode)]
pub enum HandleKind {
RustFuture,
ForeignFuture,
ForeignFutureCallbackData,
StructInterface {
namespace: String,
interface_name: String,
},
TraitInterface {
namespace: String,
interface_name: String,
},
}
#[derive(Debug, Clone, Node, MapNode)]
pub struct Checksum {
pub fn_name: RustFfiFunctionName,
pub checksum: u16,
}
#[derive(Default, Debug, Clone, Node, MapNode)]
#[map_node(from(Vec<initial::UniffiTrait>))]
#[map_node(uniffi_traits::map_trait_vec)]
pub struct UniffiTraitMethods {
pub debug_fmt: Option<Method>,
pub display_fmt: Option<Method>,
pub eq_eq: Option<Method>,
pub eq_ne: Option<Method>,
pub hash_hash: Option<Method>,
pub ord_cmp: Option<Method>,
}
impl FfiDefinition {
pub fn name(&self) -> &str {
match self {
Self::RustFunction(func) => &func.name.0,
Self::FunctionType(func_type) => &func_type.name.0,
Self::Struct(st) => &st.name.0,
}
}
}
impl From<FfiFunction> for FfiDefinition {
fn from(func: FfiFunction) -> Self {
Self::RustFunction(func)
}
}
impl From<FfiFunctionType> for FfiDefinition {
fn from(func_type: FfiFunctionType) -> Self {
Self::FunctionType(func_type)
}
}
impl From<FfiStruct> for FfiDefinition {
fn from(st: FfiStruct) -> Self {
Self::Struct(st)
}
}
impl FfiArgument {
pub fn new(name: impl Into<String>, ty: FfiType) -> Self {
Self {
name: name.into(),
ty,
}
}
}
impl FfiField {
pub fn new(name: impl Into<String>, ty: FfiType) -> Self {
Self {
name: name.into(),
ty,
}
}
}
impl Callable {
pub fn is_async(&self) -> bool {
self.async_data.is_some()
}
pub fn is_primary_constructor(&self) -> bool {
matches!(self.kind, CallableKind::Constructor { primary: true, .. })
}
}