diff options
Diffstat (limited to 'third_party/rust/uniffi_meta')
-rw-r--r-- | third_party/rust/uniffi_meta/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/uniffi_meta/Cargo.toml | 33 | ||||
-rw-r--r-- | third_party/rust/uniffi_meta/src/lib.rs | 280 |
3 files changed, 314 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_meta/.cargo-checksum.json b/third_party/rust/uniffi_meta/.cargo-checksum.json new file mode 100644 index 0000000000..c7b53da275 --- /dev/null +++ b/third_party/rust/uniffi_meta/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"034db422dda8022d11beeac51c91bb472c9fc8d523e95a01a348ed6c90383bc1","src/lib.rs":"fde4a760b126cacf7e8008a8a8ce4e97b3c91d1ec3db08df4945bee549dee16a"},"package":"66fdab2c436aed7a6391bec64204ec33948bfed9b11b303235740771f85c4ea6"}
\ No newline at end of file diff --git a/third_party/rust/uniffi_meta/Cargo.toml b/third_party/rust/uniffi_meta/Cargo.toml new file mode 100644 index 0000000000..ee71f4c121 --- /dev/null +++ b/third_party/rust/uniffi_meta/Cargo.toml @@ -0,0 +1,33 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "uniffi_meta" +version = "0.23.0" +description = "uniffi_meta" +homepage = "https://mozilla.github.io/uniffi-rs" +keywords = [ + "ffi", + "bindgen", +] +license = "MPL-2.0" +repository = "https://github.com/mozilla/uniffi-rs" + +[dependencies.serde] +version = "1.0.136" +features = ["derive"] + +[dependencies.siphasher] +version = "0.3" + +[dependencies.uniffi_checksum_derive] +version = "0.23.0" diff --git a/third_party/rust/uniffi_meta/src/lib.rs b/third_party/rust/uniffi_meta/src/lib.rs new file mode 100644 index 0000000000..13af3b112d --- /dev/null +++ b/third_party/rust/uniffi_meta/src/lib.rs @@ -0,0 +1,280 @@ +/* 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 std::{collections::BTreeMap, hash::Hasher}; +pub use uniffi_checksum_derive::Checksum; + +use serde::{Deserialize, Serialize}; + +/// Similar to std::hash::Hash. +/// +/// Implementations of this trait are expected to update the hasher state in +/// the same way across platforms. #[derive(Checksum)] will do the right thing. +pub trait Checksum { + fn checksum<H: Hasher>(&self, state: &mut H); +} + +impl Checksum for bool { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write_u8(*self as u8); + } +} + +impl Checksum for u64 { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write(&self.to_le_bytes()); + } +} + +impl Checksum for i64 { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write(&self.to_le_bytes()); + } +} + +impl<T: Checksum> Checksum for Box<T> { + fn checksum<H: Hasher>(&self, state: &mut H) { + (**self).checksum(state) + } +} + +impl<T: Checksum> Checksum for [T] { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write(&(self.len() as u64).to_le_bytes()); + for item in self { + Checksum::checksum(item, state); + } + } +} + +impl<T: Checksum> Checksum for Vec<T> { + fn checksum<H: Hasher>(&self, state: &mut H) { + Checksum::checksum(&**self, state); + } +} + +impl<K: Checksum, V: Checksum> Checksum for BTreeMap<K, V> { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write(&(self.len() as u64).to_le_bytes()); + for (key, value) in self { + Checksum::checksum(key, state); + Checksum::checksum(value, state); + } + } +} + +impl<T: Checksum> Checksum for Option<T> { + fn checksum<H: Hasher>(&self, state: &mut H) { + match self { + None => state.write(&0u64.to_le_bytes()), + Some(value) => { + state.write(&1u64.to_le_bytes()); + Checksum::checksum(value, state) + } + } + } +} + +impl Checksum for str { + fn checksum<H: Hasher>(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff); + } +} + +impl Checksum for String { + fn checksum<H: Hasher>(&self, state: &mut H) { + (**self).checksum(state) + } +} + +impl Checksum for &str { + fn checksum<H: Hasher>(&self, state: &mut H) { + (**self).checksum(state) + } +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct FnMetadata { + pub module_path: Vec<String>, + pub name: String, + pub inputs: Vec<FnParamMetadata>, + pub return_type: Option<Type>, + pub throws: Option<String>, +} + +impl FnMetadata { + pub fn ffi_symbol_name(&self) -> String { + fn_ffi_symbol_name(&self.module_path, &self.name, checksum(self)) + } +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct MethodMetadata { + pub module_path: Vec<String>, + pub self_name: String, + pub name: String, + pub inputs: Vec<FnParamMetadata>, + pub return_type: Option<Type>, + pub throws: Option<String>, +} + +impl MethodMetadata { + pub fn ffi_symbol_name(&self) -> String { + let full_name = format!("impl_{}_{}", self.self_name, self.name); + fn_ffi_symbol_name(&self.module_path, &full_name, checksum(self)) + } +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct FnParamMetadata { + pub name: String, + #[serde(rename = "type")] + pub ty: Type, +} + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Checksum, Deserialize, Serialize)] +pub enum Type { + U8, + U16, + U32, + U64, + I8, + I16, + I32, + I64, + F32, + F64, + Bool, + String, + Option { + inner_type: Box<Type>, + }, + Vec { + inner_type: Box<Type>, + }, + HashMap { + key_type: Box<Type>, + value_type: Box<Type>, + }, + ArcObject { + object_name: String, + }, + Unresolved { + name: String, + }, +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct RecordMetadata { + pub module_path: Vec<String>, + pub name: String, + pub fields: Vec<FieldMetadata>, +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct FieldMetadata { + pub name: String, + #[serde(rename = "type")] + pub ty: Type, +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct EnumMetadata { + pub module_path: Vec<String>, + pub name: String, + pub variants: Vec<VariantMetadata>, +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct VariantMetadata { + pub name: String, + pub fields: Vec<FieldMetadata>, +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct ObjectMetadata { + pub module_path: Vec<String>, + pub name: String, +} + +impl ObjectMetadata { + /// FFI symbol name for the `free` function for this object. + /// + /// This function is used to free the memory used by this object. + pub fn free_ffi_symbol_name(&self) -> String { + let free_name = format!("object_free_{}", self.name); + fn_ffi_symbol_name(&self.module_path, &free_name, checksum(self)) + } +} + +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub struct ErrorMetadata { + pub module_path: Vec<String>, + pub name: String, + pub variants: Vec<VariantMetadata>, + pub flat: bool, +} + +/// Returns the last 16 bits of the value's hash as computed with [`SipHasher13`]. +/// +/// To be used as a checksum of FFI symbols, as a safeguard against different UniFFI versions being +/// used for scaffolding and bindings generation. +pub fn checksum<T: Checksum>(val: &T) -> u16 { + let mut hasher = siphasher::sip::SipHasher13::new(); + val.checksum(&mut hasher); + (hasher.finish() & 0x000000000000FFFF) as u16 +} + +pub fn fn_ffi_symbol_name(mod_path: &[String], name: &str, checksum: u16) -> String { + let mod_path = mod_path.join("__"); + format!("_uniffi_{mod_path}_{name}_{checksum:x}") +} + +/// Enum covering all the possible metadata types +#[derive(Clone, Debug, Checksum, Deserialize, Serialize)] +pub enum Metadata { + Func(FnMetadata), + Method(MethodMetadata), + Record(RecordMetadata), + Enum(EnumMetadata), + Object(ObjectMetadata), + Error(ErrorMetadata), +} + +impl From<FnMetadata> for Metadata { + fn from(value: FnMetadata) -> Metadata { + Self::Func(value) + } +} + +impl From<MethodMetadata> for Metadata { + fn from(m: MethodMetadata) -> Self { + Self::Method(m) + } +} + +impl From<RecordMetadata> for Metadata { + fn from(r: RecordMetadata) -> Self { + Self::Record(r) + } +} + +impl From<EnumMetadata> for Metadata { + fn from(e: EnumMetadata) -> Self { + Self::Enum(e) + } +} + +impl From<ObjectMetadata> for Metadata { + fn from(v: ObjectMetadata) -> Self { + Self::Object(v) + } +} + +impl From<ErrorMetadata> for Metadata { + fn from(v: ErrorMetadata) -> Self { + Self::Error(v) + } +} |