summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_meta/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /third_party/rust/uniffi_meta/src
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/uniffi_meta/src')
-rw-r--r--third_party/rust/uniffi_meta/src/ffi_names.rs13
-rw-r--r--third_party/rust/uniffi_meta/src/group.rs9
-rw-r--r--third_party/rust/uniffi_meta/src/lib.rs65
-rw-r--r--third_party/rust/uniffi_meta/src/metadata.rs13
-rw-r--r--third_party/rust/uniffi_meta/src/reader.rs148
-rw-r--r--third_party/rust/uniffi_meta/src/types.rs22
6 files changed, 190 insertions, 80 deletions
diff --git a/third_party/rust/uniffi_meta/src/ffi_names.rs b/third_party/rust/uniffi_meta/src/ffi_names.rs
index 44a5bc3e63..5c931a09e3 100644
--- a/third_party/rust/uniffi_meta/src/ffi_names.rs
+++ b/third_party/rust/uniffi_meta/src/ffi_names.rs
@@ -33,6 +33,12 @@ pub fn method_symbol_name(namespace: &str, object_name: &str, name: &str) -> Str
format!("uniffi_{namespace}_fn_method_{object_name}_{name}")
}
+/// FFI symbol name for the `clone` function for an object.
+pub fn clone_fn_symbol_name(namespace: &str, object_name: &str) -> String {
+ let object_name = object_name.to_ascii_lowercase();
+ format!("uniffi_{namespace}_fn_clone_{object_name}")
+}
+
/// FFI symbol name for the `free` function for an object.
pub fn free_fn_symbol_name(namespace: &str, object_name: &str) -> String {
let object_name = object_name.to_ascii_lowercase();
@@ -40,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/third_party/rust/uniffi_meta/src/group.rs b/third_party/rust/uniffi_meta/src/group.rs
index f0be2e5a98..a41776bf8a 100644
--- a/third_party/rust/uniffi_meta/src/group.rs
+++ b/third_party/rust/uniffi_meta/src/group.rs
@@ -18,6 +18,7 @@ pub fn create_metadata_groups(items: &[Metadata]) -> MetadataGroupMap {
Metadata::Namespace(namespace) => {
let group = MetadataGroup {
namespace: namespace.clone(),
+ namespace_docstring: None,
items: BTreeSet::new(),
};
Some((namespace.crate_name.clone(), group))
@@ -29,6 +30,7 @@ pub fn create_metadata_groups(items: &[Metadata]) -> MetadataGroupMap {
};
let group = MetadataGroup {
namespace,
+ namespace_docstring: None,
items: BTreeSet::new(),
};
Some((udl.module_path.clone(), group))
@@ -63,6 +65,7 @@ pub fn group_metadata(group_map: &mut MetadataGroupMap, items: Vec<Metadata>) ->
#[derive(Debug)]
pub struct MetadataGroup {
pub namespace: NamespaceMetadata,
+ pub namespace_docstring: Option<String>,
pub items: BTreeSet<Metadata>,
}
@@ -127,12 +130,6 @@ impl<'a> ExternalTypeConverter<'a> {
..meta
}),
Metadata::Enum(meta) => Metadata::Enum(self.convert_enum(meta)),
- Metadata::Error(meta) => Metadata::Error(match meta {
- ErrorMetadata::Enum { enum_, is_flat } => ErrorMetadata::Enum {
- enum_: self.convert_enum(enum_),
- is_flat,
- },
- }),
_ => item,
}
}
diff --git a/third_party/rust/uniffi_meta/src/lib.rs b/third_party/rust/uniffi_meta/src/lib.rs
index e486d84d89..90f7b2d3cd 100644
--- a/third_party/rust/uniffi_meta/src/lib.rs
+++ b/third_party/rust/uniffi_meta/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 = 24;
+pub const UNIFFI_CONTRACT_VERSION: u32 = 26;
/// Similar to std::hash::Hash.
///
@@ -143,6 +143,7 @@ pub struct FnMetadata {
pub return_type: Option<Type>,
pub throws: Option<Type>,
pub checksum: Option<u16>,
+ pub docstring: Option<String>,
}
impl FnMetadata {
@@ -160,9 +161,11 @@ 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>,
+ pub docstring: Option<String>,
}
impl ConstructorMetadata {
@@ -190,6 +193,7 @@ pub struct MethodMetadata {
pub throws: Option<Type>,
pub takes_self_by_arc: bool, // unused except by rust udl bindgen.
pub checksum: Option<u16>,
+ pub docstring: Option<String>,
}
impl MethodMetadata {
@@ -216,6 +220,7 @@ pub struct TraitMethodMetadata {
pub throws: Option<Type>,
pub takes_self_by_arc: bool, // unused except by rust udl bindgen.
pub checksum: Option<u16>,
+ pub docstring: Option<String>,
}
impl TraitMethodMetadata {
@@ -266,7 +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.
@@ -283,6 +298,7 @@ pub struct RecordMetadata {
pub module_path: String,
pub name: String,
pub fields: Vec<FieldMetadata>,
+ pub docstring: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -290,19 +306,26 @@ pub struct FieldMetadata {
pub name: String,
pub ty: Type,
pub default: Option<LiteralMetadata>,
+ pub docstring: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct EnumMetadata {
pub module_path: String,
pub name: String,
+ pub forced_flatness: Option<bool>,
pub variants: Vec<VariantMetadata>,
+ pub discr_type: Option<Type>,
+ pub non_exhaustive: bool,
+ pub docstring: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct VariantMetadata {
pub name: String,
+ pub discr: Option<LiteralMetadata>,
pub fields: Vec<FieldMetadata>,
+ pub docstring: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -310,15 +333,25 @@ pub struct ObjectMetadata {
pub module_path: String,
pub name: String,
pub imp: types::ObjectImpl,
+ pub docstring: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct CallbackInterfaceMetadata {
pub module_path: String,
pub name: String,
+ pub docstring: Option<String>,
}
impl ObjectMetadata {
+ /// FFI symbol name for the `clone` function for this object.
+ ///
+ /// This function is used to increment the reference count before lowering an object to pass
+ /// back to Rust.
+ pub fn clone_ffi_symbol_name(&self) -> String {
+ clone_fn_symbol_name(&self.module_path, &self.name)
+ }
+
/// FFI symbol name for the `free` function for this object.
///
/// This function is used to free the memory used by this object.
@@ -368,6 +401,7 @@ impl UniffiTraitMetadata {
}
#[repr(u8)]
+#[derive(Eq, PartialEq, Hash)]
pub enum UniffiTraitDiscriminants {
Debug,
Display,
@@ -388,25 +422,6 @@ impl UniffiTraitDiscriminants {
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub enum ErrorMetadata {
- Enum { enum_: EnumMetadata, is_flat: bool },
-}
-
-impl ErrorMetadata {
- pub fn name(&self) -> &String {
- match self {
- Self::Enum { enum_, .. } => &enum_.name,
- }
- }
-
- pub fn module_path(&self) -> &String {
- match self {
- Self::Enum { enum_, .. } => &enum_.module_path,
- }
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct CustomTypeMetadata {
pub module_path: String,
pub name: String,
@@ -433,7 +448,6 @@ pub enum Metadata {
CallbackInterface(CallbackInterfaceMetadata),
Record(RecordMetadata),
Enum(EnumMetadata),
- Error(ErrorMetadata),
Constructor(ConstructorMetadata),
Method(MethodMetadata),
TraitMethod(TraitMethodMetadata),
@@ -458,7 +472,6 @@ impl Metadata {
Metadata::Object(meta) => &meta.module_path,
Metadata::CallbackInterface(meta) => &meta.module_path,
Metadata::TraitMethod(meta) => &meta.module_path,
- Metadata::Error(meta) => meta.module_path(),
Metadata::CustomType(meta) => &meta.module_path,
Metadata::UniffiTrait(meta) => meta.module_path(),
}
@@ -507,12 +520,6 @@ impl From<EnumMetadata> for Metadata {
}
}
-impl From<ErrorMetadata> for Metadata {
- fn from(e: ErrorMetadata) -> Self {
- Self::Error(e)
- }
-}
-
impl From<ObjectMetadata> for Metadata {
fn from(v: ObjectMetadata) -> Self {
Self::Object(v)
diff --git a/third_party/rust/uniffi_meta/src/metadata.rs b/third_party/rust/uniffi_meta/src/metadata.rs
index 6e490a4866..9cfb77a244 100644
--- a/third_party/rust/uniffi_meta/src/metadata.rs
+++ b/third_party/rust/uniffi_meta/src/metadata.rs
@@ -7,7 +7,7 @@
// `uniffi_core`.
// This is the easy way out of that issue and is a temporary hacky solution.
-/// Metadata constants, make sure to keep this in sync with copy in `uniffi_meta::reader`
+/// Metadata constants, make sure to keep this in sync with copy in `uniffi_core::metadata`
pub mod codes {
// Top-level metadata item codes
pub const FUNC: u8 = 0;
@@ -15,13 +15,14 @@ pub mod codes {
pub const RECORD: u8 = 2;
pub const ENUM: u8 = 3;
pub const INTERFACE: u8 = 4;
- pub const ERROR: u8 = 5;
pub const NAMESPACE: u8 = 6;
pub const CONSTRUCTOR: u8 = 7;
pub const UDL_FILE: u8 = 8;
pub const CALLBACK_INTERFACE: u8 = 9;
pub const TRAIT_METHOD: u8 = 10;
pub const UNIFFI_TRAIT: u8 = 11;
+ pub const TRAIT_INTERFACE: u8 = 12;
+ pub const CALLBACK_TRAIT_INTERFACE: u8 = 13;
//pub const UNKNOWN: u8 = 255;
// Type codes
@@ -49,8 +50,8 @@ pub mod codes {
pub const TYPE_CALLBACK_INTERFACE: u8 = 21;
pub const TYPE_CUSTOM: u8 = 22;
pub const TYPE_RESULT: u8 = 23;
- //pub const TYPE_FUTURE: u8 = 24;
- pub const TYPE_FOREIGN_EXECUTOR: u8 = 25;
+ pub const TYPE_TRAIT_INTERFACE: u8 = 24;
+ pub const TYPE_CALLBACK_TRAIT_INTERFACE: u8 = 25;
pub const TYPE_UNIT: u8 = 255;
// Literal codes
@@ -58,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/third_party/rust/uniffi_meta/src/reader.rs b/third_party/rust/uniffi_meta/src/reader.rs
index bf6525f2b5..6fec6cb3a3 100644
--- a/third_party/rust/uniffi_meta/src/reader.rs
+++ b/third_party/rust/uniffi_meta/src/reader.rs
@@ -52,9 +52,10 @@ impl<'a> MetadataReader<'a> {
codes::CONSTRUCTOR => self.read_constructor()?.into(),
codes::METHOD => self.read_method()?.into(),
codes::RECORD => self.read_record()?.into(),
- codes::ENUM => self.read_enum(false)?.into(),
- codes::ERROR => self.read_error()?.into(),
- codes::INTERFACE => self.read_object()?.into(),
+ codes::ENUM => self.read_enum()?.into(),
+ codes::INTERFACE => self.read_object(ObjectImpl::Struct)?.into(),
+ codes::TRAIT_INTERFACE => self.read_object(ObjectImpl::Trait)?.into(),
+ codes::CALLBACK_TRAIT_INTERFACE => self.read_object(ObjectImpl::CallbackTrait)?.into(),
codes::CALLBACK_INTERFACE => self.read_callback_interface()?.into(),
codes::TRAIT_METHOD => self.read_trait_method()?.into(),
codes::UNIFFI_TRAIT => self.read_uniffi_trait()?.into(),
@@ -80,6 +81,17 @@ impl<'a> MetadataReader<'a> {
}
}
+ fn read_u16(&mut self) -> Result<u16> {
+ if self.buf.len() >= 2 {
+ // read the value as little-endian
+ let value = u16::from_le_bytes([self.buf[0], self.buf[1]]);
+ self.buf = &self.buf[2..];
+ Ok(value)
+ } else {
+ bail!("Not enough data left in buffer to read a u16 value");
+ }
+ }
+
fn read_u32(&mut self) -> Result<u32> {
if self.buf.len() >= 4 {
// read the value as little-endian
@@ -105,6 +117,17 @@ impl<'a> MetadataReader<'a> {
String::from_utf8(slice.into()).context("Invalid string data")
}
+ fn read_long_string(&mut self) -> Result<String> {
+ let size = self.read_u16()? as usize;
+ let slice;
+ (slice, self.buf) = self.buf.split_at(size);
+ String::from_utf8(slice.into()).context("Invalid string data")
+ }
+
+ fn read_optional_long_string(&mut self) -> Result<Option<String>> {
+ Ok(Some(self.read_long_string()?).filter(|str| !str.is_empty()))
+ }
+
fn read_type(&mut self) -> Result<Type> {
let value = self.read_u8()?;
Ok(match value {
@@ -122,7 +145,6 @@ impl<'a> MetadataReader<'a> {
codes::TYPE_STRING => Type::String,
codes::TYPE_DURATION => Type::Duration,
codes::TYPE_SYSTEM_TIME => Type::Timestamp,
- codes::TYPE_FOREIGN_EXECUTOR => Type::ForeignExecutor,
codes::TYPE_RECORD => Type::Record {
module_path: self.read_string()?,
name: self.read_string()?,
@@ -134,7 +156,17 @@ impl<'a> MetadataReader<'a> {
codes::TYPE_INTERFACE => Type::Object {
module_path: self.read_string()?,
name: self.read_string()?,
- imp: ObjectImpl::from_is_trait(self.read_bool()?),
+ imp: ObjectImpl::Struct,
+ },
+ codes::TYPE_TRAIT_INTERFACE => Type::Object {
+ module_path: self.read_string()?,
+ name: self.read_string()?,
+ imp: ObjectImpl::Trait,
+ },
+ codes::TYPE_CALLBACK_TRAIT_INTERFACE => Type::Object {
+ module_path: self.read_string()?,
+ name: self.read_string()?,
+ imp: ObjectImpl::CallbackTrait,
},
codes::TYPE_CALLBACK_INTERFACE => Type::CallbackInterface {
module_path: self.read_string()?,
@@ -198,6 +230,7 @@ impl<'a> MetadataReader<'a> {
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()?;
Ok(FnMetadata {
module_path,
name,
@@ -205,6 +238,7 @@ impl<'a> MetadataReader<'a> {
inputs,
return_type,
throws,
+ docstring,
checksum: self.calc_checksum(),
})
}
@@ -213,8 +247,10 @@ 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()?;
return_type
.filter(|t| {
@@ -228,10 +264,12 @@ impl<'a> MetadataReader<'a> {
Ok(ConstructorMetadata {
module_path,
self_name,
+ is_async,
name,
inputs,
throws,
checksum: self.calc_checksum(),
+ docstring,
})
}
@@ -242,6 +280,7 @@ impl<'a> MetadataReader<'a> {
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()?;
Ok(MethodMetadata {
module_path,
self_name,
@@ -252,6 +291,7 @@ impl<'a> MetadataReader<'a> {
throws,
takes_self_by_arc: false, // not emitted by macros
checksum: self.calc_checksum(),
+ docstring,
})
}
@@ -260,13 +300,25 @@ impl<'a> MetadataReader<'a> {
module_path: self.read_string()?,
name: self.read_string()?,
fields: self.read_fields()?,
+ docstring: self.read_optional_long_string()?,
})
}
- fn read_enum(&mut self, is_flat_error: bool) -> Result<EnumMetadata> {
+ fn read_enum(&mut self) -> Result<EnumMetadata> {
let module_path = self.read_string()?;
let name = self.read_string()?;
- let variants = if is_flat_error {
+ let forced_flatness = match self.read_u8()? {
+ 0 => None,
+ 1 => Some(false),
+ 2 => Some(true),
+ _ => unreachable!("invalid flatness"),
+ };
+ let discr_type = if self.read_bool()? {
+ Some(self.read_type()?)
+ } else {
+ None
+ };
+ let variants = if forced_flatness == Some(true) {
self.read_flat_variants()?
} else {
self.read_variants()?
@@ -275,21 +327,20 @@ impl<'a> MetadataReader<'a> {
Ok(EnumMetadata {
module_path,
name,
+ forced_flatness,
+ discr_type,
variants,
+ non_exhaustive: self.read_bool()?,
+ docstring: self.read_optional_long_string()?,
})
}
- fn read_error(&mut self) -> Result<ErrorMetadata> {
- let is_flat = self.read_bool()?;
- let enum_ = self.read_enum(is_flat)?;
- Ok(ErrorMetadata::Enum { enum_, is_flat })
- }
-
- fn read_object(&mut self) -> Result<ObjectMetadata> {
+ fn read_object(&mut self, imp: ObjectImpl) -> Result<ObjectMetadata> {
Ok(ObjectMetadata {
module_path: self.read_string()?,
name: self.read_string()?,
- imp: ObjectImpl::from_is_trait(self.read_bool()?),
+ imp,
+ docstring: self.read_optional_long_string()?,
})
}
@@ -322,6 +373,7 @@ impl<'a> MetadataReader<'a> {
Ok(CallbackInterfaceMetadata {
module_path: self.read_string()?,
name: self.read_string()?,
+ docstring: self.read_optional_long_string()?,
})
}
@@ -333,6 +385,7 @@ impl<'a> MetadataReader<'a> {
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()?;
Ok(TraitMethodMetadata {
module_path,
trait_name,
@@ -344,6 +397,7 @@ impl<'a> MetadataReader<'a> {
throws,
takes_self_by_arc: false, // not emitted by macros
checksum: self.calc_checksum(),
+ docstring,
})
}
@@ -353,8 +407,13 @@ impl<'a> MetadataReader<'a> {
.map(|_| {
let name = self.read_string()?;
let ty = self.read_type()?;
- let default = self.read_default(&name, &ty)?;
- Ok(FieldMetadata { name, ty, default })
+ let default = self.read_optional_default(&name, &ty)?;
+ Ok(FieldMetadata {
+ name,
+ ty,
+ default,
+ docstring: self.read_optional_long_string()?,
+ })
})
.collect()
}
@@ -365,7 +424,9 @@ impl<'a> MetadataReader<'a> {
.map(|_| {
Ok(VariantMetadata {
name: self.read_string()?,
+ discr: self.read_optional_default("<variant-value>", &Type::UInt64)?,
fields: self.read_fields()?,
+ docstring: self.read_optional_long_string()?,
})
})
.collect()
@@ -377,7 +438,9 @@ impl<'a> MetadataReader<'a> {
.map(|_| {
Ok(VariantMetadata {
name: self.read_string()?,
+ discr: None,
fields: vec![],
+ docstring: self.read_optional_long_string()?,
})
})
.collect()
@@ -387,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()
@@ -405,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),
@@ -422,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(),
@@ -458,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:?}"),
- }))
+ })
}
}
diff --git a/third_party/rust/uniffi_meta/src/types.rs b/third_party/rust/uniffi_meta/src/types.rs
index 24f8a6f2a8..51bf156b50 100644
--- a/third_party/rust/uniffi_meta/src/types.rs
+++ b/third_party/rust/uniffi_meta/src/types.rs
@@ -21,8 +21,12 @@ use crate::Checksum;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Checksum, Ord, PartialOrd)]
pub enum ObjectImpl {
+ // A single Rust type
Struct,
+ // A trait that's can be implemented by Rust types
Trait,
+ // A trait + a callback interface -- can be implemented by both Rust and foreign types.
+ CallbackTrait,
}
impl ObjectImpl {
@@ -31,27 +35,26 @@ impl ObjectImpl {
/// Includes `r#`, traits get a leading `dyn`. If we ever supported associated types, then
/// this would also include them.
pub fn rust_name_for(&self, name: &str) -> String {
- if self == &ObjectImpl::Trait {
+ if self.is_trait_interface() {
format!("dyn r#{name}")
} else {
format!("r#{name}")
}
}
- // uniffi_meta and procmacro support tend to carry around `is_trait` bools. This makes that
- // mildly less painful
- pub fn from_is_trait(is_trait: bool) -> Self {
- if is_trait {
- ObjectImpl::Trait
- } else {
- ObjectImpl::Struct
- }
+ pub fn is_trait_interface(&self) -> bool {
+ matches!(self, Self::Trait | Self::CallbackTrait)
+ }
+
+ pub fn has_callback_interface(&self) -> bool {
+ matches!(self, Self::CallbackTrait)
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Checksum, Ord, PartialOrd)]
pub enum ExternalKind {
Interface,
+ Trait,
// Either a record or enum
DataClass,
}
@@ -85,7 +88,6 @@ pub enum Type {
// How the object is implemented.
imp: ObjectImpl,
},
- ForeignExecutor,
// Types defined in the component API, each of which has a string name.
Record {
module_path: String,