diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/uniffi_meta/src/lib.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/uniffi_meta/src/lib.rs')
-rw-r--r-- | third_party/rust/uniffi_meta/src/lib.rs | 280 |
1 files changed, 280 insertions, 0 deletions
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) + } +} |