summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-26 07:11:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-26 07:11:28 +0000
commit69e1896293c1796e44d532f7f335d27464b3be99 (patch)
tree0635ecc387e763c190b8128bb034f973d3c15ce7
parentde52c007b039ddb0dcfa0028b06a174c0ac30f0e (diff)
parentc8192fe65ee2cd04a5f29e1a25450315a5b76c39 (diff)
downloaduniffi_meta-busytown-mac-infra-release.tar.gz
Snap for 11878398 from c8192fe65ee2cd04a5f29e1a25450315a5b76c39 to busytown-mac-infra-releasebusytown-mac-infra-release
Change-Id: I3d33113f3d3d714b88d89d997a77af6abe4df43a
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp59
-rw-r--r--Cargo.lock76
-rw-r--r--Cargo.toml4
-rw-r--r--METADATA8
-rw-r--r--README.md6
-rw-r--r--cargo_embargo.json3
-rw-r--r--src/ffi_names.rs7
-rw-r--r--src/lib.rs9
-rw-r--r--src/metadata.rs4
-rw-r--r--src/reader.rs57
11 files changed, 131 insertions, 104 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 1c28374..c684c40 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "d5332be35ef497255f7ce49debfd917f6a1009c7"
+ "sha1": "0ecafdc06799205caf1432b93787a9c1f810a168"
},
"path_in_vcs": "uniffi_meta"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..eb389d9
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,59 @@
+// This file is generated by cargo_embargo.
+// Do not modify this file after the first "rust_*" or "genrule" module
+// because the changes will be overridden on upgrade.
+// Content before the first "rust_*" or "genrule" module is preserved.
+
+package {
+ default_applicable_licenses: ["external_rust_crates_uniffi_meta"],
+}
+
+// See: http://go/android-license-faq
+license {
+ name: "external_rust_crates_uniffi_meta",
+ visibility: [":__subpackages__"],
+ license_kinds: ["SPDX-license-identifier-MPL-2.0"],
+ license_text: ["LICENSE"],
+}
+
+rust_library {
+ name: "libuniffi_meta",
+ host_supported: true,
+ crate_name: "uniffi_meta",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.27.1",
+ crate_root: "src/lib.rs",
+ edition: "2021",
+ rustlibs: [
+ "libanyhow",
+ "libbytes",
+ "libsiphasher",
+ ],
+ proc_macros: ["libuniffi_checksum_derive"],
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ product_available: true,
+ vendor_available: true,
+}
+
+rust_test {
+ name: "uniffi_meta_test_src_lib",
+ host_supported: true,
+ crate_name: "uniffi_meta",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.27.1",
+ crate_root: "src/lib.rs",
+ test_suites: ["general-tests"],
+ auto_gen_config: true,
+ test_options: {
+ unit_test: true,
+ },
+ edition: "2021",
+ rustlibs: [
+ "libanyhow",
+ "libbytes",
+ "libsiphasher",
+ ],
+ proc_macros: ["libuniffi_checksum_derive"],
+}
diff --git a/Cargo.lock b/Cargo.lock
deleted file mode 100644
index 32c931a..0000000
--- a/Cargo.lock
+++ /dev/null
@@ -1,76 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "anyhow"
-version = "1.0.81"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
-
-[[package]]
-name = "bytes"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
-[[package]]
-name = "syn"
-version = "2.0.53"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-
-[[package]]
-name = "uniffi_checksum_derive"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72775b3afa6adb30e0c92b3107858d2fcb0ff1a417ac242db1f648b0e2dd0ef2"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "uniffi_meta"
-version = "0.26.1"
-dependencies = [
- "anyhow",
- "bytes",
- "siphasher",
- "uniffi_checksum_derive",
-]
diff --git a/Cargo.toml b/Cargo.toml
index 4816c8e..04d8170 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2021"
name = "uniffi_meta"
-version = "0.26.1"
+version = "0.27.1"
description = "uniffi_meta"
homepage = "https://mozilla.github.io/uniffi-rs"
readme = "README.md"
@@ -33,4 +33,4 @@ version = "1.3"
version = "0.3"
[dependencies.uniffi_checksum_derive]
-version = "0.26.1"
+version = "0.27.1"
diff --git a/METADATA b/METADATA
index d2b56a1..efbf491 100644
--- a/METADATA
+++ b/METADATA
@@ -7,14 +7,14 @@ third_party {
}
identifier {
type: "Archive"
- value: "https://static.crates.io/crates/uniffi_meta/uniffi_meta-0.26.1.crate"
+ value: "https://static.crates.io/crates/uniffi_meta/uniffi_meta-0.27.1.crate"
primary_source: true
}
- version: "0.26.1"
+ version: "0.27.1"
license_type: RECIPROCAL
last_upgrade_date {
year: 2024
- month: 3
- day: 21
+ month: 5
+ day: 6
}
}
diff --git a/README.md b/README.md
index bb72360..64ac348 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,12 @@ you can use UniFFI to help you:
You can describe your object model in an [interface definition file](https://mozilla.github.io/uniffi-rs/udl_file_spec.html)
or [by using proc-macros](https://mozilla.github.io/uniffi-rs/proc_macro/index.html).
-UniFFI is currently extensively by Mozilla in Firefox mobile and desktop browsers;
+UniFFI is currently used extensively by Mozilla in Firefox mobile and desktop browsers;
written once in Rust, auto-generated bindings allow that functionality to be called
from both Kotlin (for Android apps) and Swift (for iOS apps).
It also has a growing community of users shipping various cool things to many users.
-UniFII comes with support for **Kotlin**, **Swift**, **Python** and **Ruby** with 3rd party bindings available for **C#** and **Golang**.
+UniFFI comes with support for **Kotlin**, **Swift**, **Python** and **Ruby** with 3rd party bindings available for **C#** and **Golang**.
Additional foreign language bindings can be developed externally and we welcome contributions to list them here.
See [Third-party foreign language bindings](#third-party-foreign-language-bindings).
@@ -62,6 +62,8 @@ There are a few third-party resources that make it easier to work with UniFFI:
* [Plugin support for `.udl` files](https://github.com/Lonami/uniffi-dl) for the IDEA platform ([*uniffi-dl* in the JetBrains marketplace](https://plugins.jetbrains.com/plugin/20527-uniffi-dl)). It provides syntax highlighting, code folding, code completion, reference resolution and navigation (among others features) for the [UniFFI Definition Language (UDL)](https://mozilla.github.io/uniffi-rs/).
* [cargo swift](https://github.com/antoniusnaumann/cargo-swift), a cargo plugin to build a Swift Package from Rust code. It provides an init command for setting up a UniFFI crate and a package command for building a Swift package from Rust code - without the need for additional configuration or build scripts.
+* [Cargo NDK Gradle Plugin](https://github.com/willir/cargo-ndk-android-gradle) allows you to build Rust code using [`cargo-ndk`](https://github.com/bbqsrc/cargo-ndk), which generally makes Android library builds less painful.
+* [`uniffi-starter`](https://github.com/ianthetechie/uniffi-starter) is a minimal project demonstrates a wide range of UniFFI in a complete project in a compact manner. It includes a full Android library build process, an XCFramework generation script, and example Swift package structure.
(Please open a PR if you think other resources should be listed!)
diff --git a/cargo_embargo.json b/cargo_embargo.json
index cb908d7..d40889a 100644
--- a/cargo_embargo.json
+++ b/cargo_embargo.json
@@ -1,3 +1,4 @@
{
- "run_cargo": false
+ "run_cargo": false,
+ "tests": true
}
diff --git a/src/ffi_names.rs b/src/ffi_names.rs
index a58977b..5c931a0 100644
--- a/src/ffi_names.rs
+++ b/src/ffi_names.rs
@@ -46,9 +46,12 @@ pub fn free_fn_symbol_name(namespace: &str, object_name: &str) -> String {
}
/// FFI symbol name for the `init_callback` function for a callback interface
-pub fn init_callback_fn_symbol_name(namespace: &str, callback_interface_name: &str) -> String {
+pub fn init_callback_vtable_fn_symbol_name(
+ namespace: &str,
+ callback_interface_name: &str,
+) -> String {
let callback_interface_name = callback_interface_name.to_ascii_lowercase();
- format!("uniffi_{namespace}_fn_init_callback_{callback_interface_name}")
+ format!("uniffi_{namespace}_fn_init_callback_vtable_{callback_interface_name}")
}
/// FFI checksum symbol name for a top-level function
diff --git a/src/lib.rs b/src/lib.rs
index eb4cdca..90f7b2d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,7 +23,7 @@ mod metadata;
// `docs/uniffi-versioning.md` for details.
//
// Once we get to 1.0, then we'll need to update the scheme to something like 100 + major_version
-pub const UNIFFI_CONTRACT_VERSION: u32 = 25;
+pub const UNIFFI_CONTRACT_VERSION: u32 = 26;
/// Similar to std::hash::Hash.
///
@@ -161,6 +161,7 @@ pub struct ConstructorMetadata {
pub module_path: String,
pub self_name: String,
pub name: String,
+ pub is_async: bool,
pub inputs: Vec<FnParamMetadata>,
pub throws: Option<Type>,
pub checksum: Option<u16>,
@@ -270,13 +271,17 @@ pub enum LiteralMetadata {
Enum(String, Type),
EmptySequence,
EmptyMap,
- Null,
+ None,
+ Some { inner: Box<LiteralMetadata> },
}
impl LiteralMetadata {
pub fn new_uint(v: u64) -> Self {
LiteralMetadata::UInt(v, Radix::Decimal, Type::UInt64)
}
+ pub fn new_int(v: i64) -> Self {
+ LiteralMetadata::Int(v, Radix::Decimal, Type::Int64)
+ }
}
// Represent the radix of integer literal values.
diff --git a/src/metadata.rs b/src/metadata.rs
index 66c2c63..9cfb77a 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -59,7 +59,9 @@ pub mod codes {
pub const LIT_INT: u8 = 1;
pub const LIT_FLOAT: u8 = 2;
pub const LIT_BOOL: u8 = 3;
- pub const LIT_NULL: u8 = 4;
+ pub const LIT_NONE: u8 = 4;
+ pub const LIT_SOME: u8 = 5;
+ pub const LIT_EMPTY_SEQ: u8 = 6;
}
// Create a checksum for a MetadataBuffer
diff --git a/src/reader.rs b/src/reader.rs
index 5a09d9d..6fec6cb 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -247,6 +247,7 @@ impl<'a> MetadataReader<'a> {
let module_path = self.read_string()?;
let self_name = self.read_string()?;
let name = self.read_string()?;
+ let is_async = self.read_bool()?;
let inputs = self.read_inputs()?;
let (return_type, throws) = self.read_return_type()?;
let docstring = self.read_optional_long_string()?;
@@ -263,6 +264,7 @@ impl<'a> MetadataReader<'a> {
Ok(ConstructorMetadata {
module_path,
self_name,
+ is_async,
name,
inputs,
throws,
@@ -405,7 +407,7 @@ impl<'a> MetadataReader<'a> {
.map(|_| {
let name = self.read_string()?;
let ty = self.read_type()?;
- let default = self.read_default(&name, &ty)?;
+ let default = self.read_optional_default(&name, &ty)?;
Ok(FieldMetadata {
name,
ty,
@@ -422,7 +424,7 @@ impl<'a> MetadataReader<'a> {
.map(|_| {
Ok(VariantMetadata {
name: self.read_string()?,
- discr: self.read_default("<variant-value>", &Type::UInt64)?,
+ discr: self.read_optional_default("<variant-value>", &Type::UInt64)?,
fields: self.read_fields()?,
docstring: self.read_optional_long_string()?,
})
@@ -448,13 +450,16 @@ impl<'a> MetadataReader<'a> {
let len = self.read_u8()?;
(0..len)
.map(|_| {
+ let name = self.read_string()?;
+ let ty = self.read_type()?;
+ let default = self.read_optional_default(&name, &ty)?;
Ok(FnParamMetadata {
- name: self.read_string()?,
- ty: self.read_type()?,
+ name,
+ ty,
+ default,
// not emitted by macros
by_ref: false,
optional: false,
- default: None,
})
})
.collect()
@@ -466,14 +471,18 @@ impl<'a> MetadataReader<'a> {
Some(checksum_metadata(metadata_buf))
}
- fn read_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
- let has_default = self.read_bool()?;
- if !has_default {
- return Ok(None);
+ fn read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
+ if self.read_bool()? {
+ Ok(Some(self.read_default(name, ty)?))
+ } else {
+ Ok(None)
}
+ }
+ fn read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata> {
let literal_kind = self.read_u8()?;
- Ok(Some(match literal_kind {
+
+ Ok(match literal_kind {
codes::LIT_STR => {
ensure!(
matches!(ty, Type::String),
@@ -483,12 +492,24 @@ impl<'a> MetadataReader<'a> {
}
codes::LIT_INT => {
let base10_digits = self.read_string()?;
+ // procmacros emit the type for discriminant values based purely on whether the constant
+ // is positive or negative.
+ let ty = if !base10_digits.is_empty()
+ && base10_digits.as_bytes()[0] == b'-'
+ && ty == &Type::UInt64
+ {
+ &Type::Int64
+ } else {
+ ty
+ };
macro_rules! parse_int {
($ty:ident, $variant:ident) => {
LiteralMetadata::$variant(
base10_digits
.parse::<$ty>()
- .with_context(|| format!("parsing default for field {name}"))?
+ .with_context(|| {
+ format!("parsing default for field {name}: {base10_digits}")
+ })?
.into(),
Radix::Decimal,
ty.to_owned(),
@@ -519,8 +540,18 @@ impl<'a> MetadataReader<'a> {
}
},
codes::LIT_BOOL => LiteralMetadata::Boolean(self.read_bool()?),
- codes::LIT_NULL => LiteralMetadata::Null,
+ codes::LIT_NONE => match ty {
+ Type::Optional { .. } => LiteralMetadata::None,
+ _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
+ },
+ codes::LIT_SOME => match ty {
+ Type::Optional { inner_type, .. } => LiteralMetadata::Some {
+ inner: Box::new(self.read_default(name, inner_type)?),
+ },
+ _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
+ },
+ codes::LIT_EMPTY_SEQ => LiteralMetadata::EmptySequence,
_ => bail!("Unexpected literal kind code: {literal_kind:?}"),
- }))
+ })
}
}