1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::interface::{ComponentInterface, Enum, Error, Record, Type};
use anyhow::anyhow;
use uniffi_meta::Metadata;
/// Add Metadata items to the ComponentInterface
///
/// This function exists to support the transition period where the `uniffi::export` macro can only
/// handle some components. This means that crates need to continue using UDL files to define the
/// parts of the components that aren't supported yet.
///
/// To make things work, we generate a `ComponentInterface` from the UDL file, then combine it with
/// the `Metadata` items that the macro creates.
pub fn add_to_ci(
iface: &mut ComponentInterface,
metadata_items: Vec<Metadata>,
) -> anyhow::Result<()> {
for item in metadata_items {
let (item_desc, crate_name) = match &item {
Metadata::Func(meta) => (
format!("function `{}`", meta.name),
meta.module_path.first().unwrap(),
),
Metadata::Method(meta) => (
format!("method `{}.{}`", meta.self_name, meta.name),
meta.module_path.first().unwrap(),
),
Metadata::Record(meta) => (
format!("record `{}`", meta.name),
meta.module_path.first().unwrap(),
),
Metadata::Enum(meta) => (
format!("enum `{}`", meta.name),
meta.module_path.first().unwrap(),
),
Metadata::Object(meta) => (
format!("object `{}`", meta.name),
meta.module_path.first().unwrap(),
),
Metadata::Error(meta) => (
format!("error `{}`", meta.name),
meta.module_path.first().unwrap(),
),
};
let ns = iface.namespace();
if crate_name != ns {
return Err(anyhow!("Found {item_desc} from crate `{crate_name}`.")
.context(format!(
"Main crate is expected to be named `{ns}` based on the UDL namespace."
))
.context("Mixing symbols from multiple crates is not supported yet."));
}
match item {
Metadata::Func(meta) => {
iface.add_fn_meta(meta)?;
}
Metadata::Method(meta) => {
iface.add_method_meta(meta);
}
Metadata::Record(meta) => {
let ty = Type::Record(meta.name.clone());
iface.types.add_known_type(&ty)?;
iface.types.add_type_definition(&meta.name, ty)?;
let record: Record = meta.into();
iface.add_record_definition(record)?;
}
Metadata::Enum(meta) => {
let ty = Type::Enum(meta.name.clone());
iface.types.add_known_type(&ty)?;
iface.types.add_type_definition(&meta.name, ty)?;
let enum_: Enum = meta.into();
iface.add_enum_definition(enum_)?;
}
Metadata::Object(meta) => {
iface.add_object_free_fn(meta);
}
Metadata::Error(meta) => {
let ty = Type::Error(meta.name.clone());
iface.types.add_known_type(&ty)?;
iface.types.add_type_definition(&meta.name, ty)?;
let error: Error = meta.into();
iface.add_error_definition(error)?;
}
}
}
iface.resolve_types()?;
iface.derive_ffi_funcs()?;
iface.check_consistency()?;
Ok(())
}
|