summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_checksum_derive
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/uniffi_checksum_derive
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/uniffi_checksum_derive')
-rw-r--r--third_party/rust/uniffi_checksum_derive/.cargo-checksum.json1
-rw-r--r--third_party/rust/uniffi_checksum_derive/Cargo.toml42
-rw-r--r--third_party/rust/uniffi_checksum_derive/src/lib.rs134
3 files changed, 177 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_checksum_derive/.cargo-checksum.json b/third_party/rust/uniffi_checksum_derive/.cargo-checksum.json
new file mode 100644
index 0000000000..f27c09330c
--- /dev/null
+++ b/third_party/rust/uniffi_checksum_derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"2ab3c60724c4c504297f8876bf0a8d1291f76a2fc46f5e83634aa147e89ffc71","src/lib.rs":"c68c69a1cf6a69e5fe78f7b069364a265c5bb6ce8c0abf0b5745eca01c79604a"},"package":"78b6e16d46caf942016997af8bbdf4b163bf8ae3deb0b667d9643de7b7ffd4c9"} \ No newline at end of file
diff --git a/third_party/rust/uniffi_checksum_derive/Cargo.toml b/third_party/rust/uniffi_checksum_derive/Cargo.toml
new file mode 100644
index 0000000000..23056e2267
--- /dev/null
+++ b/third_party/rust/uniffi_checksum_derive/Cargo.toml
@@ -0,0 +1,42 @@
+# 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_checksum_derive"
+version = "0.21.1"
+authors = ["Firefox Sync Team <sync-team@mozilla.com>"]
+description = "a multi-language bindings generator for rust (checksum custom derive)"
+homepage = "https://mozilla.github.io/uniffi-rs"
+documentation = "https://mozilla.github.io/uniffi-rs"
+keywords = [
+ "ffi",
+ "bindgen",
+]
+license = "MPL-2.0"
+repository = "https://github.com/mozilla/uniffi-rs"
+
+[lib]
+proc-macro = true
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0"
+features = [
+ "derive",
+ "parsing",
+]
+
+[features]
+default = []
+nightly = []
diff --git a/third_party/rust/uniffi_checksum_derive/src/lib.rs b/third_party/rust/uniffi_checksum_derive/src/lib.rs
new file mode 100644
index 0000000000..2fefdb2574
--- /dev/null
+++ b/third_party/rust/uniffi_checksum_derive/src/lib.rs
@@ -0,0 +1,134 @@
+/* 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/. */
+#![cfg_attr(feature = "nightly", feature(proc_macro_expand))]
+
+//! Custom derive for uniffi_meta::Checksum
+
+use proc_macro::TokenStream;
+use quote::{format_ident, quote};
+use syn::{parse_macro_input, Attribute, Data, DeriveInput, Expr, ExprLit, Fields, Index, Lit};
+
+fn has_ignore_attribute(attrs: &[Attribute]) -> bool {
+ attrs.iter().any(|attr| {
+ if attr.path.is_ident("checksum_ignore") {
+ if !attr.tokens.is_empty() {
+ panic!("#[checksum_ignore] doesn't accept extra information");
+ }
+ true
+ } else {
+ false
+ }
+ })
+}
+
+#[proc_macro_derive(Checksum, attributes(checksum_ignore))]
+pub fn checksum_derive(input: TokenStream) -> TokenStream {
+ let input: DeriveInput = parse_macro_input!(input);
+
+ let name = input.ident;
+
+ let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+
+ let code = match input.data {
+ Data::Enum(enum_)
+ if enum_.variants.len() == 1
+ && enum_
+ .variants
+ .iter()
+ .all(|variant| matches!(variant.fields, Fields::Unit)) =>
+ {
+ quote!()
+ }
+ Data::Enum(enum_) => {
+ let mut next_discriminant = 0u64;
+ let match_inner = enum_.variants.iter().map(|variant| {
+ let ident = &variant.ident;
+ if has_ignore_attribute(&variant.attrs) {
+ panic!("#[checksum_ignore] is not supported in enums");
+ }
+ match &variant.discriminant {
+ Some((_, Expr::Lit(ExprLit { lit: Lit::Int(value), .. }))) => {
+ next_discriminant = value.base10_parse::<u64>().unwrap();
+ }
+ Some(_) => {
+ panic!("#[derive(Checksum)] doesn't support non-numeric explicit discriminants in enums");
+ }
+ None => {}
+ }
+ let discriminant = quote! { state.write(&#next_discriminant.to_le_bytes()) };
+ next_discriminant += 1;
+ match &variant.fields {
+ Fields::Unnamed(fields) => {
+ let field_idents = fields
+ .unnamed
+ .iter()
+ .enumerate()
+ .map(|(num, _)| format_ident!("__self_{}", num));
+ let field_stmts = field_idents
+ .clone()
+ .map(|ident| quote! { Checksum::checksum(#ident, state); });
+ quote! {
+ Self::#ident(#(#field_idents,)*) => {
+ #discriminant;
+ #(#field_stmts)*
+ }
+ }
+ }
+ Fields::Named(fields) => {
+ let field_idents = fields
+ .named
+ .iter()
+ .map(|field| field.ident.as_ref().unwrap());
+ let field_stmts = field_idents
+ .clone()
+ .map(|ident| quote! { Checksum::checksum(#ident, state); });
+ quote! {
+ Self::#ident { #(#field_idents,)* } => {
+ #discriminant;
+ #(#field_stmts)*
+ }
+ }
+ }
+ Fields::Unit => quote! { Self::#ident => #discriminant, },
+ }
+ });
+ quote! {
+ match self {
+ #(#match_inner)*
+ }
+ }
+ }
+ Data::Struct(struct_) => {
+ let stmts = struct_
+ .fields
+ .iter()
+ .enumerate()
+ .filter_map(|(num, field)| {
+ (!has_ignore_attribute(&field.attrs)).then(|| match field.ident.as_ref() {
+ Some(ident) => quote! { Checksum::checksum(&self.#ident, state); },
+ None => {
+ let i = Index::from(num);
+ quote! { Checksum::checksum(&self.#i, state); }
+ }
+ })
+ });
+ quote! {
+ #(#stmts)*
+ }
+ }
+ Data::Union(_) => {
+ panic!("#[derive(Checksum)] is not supported for unions");
+ }
+ };
+
+ quote! {
+ #[automatically_derived]
+ impl #impl_generics Checksum for #name #ty_generics #where_clause {
+ fn checksum<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
+ #code
+ }
+ }
+ }
+ .into()
+}