summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_checksum_derive
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/uniffi_checksum_derive
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
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.rs138
3 files changed, 181 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..9df6eba7b4
--- /dev/null
+++ b/third_party/rust/uniffi_checksum_derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"028104be15a1d73a8ca192a30865b26827344808a95b21e3798e4c9406ebc4f1","src/lib.rs":"44d2e2c595b14d33d16c71dfe4ef42ad0b9e010a878ee2ec49c2e929d60275ba"},"package":"55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"} \ 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..a3c4ed7ca3
--- /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.25.3"
+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 = "2.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..e600982d08
--- /dev/null
+++ b/third_party/rust/uniffi_checksum_derive/src/lib.rs
@@ -0,0 +1,138 @@
+/* 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/. */
+
+//! 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, Meta,
+};
+
+fn has_ignore_attribute(attrs: &[Attribute]) -> bool {
+ attrs.iter().any(|attr| {
+ if attr.path().is_ident("checksum_ignore") {
+ if let Meta::List(_) | Meta::NameValue(_) = &attr.meta {
+ 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 = fields.named.iter()
+ .filter(|field| !has_ignore_attribute(&field.attrs))
+ .map(|field| {
+ let ident = field.ident.as_ref().unwrap();
+ 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()
+}