commit e285c7f3d366a63e6fd365ccc346ef9e3aeb4184
parent 57129f85b8b10593c4ce23a1eaf62604bccae7bd
Author: Johannes Schmidt <joschmidt@mozilla.com>
Date: Thu, 2 Oct 2025 08:12:32 +0000
Bug 1966326 - use rust logins: vendor rust and generate uniffi r=supply-chain-reviewers,markh
These are the build artefacts from the previously configured application
sevrices components, split out for easier review. It's the result of
both `./mach vendor rust` and `./mach uniffi generate` commands.
Differential Revision: https://phabricator.services.mozilla.com/D260122
Diffstat:
154 files changed, 32867 insertions(+), 4989 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -394,6 +394,12 @@ name = "backtrace"
version = "0.3.999"
[[package]]
+name = "base16"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"
+
+[[package]]
name = "base64"
version = "0.21.999"
dependencies = [
@@ -2673,6 +2679,8 @@ dependencies = [
"context_id",
"error-support",
"filter_adult",
+ "init_rust_components",
+ "logins",
"relevancy",
"search",
"suggest",
@@ -2951,6 +2959,20 @@ dependencies = [
]
[[package]]
+name = "hawk"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab302457b3e28e621daab18932d67a67328f29240bfaa5f604b7627ece1eacda"
+dependencies = [
+ "anyhow",
+ "base64 0.22.1",
+ "log",
+ "once_cell",
+ "thiserror 1.999.999",
+ "url",
+]
+
+[[package]]
name = "headers"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3386,6 +3408,15 @@ dependencies = [
]
[[package]]
+name = "init_rust_components"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "nss",
+ "uniffi",
+]
+
+[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
@@ -3566,6 +3597,20 @@ dependencies = [
]
[[package]]
+name = "jwcrypto"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "base64 0.21.999",
+ "error-support",
+ "rc_crypto",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "thiserror 2.0.12",
+]
+
+[[package]]
name = "keccak"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3876,6 +3921,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
+name = "logins"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "error-support",
+ "futures",
+ "interrupt-support",
+ "jwcrypto",
+ "lazy_static",
+ "nss",
+ "parking_lot",
+ "rusqlite 0.37.0",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sql-support",
+ "sync-guid",
+ "sync15",
+ "thiserror 2.0.12",
+ "uniffi",
+ "url",
+]
+
+[[package]]
name = "mach2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4898,6 +4969,20 @@ dependencies = [
]
[[package]]
+name = "nss"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "base64 0.21.999",
+ "error-support",
+ "nss_sys",
+ "once_cell",
+ "serde",
+ "serde_derive",
+ "thiserror 2.0.12",
+]
+
+[[package]]
name = "nss-gk-api"
version = "0.3.0"
source = "git+https://github.com/beurdouche/nss-gk-api?rev=e48a946811ffd64abc78de3ee284957d8d1c0d63#e48a946811ffd64abc78de3ee284957d8d1c0d63"
@@ -4913,6 +4998,20 @@ dependencies = [
]
[[package]]
+name = "nss_build_common"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+
+[[package]]
+name = "nss_sys"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "libsqlite3-sys",
+ "nss_build_common",
+]
+
+[[package]]
name = "nsstring"
version = "0.1.0"
dependencies = [
@@ -5689,6 +5788,19 @@ dependencies = [
]
[[package]]
+name = "rc_crypto"
+version = "0.1.0"
+source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
+dependencies = [
+ "base64 0.21.999",
+ "error-support",
+ "hawk",
+ "hex",
+ "nss",
+ "thiserror 2.0.12",
+]
+
+[[package]]
name = "redox_syscall"
version = "0.5.999"
@@ -6609,10 +6721,13 @@ version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=f6f667f590ac15367fc37eb1ad3a6bdea4ffc526#f6f667f590ac15367fc37eb1ad3a6bdea4ffc526"
dependencies = [
"anyhow",
+ "base16",
+ "base64 0.21.999",
"error-support",
"interrupt-support",
"lazy_static",
"payload-support",
+ "rc_crypto",
"serde",
"serde_derive",
"serde_json",
@@ -6620,6 +6735,8 @@ dependencies = [
"sync-guid",
"thiserror 2.0.12",
"uniffi",
+ "url",
+ "viaduct",
]
[[package]]
diff --git a/docs/rust-components/api/js/init_rust_components.md b/docs/rust-components/api/js/init_rust_components.md
@@ -0,0 +1,3 @@
+# RustInitRustComponents.sys.mjs
+```{js:autofunction} RustInitRustComponents.sys.initialize
+```
diff --git a/docs/rust-components/api/js/logins.md b/docs/rust-components/api/js/logins.md
@@ -0,0 +1,103 @@
+# RustLogins.sys.mjs
+```{js:autoclass} RustLogins.sys.AuthenticationCanceled
+ :members:
+ :exclude-members: AuthenticationCanceled
+```
+```{js:autoclass} RustLogins.sys.AuthenticationError
+ :members:
+ :exclude-members: AuthenticationError
+```
+```{js:autoclass} RustLogins.sys.BulkResultEntry
+ :members:
+ :exclude-members: BulkResultEntry
+```
+```{js:autoclass} RustLogins.sys.DecryptionFailed
+ :members:
+ :exclude-members: DecryptionFailed
+```
+```{js:autoclass} RustLogins.sys.EncryptionFailed
+ :members:
+ :exclude-members: EncryptionFailed
+```
+```{js:autoclass} RustLogins.sys.Interrupted
+ :members:
+ :exclude-members: Interrupted
+```
+```{js:autoclass} RustLogins.sys.InvalidKey
+ :members:
+ :exclude-members: InvalidKey
+```
+```{js:autoclass} RustLogins.sys.InvalidRecord
+ :members:
+ :exclude-members: InvalidRecord
+```
+```{js:autoclass} RustLogins.sys.Login
+ :members:
+ :exclude-members: Login
+```
+```{js:autoclass} RustLogins.sys.LoginEntry
+ :members:
+ :exclude-members: LoginEntry
+```
+```{js:autoclass} RustLogins.sys.LoginEntryWithMeta
+ :members:
+ :exclude-members: LoginEntryWithMeta
+```
+```{js:autoclass} RustLogins.sys.LoginMeta
+ :members:
+ :exclude-members: LoginMeta
+```
+```{js:autoclass} RustLogins.sys.LoginsApiError
+ :members:
+ :exclude-members: LoginsApiError
+```
+```{js:autoclass} RustLogins.sys.LoginsDeletionMetrics
+ :members:
+ :exclude-members: LoginsDeletionMetrics
+```
+```{js:autoclass} RustLogins.sys.MissingKey
+ :members:
+ :exclude-members: MissingKey
+```
+```{js:autoclass} RustLogins.sys.NoSuchRecord
+ :members:
+ :exclude-members: NoSuchRecord
+```
+```{js:autoclass} RustLogins.sys.NssAuthenticationError
+ :members:
+ :exclude-members: NssAuthenticationError
+```
+```{js:autoclass} RustLogins.sys.NssKeyManager
+ :members:
+ :exclude-members: NssKeyManager
+```
+```{js:autoclass} RustLogins.sys.NssUninitialized
+ :members:
+ :exclude-members: NssUninitialized
+```
+```{js:autoclass} RustLogins.sys.PrimaryPasswordAuthenticator
+ :members:
+ :exclude-members: PrimaryPasswordAuthenticator
+```
+```{js:autoclass} RustLogins.sys.SyncAuthInvalid
+ :members:
+ :exclude-members: SyncAuthInvalid
+```
+```{js:autoclass} RustLogins.sys.UnexpectedLoginsApiError
+ :members:
+ :exclude-members: UnexpectedLoginsApiError
+```
+```{js:autofunction} RustLogins.sys.checkCanary
+```
+```{js:autofunction} RustLogins.sys.createCanary
+```
+```{js:autofunction} RustLogins.sys.createKey
+```
+```{js:autofunction} RustLogins.sys.createLoginStoreWithNssKeymanager
+```
+```{js:autofunction} RustLogins.sys.createLoginStoreWithStaticKeyManager
+```
+```{js:autofunction} RustLogins.sys.createManagedEncdec
+```
+```{js:autofunction} RustLogins.sys.createStaticKeyManager
+```
diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml
@@ -315,7 +315,7 @@ end = "2025-08-30"
[[wildcard-audits.hawk]]
who = "Ryan Safaeian <rsafaeian@mozilla.com>"
criteria = "safe-to-deploy"
-user-id = 158511
+user-id = 158511 # Yarik (lotas)
start = "2022-05-05"
end = "2026-04-24"
notes = "Hawk is written and maintained by mozilla employees."
diff --git a/supply-chain/config.toml b/supply-chain/config.toml
@@ -181,7 +181,6 @@ audit-as-crates-io = false
[policy.mtu]
audit-as-crates-io = true
-notes = "This is a first-party crate which is also published to crates.io, but since <https://github.com/mozilla/neqo/pull/2897> part of <https://github.com/mozilla/neqo>."
[policy.naga]
audit-as-crates-io = true
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
@@ -302,6 +302,13 @@ user-id = 2915
user-login = "Amanieu"
user-name = "Amanieu d'Antras"
+[[publisher.hawk]]
+version = "5.0.1"
+when = "2024-09-13"
+user-id = 158511
+user-login = "lotas"
+user-name = "Yarik"
+
[[publisher.headers]]
version = "0.3.9"
when = "2023-08-31"
diff --git a/third_party/rust/base16/.cargo-checksum.json b/third_party/rust/base16/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"fe5fc3587d67ecbe1f26f917e448120b163c88dd2f770fd057215965a23fb318","Cargo.toml":"2d899ced4d3d938d5f4ecfba787b4443787d24d474e4511beeed6ae565bfa1c3","LICENSE-CC0":"a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499","README.md":"66ce64772ee5fd96c954a1d8ae5679c684f5dbdb2c8bf29e09bac1158c089e1e","benches/bench.rs":"df402e28f2b0ea63ba725cf20db57307e1ebfadc3120d8af6193f30c5db0dd14","src/lib.rs":"2bd2cf157991c5d79a85d4a095294f60ee238956922518fe3a35953be8197812","tests/doctest_copies.rs":"b274efd7a8a95e5a7d9d4e59eacb0458329343169628f389c7d867bc39846524","tests/tests.rs":"6f93802e5eb447966bbe154707ff552a251a30653e955902f04669af7eecd6f2"},"package":"d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"}
+\ No newline at end of file
diff --git a/third_party/rust/base16/CHANGELOG.md b/third_party/rust/base16/CHANGELOG.md
@@ -0,0 +1,35 @@
+# 0.2.0
+
+- `encode_byte` now returns `[u8; 2]` instead of `(u8, u8)`, as in practice this
+ tends to be more convenient.
+
+- The use of `std` which requires the `alloc` trait has been split into the
+ `alloc` feature.
+
+- `base16` has been relicensed as CC0-1.0 from dual MIT/Apache-2.0.
+
+# 0.2.1
+
+- Make code more bulletproof in the case of panics when using the `decode_buf`
+ or `encode_config_buf` functions.
+
+ Previously, if the innermost encode/decode function paniced, code that
+ inspected the contents of the Vec (either in a Drop implementation, or by
+ catching the panic) could read from uninitialized memory.
+
+ However, I don't believe it is possible for the innermost encode/decode
+ functions to panic, so I don't think there was any risk in previous
+ versions.
+
+ I don't believe the panic is possible because only two panics exist in the generated assembly (both only in debug configuration, and not in release). The two panics are respectively:
+
+ - a debug_assert verifying the caller performed a check (which it does).
+
+ - a usize overflow check on an index variable, which is impossible as we've
+ already tested for that.
+
+ That said, this is some powerful rationalization, so I'm cutting a new version
+ with this fix anyway.
+
+- Additionally, several functions that previously used unsafe internally now
+ either use less unsafe, or are entirely safe.
diff --git a/third_party/rust/base16/Cargo.toml b/third_party/rust/base16/Cargo.toml
@@ -0,0 +1,49 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "base16"
+version = "0.2.1"
+authors = ["Thom Chiovoloni <tchiovoloni@mozilla.com>"]
+description = "base16 (hex) encoding and decoding"
+readme = "README.md"
+keywords = ["hex", "base16", "encode", "decode", "no_std"]
+categories = ["encoding", "no-std"]
+license = "CC0-1.0"
+repository = "https://github.com/thomcc/rust-base16"
+[package.metadata.docs.rs]
+all-features = true
+
+[[bench]]
+name = "bench"
+harness = false
+
+[dependencies]
+[dev-dependencies.criterion]
+version = "0.2.11"
+
+[dev-dependencies.rand]
+version = "0.6.5"
+
+[features]
+alloc = []
+default = ["std"]
+std = ["alloc"]
+[badges.circle-ci]
+branch = "master"
+repository = "thomcc/rust-base16"
+
+[badges.codecov]
+branch = "master"
+repository = "thomcc/rust-base16"
+service = "github"
diff --git a/third_party/rust/base16/LICENSE-CC0 b/third_party/rust/base16/LICENSE-CC0
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/third_party/rust/base16/README.md b/third_party/rust/base16/README.md
@@ -0,0 +1,62 @@
+# [base16](https://crates.io/crates/base16) (hex) encoding for Rust.
+
+[](https://docs.rs/base16) [](https://circleci.com/gh/thomcc/rust-base16) [](https://codecov.io/gh/thomcc/rust-base16)
+
+This is a base16 (e.g. hexadecimal) encoding and decoding library which was initially written with an emphasis on performance.
+
+This was before Rust added SIMD, and I haven't gotten around to adding that. It's still probably the fastest non-SIMD impl.
+
+## Usage
+
+Add `base16 = "0.2"` to Cargo.toml, then:
+
+```rust
+fn main() {
+ let original_msg = "Foobar";
+ let hex_string = base16::encode_lower(original_msg);
+ assert_eq!(hex_string, "466f6f626172");
+ let decoded = base16::decode(&hex_string).unwrap();
+ assert_eq!(String::from_utf8(decoded).unwrap(), original_msg);
+}
+```
+
+More usage examples in the [docs](https://docs.rs/base16).
+
+## `no_std` Usage
+
+This crate supports use in `no_std` configurations using the following knobs.
+
+- The `"alloc"` feature, which is on by default, adds a number of helpful functions
+ that require use of the [`alloc`](https://doc.rust-lang.org/alloc/index.html) crate,
+ but not the rest of `std`. This is `no_std` compatible.
+ - Each function documents if it requires use of the `alloc` feature.
+- The `"std"` feature, which is on by default, enables the `"alloc"` feature, and
+ additionally makes `base16::DecodeError` implement the `std::error::Error` trait.
+ (Frustratingly, this trait is in `std` and not in `core` or `alloc`...)
+
+For clarity, this means that by default, we assume you are okay with use of `std`.
+
+If you'd like to disable the use of `std`, but are in an environment where you have
+an allocator (e.g. use of the [`alloc`](https://doc.rust-lang.org/alloc/index.html)
+crate is acceptable), then you require this as `alloc`-only as follows:
+
+```toml
+[dependencies]
+# Turn of use of `std` (but leave use of `alloc`).
+base16 = { version = "0.2", default-features = false, features = ["alloc"] }
+```
+
+If you just want the core `base16` functionality and none of the helpers, then
+you should turn off all features.
+
+```toml
+[dependencies]
+# Turn of use of `std` and `alloc`.
+base16 = { version = "0.2", default-features = false }
+```
+
+Both of these configurations are `no_std` compatible.
+
+# License
+
+Public domain, as explained [here](https://creativecommons.org/publicdomain/zero/1.0/legalcode)
diff --git a/third_party/rust/base16/benches/bench.rs b/third_party/rust/base16/benches/bench.rs
@@ -0,0 +1,145 @@
+#![allow(unknown_lints)]
+
+use criterion::{criterion_group, criterion_main, Criterion, BatchSize, Throughput, ParameterizedBenchmark};
+use rand::prelude::*;
+
+
+const SIZES: &[usize] = &[3, 16, 64, 256, 1024];
+
+fn rand_enc_input(sz: usize) -> (Vec<u8>, base16::EncConfig) {
+ let mut rng = thread_rng();
+ let mut vec = vec![0u8; sz];
+ let cfg = if rng.gen::<bool>() {
+ base16::EncodeUpper
+ } else {
+ base16::EncodeLower
+ };
+ rng.fill_bytes(&mut vec);
+ (vec, cfg)
+}
+
+fn batch_size_for_input(i: usize) -> BatchSize {
+ if i < 1024 {
+ BatchSize::SmallInput
+ } else {
+ BatchSize::LargeInput
+ }
+}
+
+fn bench_encode(c: &mut Criterion) {
+ c.bench(
+ "encode to fresh string",
+ ParameterizedBenchmark::new(
+ "encode_config",
+ |b, items| {
+ b.iter_batched(
+ || rand_enc_input(*items),
+ |(input, enc)| base16::encode_config(&input, enc),
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32)),
+ );
+
+ c.bench(
+ "encode to preallocated string",
+ ParameterizedBenchmark::new(
+ "encode_config_buf",
+ |b, items| {
+ b.iter_batched(
+ || (rand_enc_input(*items), String::with_capacity(2 * *items)),
+ |((input, enc), mut buf)| {
+ buf.truncate(0);
+ base16::encode_config_buf(&input, enc, &mut buf)
+ },
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32)),
+ );
+
+ c.bench(
+ "encode to slice",
+ ParameterizedBenchmark::new(
+ "encode_config_slice",
+ |b, items| {
+ b.iter_batched(
+ || (rand_enc_input(*items), vec![0u8; 2 * *items]),
+ |((input, enc), mut dst)| {
+ base16::encode_config_slice(&input, enc, &mut dst)
+ },
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32)),
+ );
+}
+
+fn rand_hex_string(size: usize) -> String {
+ let mut rng = thread_rng();
+ let mut s = String::with_capacity(size);
+ let chars: &[u8] = b"0123456789abcdefABCDEF";
+ while s.len() < size {
+ s.push(*chars.choose(&mut rng).unwrap() as char);
+ }
+ s
+}
+
+fn bench_decode(c: &mut Criterion) {
+ c.bench(
+ "decode to fresh vec",
+ ParameterizedBenchmark::new(
+ "decode",
+ |b, items| {
+ b.iter_batched(
+ || rand_hex_string(*items),
+ |input| base16::decode(&input),
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32 * 2)),
+ );
+
+ c.bench(
+ "decode to preallocated vec",
+ ParameterizedBenchmark::new(
+ "decode_buf",
+ |b, items| {
+ b.iter_batched(
+ || (rand_hex_string(*items), Vec::with_capacity(*items)),
+ |(input, mut buf)| {
+ buf.truncate(0);
+ base16::decode_buf(&input, &mut buf)
+ },
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32 * 2)),
+ );
+
+ c.bench(
+ "decode to slice",
+ ParameterizedBenchmark::new(
+ "decode_slice",
+ |b, items| {
+ b.iter_batched(
+ || (rand_hex_string(*items), vec![0u8; *items]),
+ |(input, mut buf)| {
+ base16::decode_slice(&input, &mut buf)
+ },
+ batch_size_for_input(*items),
+ )
+ },
+ SIZES.iter().cloned(),
+ ).throughput(|bytes| Throughput::Bytes(*bytes as u32 * 2)),
+ );
+}
+
+
+criterion_group!(benches, bench_encode, bench_decode);
+criterion_main!(benches);
diff --git a/third_party/rust/base16/src/lib.rs b/third_party/rust/base16/src/lib.rs
@@ -0,0 +1,639 @@
+//! This is a base16 (e.g. hexadecimal) encoding and decoding library with an
+//! emphasis on performance. The API is very similar and inspired by the base64
+//! crate's API, however it's less complex (base16 is much more simple than
+//! base64).
+//!
+//! # Encoding
+//!
+//! The config options at the moment are limited to the output case (upper vs
+//! lower).
+//!
+//! | Function | Output | Allocates | Requires `alloc` feature |
+//! | ---------------------------------- | ---------------------------- | ----------------------- | ------------------------ |
+//! | [`encode_upper`], [`encode_lower`] | Returns a new `String` | Always | Yes |
+//! | [`encode_config`] | Returns a new `String` | Always | Yes |
+//! | [`encode_config_buf`] | Appends to provided `String` | If buffer needs to grow | Yes |
+//! | [`encode_config_slice`] | Writes to provided `&[u8]` | Never | No |
+//!
+//! # Decoding
+//!
+//! Note that there are no config options (In the future one might be added to
+//! restrict the input character set, but it's not clear to me that this is
+//! useful).
+//!
+//! | Function | Output | Allocates | Requires `alloc` feature |
+//! | ----------------- | ----------------------------- | ----------------------- | ------------------------ |
+//! | [`decode`] | Returns a new `Vec<u8>` | Always | Yes |
+//! | [`decode_slice`] | Writes to provided `&[u8]` | Never | No |
+//! | [`decode_buf`] | Appends to provided `Vec<u8>` | If buffer needs to grow | Yes |
+//!
+//! # Features
+//!
+//! This crate has two features, both are enabled by default and exist to allow
+//! users in `no_std` environments to disable various portions of .
+//!
+//! - The `"alloc"` feature, which is on by default, adds a number of helpful
+//! functions that require use of the [`alloc`][alloc_crate] crate, but not the
+//! rest of `std`.
+//! - This is `no_std` compatible.
+//! - Each function should list whether or not it requires this feature
+//! under the `Availability` of its documentation.
+//!
+//! - The `"std"` feature, which is on by default, enables the `"alloc"`
+//! feature, and additionally makes [`DecodeError`] implement the
+//! `std::error::Error` trait.
+//!
+//! - Frustratingly, this trait is in `std` (and not in `core` or `alloc`),
+//! but not implementing it would be quite annoying for some users, so
+//! it's kept, even though it's what prevents us from being `no_std`
+//! compatible in all configurations.
+//!
+//! [alloc_crate]: https://doc.rust-lang.org/alloc/index.html
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![deny(missing_docs)]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+#[cfg(feature = "alloc")]
+use alloc::{vec::Vec, string::String};
+
+/// Configuration options for encoding. Just specifies whether or not output
+/// should be uppercase or lowercase.
+#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub enum EncConfig {
+ /// Encode using lower case characters for hex values >= 10
+ EncodeLower,
+ /// Encode using upper case characters for hex values >= 10
+ EncodeUpper,
+}
+
+pub use EncConfig::*;
+
+#[inline]
+fn encoded_size(source_len: usize) -> usize {
+ const USIZE_TOP_BIT: usize = 1usize << (core::mem::size_of::<usize>() * 8 - 1);
+ if (source_len & USIZE_TOP_BIT) != 0 {
+ usize_overflow(source_len)
+ }
+ source_len << 1
+}
+
+#[inline]
+fn encode_slice_raw(src: &[u8], cfg: EncConfig, dst: &mut [u8]) {
+ let lut = if cfg == EncodeLower { HEX_LOWER } else { HEX_UPPER };
+ debug_assert!(dst.len() == encoded_size(src.len()));
+ dst.chunks_exact_mut(2).zip(src.iter().copied()).for_each(|(d, sb)| {
+ d[0] = lut[(sb >> 4) as usize];
+ d[1] = lut[(sb & 0xf) as usize];
+ })
+}
+
+#[cfg(feature = "alloc")]
+#[inline]
+fn encode_to_string(bytes: &[u8], cfg: EncConfig) -> String {
+ let size = encoded_size(bytes.len());
+ let mut buf: Vec<u8> = Vec::with_capacity(size);
+ unsafe { buf.set_len(size); }
+ encode_slice_raw(bytes, cfg, &mut buf);
+ debug_assert!(core::str::from_utf8(&buf).is_ok());
+ unsafe { String::from_utf8_unchecked(buf) }
+}
+
+#[cfg(feature = "alloc")]
+#[inline]
+unsafe fn grow_vec_uninitialized(v: &mut Vec<u8>, grow_by: usize) -> usize {
+ v.reserve(grow_by);
+ let initial_len = v.len();
+ let new_len = initial_len + grow_by;
+ debug_assert!(new_len <= v.capacity());
+ v.set_len(new_len);
+ initial_len
+}
+
+/// Encode bytes as base16, using lower case characters for nibbles between 10
+/// and 15 (`a` through `f`).
+///
+/// This is equivalent to `base16::encode_config(bytes, base16::EncodeUpper)`.
+///
+/// # Example
+///
+/// ```
+/// assert_eq!(base16::encode_lower(b"Hello World"), "48656c6c6f20576f726c64");
+/// assert_eq!(base16::encode_lower(&[0xff, 0xcc, 0xaa]), "ffccaa");
+/// ```
+///
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs to produce a String.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn encode_lower<T: ?Sized + AsRef<[u8]>>(input: &T) -> String {
+ encode_to_string(input.as_ref(), EncodeLower)
+}
+
+/// Encode bytes as base16, using upper case characters for nibbles between
+/// 10 and 15 (`A` through `F`).
+///
+/// This is equivalent to `base16::encode_config(bytes, base16::EncodeUpper)`.
+///
+/// # Example
+///
+/// ```
+/// assert_eq!(base16::encode_upper(b"Hello World"), "48656C6C6F20576F726C64");
+/// assert_eq!(base16::encode_upper(&[0xff, 0xcc, 0xaa]), "FFCCAA");
+/// ```
+///
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs to produce a `String`.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn encode_upper<T: ?Sized + AsRef<[u8]>>(input: &T) -> String {
+ encode_to_string(input.as_ref(), EncodeUpper)
+}
+
+
+/// Encode `input` into a string using the listed config. The resulting string
+/// contains `input.len() * 2` bytes.
+///
+/// # Example
+///
+/// ```
+/// let data = [1, 2, 3, 0xaa, 0xbb, 0xcc];
+/// assert_eq!(base16::encode_config(&data, base16::EncodeLower), "010203aabbcc");
+/// assert_eq!(base16::encode_config(&data, base16::EncodeUpper), "010203AABBCC");
+/// ```
+///
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs to produce a `String`.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn encode_config<T: ?Sized + AsRef<[u8]>>(input: &T, cfg: EncConfig) -> String {
+ encode_to_string(input.as_ref(), cfg)
+}
+
+/// Encode `input` into the end of the provided buffer. Returns the number of
+/// bytes that were written.
+///
+/// Only allocates when `dst.size() + (input.len() * 2) >= dst.capacity()`.
+///
+/// # Example
+///
+/// ```
+/// let messages = &["Taako, ", "Merle, ", "Magnus"];
+/// let mut buffer = String::new();
+/// for msg in messages {
+/// let bytes_written = base16::encode_config_buf(msg.as_bytes(),
+/// base16::EncodeUpper,
+/// &mut buffer);
+/// assert_eq!(bytes_written, msg.len() * 2);
+/// }
+/// assert_eq!(buffer, "5461616B6F2C204D65726C652C204D61676E7573");
+/// ```
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs write to a `String`.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn encode_config_buf<T: ?Sized + AsRef<[u8]>>(input: &T,
+ cfg: EncConfig,
+ dst: &mut String) -> usize {
+ let src = input.as_ref();
+ let bytes_to_write = encoded_size(src.len());
+ // Swap the string out while we work on it, so that if we panic, we don't
+ // leave behind garbage (we do clear the string if we panic, but that's
+ // better than UB)
+ let mut buf = core::mem::replace(dst, String::new()).into_bytes();
+ let cur_size = unsafe { grow_vec_uninitialized(&mut buf, bytes_to_write) };
+
+ encode_slice_raw(src, cfg, &mut buf[cur_size..]);
+
+ debug_assert!(core::str::from_utf8(&buf).is_ok());
+ // Put `buf` back into `dst`.
+ *dst = unsafe { String::from_utf8_unchecked(buf) };
+
+ bytes_to_write
+}
+
+/// Write bytes as base16 into the provided output buffer. Never allocates.
+///
+/// This is useful if you wish to avoid allocation entirely (e.g. your
+/// destination buffer is on the stack), or control it precisely.
+///
+/// # Panics
+///
+/// Panics if the desination buffer is insufficiently large.
+///
+/// # Example
+///
+/// ```
+/// # extern crate core as std;
+/// // Writing to a statically sized buffer on the stack.
+/// let message = b"Wu-Tang Killa Bees";
+/// let mut buffer = [0u8; 1024];
+///
+/// let wrote = base16::encode_config_slice(message,
+/// base16::EncodeLower,
+/// &mut buffer);
+///
+/// assert_eq!(message.len() * 2, wrote);
+/// assert_eq!(std::str::from_utf8(&buffer[..wrote]).unwrap(),
+/// "57752d54616e67204b696c6c612042656573");
+///
+/// // Appending to an existing buffer is possible too.
+/// let wrote2 = base16::encode_config_slice(b": The Swarm",
+/// base16::EncodeLower,
+/// &mut buffer[wrote..]);
+/// let write_end = wrote + wrote2;
+/// assert_eq!(std::str::from_utf8(&buffer[..write_end]).unwrap(),
+/// "57752d54616e67204b696c6c6120426565733a2054686520537761726d");
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn encode_config_slice<T: ?Sized + AsRef<[u8]>>(input: &T,
+ cfg: EncConfig,
+ dst: &mut [u8]) -> usize {
+ let src = input.as_ref();
+ let need_size = encoded_size(src.len());
+ if dst.len() < need_size {
+ dest_too_small_enc(dst.len(), need_size);
+ }
+ encode_slice_raw(src, cfg, &mut dst[..need_size]);
+ need_size
+}
+
+/// Encode a single character as hex, returning a tuple containing the two
+/// encoded bytes in big-endian order -- the order the characters would be in
+/// when written out (e.g. the top nibble is the first item in the tuple)
+///
+/// # Example
+/// ```
+/// assert_eq!(base16::encode_byte(0xff, base16::EncodeLower), [b'f', b'f']);
+/// assert_eq!(base16::encode_byte(0xa0, base16::EncodeUpper), [b'A', b'0']);
+/// assert_eq!(base16::encode_byte(3, base16::EncodeUpper), [b'0', b'3']);
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn encode_byte(byte: u8, cfg: EncConfig) -> [u8; 2] {
+ let lut = if cfg == EncodeLower { HEX_LOWER } else { HEX_UPPER };
+ let lo = lut[(byte & 15) as usize];
+ let hi = lut[(byte >> 4) as usize];
+ [hi, lo]
+}
+
+/// Convenience wrapper for `base16::encode_byte(byte, base16::EncodeLower)`
+///
+/// See also `base16::encode_byte_u`.
+///
+/// # Example
+/// ```
+/// assert_eq!(base16::encode_byte_l(0xff), [b'f', b'f']);
+/// assert_eq!(base16::encode_byte_l(30), [b'1', b'e']);
+/// assert_eq!(base16::encode_byte_l(0x2d), [b'2', b'd']);
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn encode_byte_l(byte: u8) -> [u8; 2] {
+ encode_byte(byte, EncodeLower)
+}
+
+/// Convenience wrapper for `base16::encode_byte(byte, base16::EncodeUpper)`
+///
+/// See also `base16::encode_byte_l`.
+///
+/// # Example
+/// ```
+/// assert_eq!(base16::encode_byte_u(0xff), [b'F', b'F']);
+/// assert_eq!(base16::encode_byte_u(30), [b'1', b'E']);
+/// assert_eq!(base16::encode_byte_u(0x2d), [b'2', b'D']);
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn encode_byte_u(byte: u8) -> [u8; 2] {
+ encode_byte(byte, EncodeUpper)
+}
+
+/// Represents a problem with the data we want to decode.
+///
+/// This implements `std::error::Error` and `Display` if the `std`
+/// feature is enabled, but only `Display` if it is not.
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum DecodeError {
+ /// An invalid byte was found in the input (bytes must be `[0-9a-fA-F]`)
+ InvalidByte {
+ /// The index at which the problematic byte was found.
+ index: usize,
+ /// The byte that we cannot decode.
+ byte: u8
+ },
+ /// The length of the input not a multiple of two
+ InvalidLength {
+ /// The input length.
+ length: usize
+ },
+}
+
+#[cold]
+fn invalid_length(length: usize) -> DecodeError {
+ DecodeError::InvalidLength { length }
+}
+
+#[cold]
+fn invalid_byte(index: usize, src: &[u8]) -> DecodeError {
+ DecodeError::InvalidByte { index, byte: src[index] }
+}
+
+impl core::fmt::Display for DecodeError {
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ match *self {
+ DecodeError::InvalidByte { index, byte } => {
+ write!(f, "Invalid byte `b{:?}`, at index {}.",
+ byte as char, index)
+ }
+ DecodeError::InvalidLength { length } =>
+ write!(f, "Base16 data cannot have length {} (must be even)",
+ length),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for DecodeError {
+ fn description(&self) -> &str {
+ match *self {
+ DecodeError::InvalidByte { .. } => "Illegal byte in base16 data",
+ DecodeError::InvalidLength { .. } => "Illegal length for base16 data",
+ }
+ }
+
+ fn cause(&self) -> Option<&dyn std::error::Error> {
+ None
+ }
+}
+
+#[inline]
+fn decode_slice_raw(src: &[u8], dst: &mut[u8]) -> Result<(), usize> {
+ // checked in caller.
+ debug_assert!(src.len() / 2 == dst.len());
+ debug_assert!((src.len() & 1) == 0);
+ src.chunks_exact(2).enumerate().zip(dst.iter_mut()).try_for_each(|((si, s), d)| {
+ let r0 = DECODE_LUT[s[0] as usize];
+ let r1 = DECODE_LUT[s[1] as usize];
+ if (r0 | r1) >= 0 {
+ *d = ((r0 << 4) | r1) as u8;
+ Ok(())
+ } else {
+ Err(si * 2)
+ }
+ }).map_err(|bad_idx| raw_decode_err(bad_idx, src))
+}
+
+#[cold]
+#[inline(never)]
+fn raw_decode_err(idx: usize, src: &[u8]) -> usize {
+ let b0 = src[idx];
+ if decode_byte(b0).is_none() {
+ idx
+ } else {
+ idx + 1
+ }
+}
+
+/// Decode bytes from base16, and return a new `Vec<u8>` containing the results.
+///
+/// # Example
+///
+/// ```
+/// assert_eq!(&base16::decode("48656c6c6f20576f726c64".as_bytes()).unwrap(),
+/// b"Hello World");
+/// assert_eq!(&base16::decode(b"deadBEEF").unwrap(),
+/// &[0xde, 0xad, 0xbe, 0xef]);
+/// // Error cases:
+/// assert_eq!(base16::decode(b"Not Hexadecimal!"),
+/// Err(base16::DecodeError::InvalidByte { byte: b'N', index: 0 }));
+/// assert_eq!(base16::decode(b"a"),
+/// Err(base16::DecodeError::InvalidLength { length: 1 }));
+/// ```
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs to produce a Vec.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn decode<T: ?Sized + AsRef<[u8]>>(input: &T) -> Result<Vec<u8>, DecodeError> {
+ let src = input.as_ref();
+ if (src.len() & 1) != 0 {
+ return Err(invalid_length(src.len()));
+ }
+ let need_size = src.len() >> 1;
+ let mut dst = Vec::with_capacity(need_size);
+ unsafe { dst.set_len(need_size); }
+ match decode_slice_raw(src, &mut dst) {
+ Ok(()) => Ok(dst),
+ Err(index) => Err(invalid_byte(index, src))
+ }
+}
+
+
+/// Decode bytes from base16, and appends into the provided buffer. Only
+/// allocates if the buffer could not fit the data. Returns the number of bytes
+/// written.
+///
+/// In the case of an error, the buffer should remain the same size.
+///
+/// # Example
+///
+/// ```
+/// # extern crate core as std;
+/// # extern crate alloc;
+/// # use alloc::vec::Vec;
+/// let mut result = Vec::new();
+/// assert_eq!(base16::decode_buf(b"4d61646f6b61", &mut result).unwrap(), 6);
+/// assert_eq!(base16::decode_buf(b"486F6D757261", &mut result).unwrap(), 6);
+/// assert_eq!(std::str::from_utf8(&result).unwrap(), "MadokaHomura");
+/// ```
+/// # Availability
+///
+/// This function is only available when the `alloc` feature is enabled, as it
+/// needs to write to a Vec.
+#[cfg(feature = "alloc")]
+#[inline]
+pub fn decode_buf<T: ?Sized + AsRef<[u8]>>(input: &T, v: &mut Vec<u8>) -> Result<usize, DecodeError> {
+ let src = input.as_ref();
+ if (src.len() & 1) != 0 {
+ return Err(invalid_length(src.len()));
+ }
+ // Swap the vec out while we work on it, so that if we panic, we don't leave
+ // behind garbage (this will end up cleared if we panic, but that's better
+ // than UB)
+ let mut work = core::mem::replace(v, Vec::default());
+ let need_size = src.len() >> 1;
+ let current_size = unsafe {
+ grow_vec_uninitialized(&mut work, need_size)
+ };
+ match decode_slice_raw(src, &mut work[current_size..]) {
+ Ok(()) => {
+ // Swap back
+ core::mem::swap(v, &mut work);
+ Ok(need_size)
+ }
+ Err(index) => {
+ work.truncate(current_size);
+ // Swap back
+ core::mem::swap(v, &mut work);
+ Err(invalid_byte(index, src))
+ }
+ }
+}
+
+/// Decode bytes from base16, and write into the provided buffer. Never
+/// allocates.
+///
+/// In the case of a decoder error, the output is not specified, but in practice
+/// will remain untouched for an `InvalidLength` error, and will contain the
+/// decoded input up to the problem byte in the case of an InvalidByte error.
+///
+/// # Panics
+///
+/// Panics if the provided buffer is not large enough for the input.
+///
+/// # Example
+/// ```
+/// let msg = "476f6f642072757374206c6962726172696573207573652073696c6c79206578616d706c6573";
+/// let mut buf = [0u8; 1024];
+/// assert_eq!(base16::decode_slice(&msg[..], &mut buf).unwrap(), 38);
+/// assert_eq!(&buf[..38], b"Good rust libraries use silly examples".as_ref());
+///
+/// let msg2 = b"2E20416C736F2C20616E696D65207265666572656e636573";
+/// assert_eq!(base16::decode_slice(&msg2[..], &mut buf[38..]).unwrap(), 24);
+/// assert_eq!(&buf[38..62], b". Also, anime references".as_ref());
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn decode_slice<T: ?Sized + AsRef<[u8]>>(input: &T, out: &mut [u8]) -> Result<usize, DecodeError> {
+ let src = input.as_ref();
+ if (src.len() & 1) != 0 {
+ return Err(invalid_length(src.len()));
+ }
+ let need_size = src.len() >> 1;
+ if out.len() < need_size {
+ dest_too_small_dec(out.len(), need_size);
+ }
+ match decode_slice_raw(src, &mut out[..need_size]) {
+ Ok(()) => Ok(need_size),
+ Err(index) => Err(invalid_byte(index, src))
+ }
+}
+
+/// Decode a single character as hex.
+///
+/// Returns `None` for values outside the ASCII hex range.
+///
+/// # Example
+/// ```
+/// assert_eq!(base16::decode_byte(b'a'), Some(10));
+/// assert_eq!(base16::decode_byte(b'B'), Some(11));
+/// assert_eq!(base16::decode_byte(b'0'), Some(0));
+/// assert_eq!(base16::decode_byte(b'q'), None);
+/// assert_eq!(base16::decode_byte(b'x'), None);
+/// ```
+/// # Availability
+///
+/// This function is available whether or not the `alloc` feature is enabled.
+#[inline]
+pub fn decode_byte(c: u8) -> Option<u8> {
+ if c.wrapping_sub(b'0') <= 9 {
+ Some(c.wrapping_sub(b'0'))
+ } else if c.wrapping_sub(b'a') < 6 {
+ Some(c.wrapping_sub(b'a') + 10)
+ } else if c.wrapping_sub(b'A') < 6 {
+ Some(c.wrapping_sub(b'A') + 10)
+ } else {
+ None
+ }
+}
+static HEX_UPPER: [u8; 16] = *b"0123456789ABCDEF";
+static HEX_LOWER: [u8; 16] = *b"0123456789abcdef";
+static DECODE_LUT: [i8; 256] = [
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1
+];
+// Outlined assertions.
+#[inline(never)]
+#[cold]
+fn usize_overflow(len: usize) -> ! {
+ panic!("usize overflow when computing size of destination: {}", len);
+}
+
+#[cold]
+#[inline(never)]
+fn dest_too_small_enc(dst_len: usize, need_size: usize) -> ! {
+ panic!("Destination is not large enough to encode input: {} < {}", dst_len, need_size);
+}
+
+#[cold]
+#[inline(never)]
+fn dest_too_small_dec(dst_len: usize, need_size: usize) -> ! {
+ panic!("Destination buffer not large enough for decoded input {} < {}", dst_len, need_size);
+}
+
+// encoded_size smoke tests
+#[cfg(test)]
+mod tests {
+ use super::*;
+ #[test]
+ #[should_panic]
+ #[cfg(pointer_size )]
+ fn test_encoded_size_panic_top_bit() {
+ #[cfg(target_pointer_width = "64")]
+ let usz = 0x8000_0000_0000_0000usize;
+ #[cfg(target_pointer_width = "32")]
+ let usz = 0x8000_0000usize;
+ let _ = encoded_size(usz);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_encoded_size_panic_max() {
+ let _ = encoded_size(usize::max_value());
+ }
+
+ #[test]
+ fn test_encoded_size_allows_almost_max() {
+ #[cfg(target_pointer_width = "64")]
+ let usz = 0x7fff_ffff_ffff_ffffusize;
+ #[cfg(target_pointer_width = "32")]
+ let usz = 0x7fff_ffffusize;
+ assert_eq!(encoded_size(usz), usz * 2);
+ }
+}
diff --git a/third_party/rust/base16/tests/doctest_copies.rs b/third_party/rust/base16/tests/doctest_copies.rs
@@ -0,0 +1,135 @@
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+// Can't run doctests for a no_std crate if it uses allocator (e.g. can't run
+// them if we're using `alloc`), so we duplicate them here...
+// See https://github.com/rust-lang/rust/issues/54010
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_encode_lower() {
+ assert_eq!(base16::encode_lower(b"Hello World"), "48656c6c6f20576f726c64");
+ assert_eq!(base16::encode_lower(&[0xff, 0xcc, 0xaa]), "ffccaa");
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_encode_upper() {
+ assert_eq!(base16::encode_upper(b"Hello World"), "48656C6C6F20576F726C64");
+ assert_eq!(base16::encode_upper(&[0xff, 0xcc, 0xaa]), "FFCCAA");
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_encode_config() {
+ let data = [1, 2, 3, 0xaa, 0xbb, 0xcc];
+ assert_eq!(base16::encode_config(&data, base16::EncodeLower), "010203aabbcc");
+ assert_eq!(base16::encode_config(&data, base16::EncodeUpper), "010203AABBCC");
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_encode_config_buf() {
+ use alloc::string::String;
+ let messages = &["Taako, ", "Merle, ", "Magnus"];
+ let mut buffer = String::new();
+ for msg in messages {
+ let bytes_written = base16::encode_config_buf(msg.as_bytes(),
+ base16::EncodeUpper,
+ &mut buffer);
+ assert_eq!(bytes_written, msg.len() * 2);
+ }
+ assert_eq!(buffer, "5461616B6F2C204D65726C652C204D61676E7573");
+}
+
+#[test]
+fn test_encode_config_slice() {
+ // Writing to a statically sized buffer on the stack.
+ let message = b"Wu-Tang Killa Bees";
+ let mut buffer = [0u8; 1024];
+
+ let wrote = base16::encode_config_slice(message,
+ base16::EncodeLower,
+ &mut buffer);
+
+ assert_eq!(message.len() * 2, wrote);
+ assert_eq!(core::str::from_utf8(&buffer[..wrote]).unwrap(),
+ "57752d54616e67204b696c6c612042656573");
+
+ // Appending to an existing buffer is possible too.
+ let wrote2 = base16::encode_config_slice(b": The Swarm",
+ base16::EncodeLower,
+ &mut buffer[wrote..]);
+ let write_end = wrote + wrote2;
+ assert_eq!(core::str::from_utf8(&buffer[..write_end]).unwrap(),
+ "57752d54616e67204b696c6c6120426565733a2054686520537761726d");
+}
+
+#[test]
+fn test_encode_config_byte() {
+ assert_eq!(base16::encode_byte(0xff, base16::EncodeLower), [b'f', b'f']);
+ assert_eq!(base16::encode_byte(0xa0, base16::EncodeUpper), [b'A', b'0']);
+ assert_eq!(base16::encode_byte(3, base16::EncodeUpper), [b'0', b'3']);
+}
+
+#[test]
+fn test_encode_config_byte_l() {
+ assert_eq!(base16::encode_byte_l(0xff), [b'f', b'f']);
+ assert_eq!(base16::encode_byte_l(30), [b'1', b'e']);
+ assert_eq!(base16::encode_byte_l(0x2d), [b'2', b'd']);
+}
+
+#[test]
+fn test_encode_config_byte_u() {
+ assert_eq!(base16::encode_byte_u(0xff), [b'F', b'F']);
+ assert_eq!(base16::encode_byte_u(30), [b'1', b'E']);
+ assert_eq!(base16::encode_byte_u(0x2d), [b'2', b'D']);
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_decode() {
+ assert_eq!(&base16::decode("48656c6c6f20576f726c64".as_bytes()).unwrap(),
+ b"Hello World");
+ assert_eq!(&base16::decode(b"deadBEEF").unwrap(),
+ &[0xde, 0xad, 0xbe, 0xef]);
+ // Error cases:
+ assert_eq!(base16::decode(b"Not Hexadecimal!"),
+ Err(base16::DecodeError::InvalidByte { byte: b'N', index: 0 }));
+ assert_eq!(base16::decode(b"a"),
+ Err(base16::DecodeError::InvalidLength { length: 1 }));
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_decode_buf() {
+ use alloc::vec::Vec;
+ let mut result = Vec::new();
+ assert_eq!(base16::decode_buf(b"4d61646f6b61", &mut result).unwrap(), 6);
+ assert_eq!(base16::decode_buf(b"486F6D757261", &mut result).unwrap(), 6);
+ assert_eq!(core::str::from_utf8(&result).unwrap(), "MadokaHomura");
+}
+
+#[test]
+fn test_decode_slice() {
+ let msg = "476f6f642072757374206c6962726172696573207573652073696c6c79206578616d706c6573";
+ let mut buf = [0u8; 1024];
+ assert_eq!(base16::decode_slice(&msg[..], &mut buf).unwrap(), 38);
+ assert_eq!(&buf[..38], b"Good rust libraries use silly examples".as_ref());
+
+ let msg2 = b"2E20416C736F2C20616E696D65207265666572656e636573";
+ assert_eq!(base16::decode_slice(&msg2[..], &mut buf[38..]).unwrap(), 24);
+ assert_eq!(&buf[38..62], b". Also, anime references".as_ref());
+}
+
+#[test]
+fn test_decode_byte() {
+ assert_eq!(base16::decode_byte(b'a'), Some(10));
+ assert_eq!(base16::decode_byte(b'B'), Some(11));
+ assert_eq!(base16::decode_byte(b'0'), Some(0));
+ assert_eq!(base16::decode_byte(b'q'), None);
+ assert_eq!(base16::decode_byte(b'x'), None);
+}
diff --git a/third_party/rust/base16/tests/tests.rs b/third_party/rust/base16/tests/tests.rs
@@ -0,0 +1,169 @@
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "alloc")]
+#[macro_use]
+extern crate alloc;
+
+use base16::*;
+
+const ALL_LOWER: &[&str] = &[
+ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b",
+ "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17",
+ "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23",
+ "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b",
+ "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47",
+ "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53",
+ "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b",
+ "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77",
+ "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83",
+ "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b",
+ "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+ "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3",
+ "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
+ "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb",
+ "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+ "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3",
+ "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb",
+ "fc", "fd", "fe", "ff",
+];
+
+const ALL_UPPER: &[&str] = &[
+ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B",
+ "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17",
+ "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23",
+ "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B",
+ "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47",
+ "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53",
+ "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B",
+ "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77",
+ "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83",
+ "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B",
+ "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+ "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3",
+ "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
+ "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB",
+ "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+ "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3",
+ "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
+ "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB",
+ "FC", "FD", "FE", "FF",
+];
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_exhaustive_bytes_encode() {
+ for i in 0..256 {
+ assert_eq!(&encode_lower(&[i as u8]), ALL_LOWER[i]);
+ assert_eq!(&encode_upper(&[i as u8]), ALL_UPPER[i]);
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_exhaustive_bytes_decode() {
+ for i in 0..16 {
+ for j in 0..16 {
+ let all_cases = format!("{0:x}{1:x}{0:x}{1:X}{0:X}{1:x}{0:X}{1:X}", i, j);
+ let byte = i * 16 + j;
+ let expect = &[byte, byte, byte, byte];
+ assert_eq!(&decode(&all_cases).unwrap(), expect,
+ "Failed for {}", all_cases);
+ }
+ }
+ for b in 0..256 {
+ let i = b as u8;
+ let expected = match i {
+ b'0' | b'1' | b'2' | b'3' | b'4' | b'5' | b'6' | b'7' | b'8' | b'9' => Ok(vec![i - b'0']),
+ b'a' | b'b' | b'c' | b'd' | b'e' | b'f' => Ok(vec![i - b'a' + 10]),
+ b'A' | b'B' | b'C' | b'D' | b'E' | b'F' => Ok(vec![i - b'A' + 10]),
+ _ => Err(DecodeError::InvalidByte { byte: i, index: 1 })
+ };
+ assert_eq!(decode(&[b'0', i]), expected);
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn test_decode_errors() {
+ let mut buf = decode(b"686f6d61646f6b61").unwrap();
+ let orig = buf.clone();
+
+ assert_eq!(buf.len(), 8);
+
+ assert_eq!(decode_buf(b"abc", &mut buf),
+ Err(DecodeError::InvalidLength { length: 3 }));
+ assert_eq!(buf, orig);
+
+ assert_eq!(decode_buf(b"6d61646f686f6d75g_", &mut buf),
+ Err(DecodeError::InvalidByte { byte: b'g', index: 16 }));
+ assert_eq!(buf, orig);
+}
+
+#[test]
+#[should_panic]
+fn test_panic_slice_encode() {
+ let mut slice = [0u8; 8];
+ encode_config_slice(b"Yuasa", EncodeLower, &mut slice);
+}
+
+#[test]
+#[should_panic]
+fn test_panic_slice_decode() {
+ let mut slice = [0u8; 32];
+ let input = b"4920646f6e277420636172652074686174206d7563682061626f757420504d4d4d20544248";
+ let _ignore = decode_slice(&input[..], &mut slice);
+}
+
+#[test]
+fn test_enc_slice_exact_fit() {
+ let mut slice = [0u8; 12];
+ let res = encode_config_slice(b"abcdef", EncodeLower, &mut slice);
+ assert_eq!(res, 12);
+ assert_eq!(&slice, b"616263646566")
+}
+
+#[test]
+fn test_exhaustive_encode_byte() {
+ for i in 0..256 {
+ let byte = i as u8;
+ let su = ALL_UPPER[byte as usize].as_bytes();
+ let sl = ALL_LOWER[byte as usize].as_bytes();
+ let tu = encode_byte(byte, EncodeUpper);
+ let tl = encode_byte(byte, EncodeLower);
+
+ assert_eq!(tu[0], su[0]);
+ assert_eq!(tu[1], su[1]);
+
+ assert_eq!(tl[0], sl[0]);
+ assert_eq!(tl[1], sl[1]);
+
+ assert_eq!(tu, encode_byte_u(byte));
+ assert_eq!(tl, encode_byte_l(byte));
+ }
+}
+
+const HEX_TO_VALUE: &[(u8, u8)] = &[
+ (b'0', 0x0), (b'1', 0x1), (b'2', 0x2), (b'3', 0x3), (b'4', 0x4),
+ (b'5', 0x5), (b'6', 0x6), (b'7', 0x7), (b'8', 0x8), (b'9', 0x9),
+ (b'a', 0xa), (b'b', 0xb), (b'c', 0xc), (b'd', 0xd), (b'e', 0xe), (b'f', 0xf),
+ (b'A', 0xA), (b'B', 0xB), (b'C', 0xC), (b'D', 0xD), (b'E', 0xE), (b'F', 0xF),
+];
+
+#[test]
+fn test_exhaustive_decode_byte() {
+ let mut expected = [None::<u8>; 256];
+ for &(k, v) in HEX_TO_VALUE {
+ expected[k as usize] = Some(v);
+ }
+ for i in 0..256 {
+ assert_eq!(decode_byte(i as u8), expected[i]);
+ }
+}
diff --git a/third_party/rust/hawk/.cargo-checksum.json b/third_party/rust/hawk/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"2c917c2285781054146c5ce672f2cc8f6c82a87975e6ebe2318dbc9f94e3436c","CODE_OF_CONDUCT.md":"902d5357af363426631d907e641e220b3ec89039164743f8442b3f120479b7cf","CONTRIBUTING.md":"2f395c6bff5805ada946b38d407bedea743230c845fd69cbd004da36871b9580","Cargo.toml":"1f22ec3a611f4fbe52eb851cdaab8ff28b1a6f98718364a68150809d421954c7","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"43f86b667ba065459d185ec47e5a48f943ce6dfe04dc02e1cfff0baf58714243","build.rs":"ae11c573f1edf605d7a6dc740e48f2af9ec0a8c0578bf5d381d52126582fb67e","clippy.toml":"20c46fb795c2ef5317874716faa5c8ddc1ff076f3028c85c38dc560d71347ee5","src/b64.rs":"d23d82df26f8718a58c6c9f7f79d0a7391fd0df6c102639c20941b10213c84d4","src/bewit.rs":"fc91415bd87b7d62cd39597b2d5499b4c6c4f0458cb0ca94954534659bd882df","src/credentials.rs":"6c727d846161216b2c333a843f17f8965c664cbb3ed7ff4b14eb89fb614cac59","src/crypto/holder.rs":"c0ad1269bb9b98a9f1abc17453813cc2983e958d7d3c0c95943ce74580c9fe97","src/crypto/mod.rs":"0df4f7d1e7f81553c99c31a994949e8d88ad7c4486b5f9279c486c0887e0c8ab","src/crypto/openssl.rs":"ced672fd59b70912095a718f112e4c02f63caf006680aa0db2f79306781d0cc9","src/crypto/ring.rs":"363c9bbb4269e40c160ff2d70d7232f7f4e0e29c717ca5b07c9c40dd5306ef76","src/error.rs":"7349b04c8a7a9faa818f14af05a877599126ca747669aae8f8f959319c818381","src/header.rs":"ff57d3b925187e877db408ca3c7f642142ceec89cbd7dd706897c35667674c68","src/lib.rs":"cd33cd4922732060b7bc2f1ae3a96a81a78452e0db4b2e47ac54ba949ff8e87c","src/mac.rs":"a81fbb90a0ea93fba9d167f0382a1e2541cfc8bc4cef0e1f588ed57c522f5b2f","src/payload.rs":"fb70b564296050ff3e86d9199f0c5f2a02ebde5ca9770a95a5d174a9c2409d7b","src/request.rs":"8e565c2b0b41dac4330cd462e19763d905bd29dcfdf27f3f9eb39820bba26104","src/response.rs":"d74318c3b6e9ea5570cb099d5874c085500366cdc75ba154df2cf1f28a10223c"},"package":"ab302457b3e28e621daab18932d67a67328f29240bfaa5f604b7627ece1eacda"}
+\ No newline at end of file
diff --git a/third_party/rust/hawk/CHANGELOG.md b/third_party/rust/hawk/CHANGELOG.md
@@ -0,0 +1,45 @@
+# Changelog
+
+## v5.0.1
+
+- `base64` upgraded to 0.22
+
+## v5.0.0
+
+- `ring` upgraded to 0.17.0
+- `base64` upgraded
+- Support Rust 2021 edition
+
+## v4.0.0
+
+- Hide base64::DecodeError
+
+## v3.0.0
+
+- The cryptography library used is now configurable.
+ - By default `ring` is used (the `use_ring` feature).
+ - You can use the `use_openssl` feature to use openssl instead
+ - e.g. in your Cargo.toml:
+ ```toml
+ [dependencies.hawk]
+ version = "..."
+ features = ["use_openssl"]
+ default-features = false
+ ```
+ - You can use neither and provide your own implementation using the functions in
+ `hawk::crypto` if neither feature is enabled.
+ - Note that enabling both `use_ring` and `use_openssl` will cause a build
+ failure.
+
+- BREAKING: Many functions that previously returned `T` now return `hawk::Result<T>`.
+ - Specifically, `PayloadHasher::{hash,update,finish}`, `Key::{new,sign}`.
+
+- BREAKING: `hawk::SHA{256,384,512}` are now `const` `DigestAlgorithm`s and not
+ aliases for `ring::Algorithm`
+
+- BREAKING: `Key::new` now takes a `DigestAlgorithm` and not a
+ `&'static ring::Algorithm`.
+ - If you were passing e.g. `&hawk::SHA256`, you probably just need
+ to pass `hawk::SHA256` now instead.
+
+- BREAKING (though unlikely): `Error::Rng` has been removed, and `Error::Crypto` added
diff --git a/third_party/rust/hawk/CODE_OF_CONDUCT.md b/third_party/rust/hawk/CODE_OF_CONDUCT.md
@@ -0,0 +1,15 @@
+# Community Participation Guidelines
+
+This repository is governed by Mozilla's code of conduct and etiquette guidelines.
+For more details, please read the
+[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
+
+## How to Report
+For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
+
+<!--
+## Project Specific Etiquette
+
+In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
+Please update for your project.
+-->
diff --git a/third_party/rust/hawk/CONTRIBUTING.md b/third_party/rust/hawk/CONTRIBUTING.md
@@ -0,0 +1,28 @@
+# How to Contribute
+
+We welcome pull requests from everyone. We do expect everyone to adhere to the [Mozilla Community Participation Guidelines][participation].
+
+If you're trying to figure out what to work on, here are some places to find suitable projects:
+* [Good first bugs][goodfirstbug]: these are scoped to make it easy for first-time contributors to get their feet wet with Taskcluster code.
+* [Mentored bugs][bugsahoy]: these are slightly more involved projects that may require insight or guidance from someone on the Taskcluster team.
+* [Full list of open issues][issues]: everything else
+
+If the project you're interested in working on isn't covered by a bug or issue, or you're unsure about how to proceed on an existing issue, it's a good idea to talk to someone on the Taskcluster team before you go too far down a particular path. You can find us in the #taskcluster channel on [Mozilla's IRC server][irc] to discuss. You can also simply add a comment to the issue or bug.
+
+Once you've found an issue to work on and written a patch, submit a pull request. Some things that will increase the chance that your pull request is accepted:
+
+* Follow our [best practices][bestpractices].
+* This includes [writing or updating tests][testing].
+* Write a [good commit message][commit].
+
+Welcome to the team!
+
+[participation]: https://www.mozilla.org/en-US/about/governance/policies/participation/
+[issues]: ../../issues
+[bugsahoy]: https://www.joshmatthews.net/bugsahoy/?taskcluster=1
+[goodfirstbug]: http://www.joshmatthews.net/bugsahoy/?taskcluster=1&simple=1
+[irc]: https://wiki.mozilla.org/IRC
+[bestpractices]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices
+[testing]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices/testing
+[commit]: https://docs.taskcluster.net/docs/manual/design/devel/best-practices/commits
+
diff --git a/third_party/rust/hawk/Cargo.toml b/third_party/rust/hawk/Cargo.toml
@@ -0,0 +1,65 @@
+# 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 = "hawk"
+version = "5.0.1"
+authors = [
+ "Jonas Finnemann Jensen <jopsen@gmail.com>",
+ "Dustin J. Mitchell <dustin@mozilla.com>",
+]
+build = "build.rs"
+exclude = [
+ "docker/*",
+ ".taskcluster.yml",
+ ".git*",
+]
+description = "Hawk Implementation for Rust"
+homepage = "https://docs.rs/hawk/"
+documentation = "https://docs.rs/hawk/"
+readme = "README.md"
+license = "MPL-2.0"
+repository = "https://github.com/taskcluster/rust-hawk"
+
+[dependencies.anyhow]
+version = "1.0"
+
+[dependencies.base64]
+version = "0.22"
+
+[dependencies.log]
+version = "0.4"
+
+[dependencies.once_cell]
+version = "1.4"
+
+[dependencies.openssl]
+version = "0.10.20"
+optional = true
+
+[dependencies.ring]
+version = "0.17.0"
+optional = true
+
+[dependencies.thiserror]
+version = "1.0"
+
+[dependencies.url]
+version = "2.1"
+
+[dev-dependencies.pretty_assertions]
+version = "^1.0.0"
+
+[features]
+default = ["use_ring"]
+use_openssl = ["openssl"]
+use_ring = ["ring"]
diff --git a/third_party/rust/hawk/LICENSE b/third_party/rust/hawk/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ 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/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/third_party/rust/hawk/README.md b/third_party/rust/hawk/README.md
@@ -0,0 +1,4 @@
+Hawk Authentication for Rust
+============================
+
+This is a Rust implementation of [Hawk](https://github.com/hueniverse/hawk).
diff --git a/third_party/rust/hawk/build.rs b/third_party/rust/hawk/build.rs
@@ -0,0 +1,7 @@
+// Just check that we aren't asked to use an impossible configuration.
+fn main() {
+ assert!(
+ !(cfg!(feature = "use_ring") && cfg!(feature = "use_openssl")),
+ "Cannot configure `hawk` with both `use_ring` and `use_openssl`!"
+ );
+}
diff --git a/third_party/rust/hawk/clippy.toml b/third_party/rust/hawk/clippy.toml
@@ -0,0 +1,2 @@
+# hawk headers have a lot of fields, and we pass them positionally..
+too-many-arguments-threshold = 15
diff --git a/third_party/rust/hawk/src/b64.rs b/third_party/rust/hawk/src/b64.rs
@@ -0,0 +1,19 @@
+//! This module contains basic base64 functionality as used in Hawk.
+
+use base64::engine::{
+ general_purpose::{GeneralPurpose, GeneralPurposeConfig},
+ DecodePaddingMode,
+};
+
+/// BEWIT_ENGINE encodes to a url-safe value with no padding, but is indifferent to padding on
+/// decode. This is used to encode bewits, which often appear in URLs.
+pub(crate) const BEWIT_ENGINE: GeneralPurpose = GeneralPurpose::new(
+ &base64::alphabet::URL_SAFE,
+ GeneralPurposeConfig::new()
+ .with_encode_padding(false)
+ .with_decode_padding_mode(DecodePaddingMode::Indifferent),
+);
+
+/// STANDARD_ENGINE encodes with the standard alphabet and includes padding. This is
+/// used to encode MACs and hashes.
+pub(crate) const STANDARD_ENGINE: GeneralPurpose = base64::engine::general_purpose::STANDARD;
diff --git a/third_party/rust/hawk/src/bewit.rs b/third_party/rust/hawk/src/bewit.rs
@@ -0,0 +1,216 @@
+use crate::b64;
+use crate::error::*;
+use crate::mac::Mac;
+use base64::Engine;
+use std::borrow::Cow;
+use std::str;
+use std::str::FromStr;
+use std::time::{Duration, SystemTime, UNIX_EPOCH};
+
+/// A Bewit is a piece of data attached to a GET request that functions in place of a Hawk
+/// Authentication header. It contains an id, a timestamp, a MAC, and an optional `ext` value.
+/// These are available using accessor functions.
+#[derive(Clone, Debug, PartialEq)]
+pub struct Bewit<'a> {
+ id: Cow<'a, str>,
+ exp: SystemTime,
+ mac: Cow<'a, Mac>,
+ ext: Option<Cow<'a, str>>,
+}
+
+impl<'a> Bewit<'a> {
+ /// Create a new Bewit with the given values.
+ ///
+ /// See Request.make_bewit for an easier way to make a Bewit
+ pub fn new(id: &'a str, exp: SystemTime, mac: Mac, ext: Option<&'a str>) -> Bewit<'a> {
+ Bewit {
+ id: Cow::Borrowed(id),
+ exp,
+ mac: Cow::Owned(mac),
+ ext: ext.map(Cow::Borrowed),
+ }
+ }
+
+ /// Generate the fully-encoded string for this Bewit
+ pub fn to_str(&self) -> String {
+ let raw = format!(
+ "{}\\{}\\{}\\{}",
+ self.id,
+ self.exp
+ .duration_since(UNIX_EPOCH)
+ .unwrap_or_default()
+ .as_secs(),
+ b64::STANDARD_ENGINE.encode(self.mac.as_ref()),
+ match self.ext {
+ Some(ref cow) => cow.as_ref(),
+ None => "",
+ }
+ );
+
+ b64::BEWIT_ENGINE.encode(raw)
+ }
+
+ /// Get the Bewit's client identifier
+ pub fn id(&self) -> &str {
+ self.id.as_ref()
+ }
+
+ /// Get the expiration time of the bewit
+ pub fn exp(&self) -> SystemTime {
+ self.exp
+ }
+
+ /// Get the MAC included in the Bewit
+ pub fn mac(&self) -> &Mac {
+ self.mac.as_ref()
+ }
+
+ /// Get the Bewit's `ext` field.
+ pub fn ext(&self) -> Option<&str> {
+ match self.ext {
+ Some(ref cow) => Some(cow.as_ref()),
+ None => None,
+ }
+ }
+}
+
+const BACKSLASH: u8 = b'\\';
+
+impl<'a> FromStr for Bewit<'a> {
+ type Err = Error;
+ fn from_str(bewit: &str) -> Result<Bewit<'a>> {
+ let bewit = b64::BEWIT_ENGINE
+ .decode(bewit)
+ .map_err(Error::from_base64_error)?;
+
+ let parts: Vec<&[u8]> = bewit.split(|c| *c == BACKSLASH).collect();
+ if parts.len() != 4 {
+ return Err(InvalidBewit::Format.into());
+ }
+
+ let id = String::from_utf8(parts[0].to_vec()).map_err(|_| InvalidBewit::Id)?;
+
+ let exp = str::from_utf8(parts[1]).map_err(|_| InvalidBewit::Exp)?;
+ let exp = u64::from_str(exp).map_err(|_| InvalidBewit::Exp)?;
+ let exp = UNIX_EPOCH + Duration::new(exp, 0);
+
+ let mac = str::from_utf8(parts[2]).map_err(|_| InvalidBewit::Mac)?;
+ let mac = Mac::from(
+ b64::STANDARD_ENGINE
+ .decode(mac)
+ .map_err(|_| InvalidBewit::Mac)?,
+ );
+
+ let ext = match parts[3].len() {
+ 0 => None,
+ _ => Some(Cow::Owned(
+ String::from_utf8(parts[3].to_vec()).map_err(|_| InvalidBewit::Ext)?,
+ )),
+ };
+
+ Ok(Bewit {
+ id: Cow::Owned(id),
+ exp,
+ mac: Cow::Owned(mac),
+ ext,
+ })
+ }
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod test {
+ use super::*;
+ use crate::credentials::Key;
+ use crate::mac::{Mac, MacType};
+ use std::str::FromStr;
+
+ const BEWIT_STR: &str =
+ "bWVcMTM1MzgzMjgzNFxmaXk0ZTV3QmRhcEROeEhIZUExOE5yU3JVMVUzaVM2NmdtMFhqVEpwWXlVPVw";
+ const BEWIT_WITH_EXT_STR: &str =
+ "bWVcMTM1MzgzMjgzNFxmaXk0ZTV3QmRhcEROeEhIZUExOE5yU3JVMVUzaVM2NmdtMFhqVEpwWXlVPVxhYmNk";
+
+ fn make_mac() -> Mac {
+ let key = Key::new(
+ vec![
+ 11u8, 19, 228, 209, 79, 189, 200, 59, 166, 47, 86, 254, 235, 184, 120, 197, 75,
+ 152, 201, 79, 115, 61, 111, 242, 219, 187, 173, 14, 227, 108, 60, 232,
+ ],
+ crate::DigestAlgorithm::Sha256,
+ )
+ .unwrap();
+ Mac::new(
+ MacType::Header,
+ &key,
+ UNIX_EPOCH + Duration::new(1353832834, 100),
+ "nonny",
+ "POST",
+ "mysite.com",
+ 443,
+ "/v1/api",
+ None,
+ None,
+ )
+ .unwrap()
+ }
+
+ #[test]
+ fn test_to_str() {
+ let bewit = Bewit::new(
+ "me",
+ UNIX_EPOCH + Duration::new(1353832834, 0),
+ make_mac(),
+ None,
+ );
+ assert_eq!(bewit.to_str(), BEWIT_STR);
+ let bewit = Bewit::new(
+ "me",
+ UNIX_EPOCH + Duration::new(1353832834, 0),
+ make_mac(),
+ Some("abcd"),
+ );
+ assert_eq!(bewit.to_str(), BEWIT_WITH_EXT_STR);
+ }
+
+ #[test]
+ fn test_accessors() {
+ let bewit = Bewit::from_str(BEWIT_STR).unwrap();
+ assert_eq!(bewit.id(), "me");
+ assert_eq!(bewit.exp(), UNIX_EPOCH + Duration::new(1353832834, 0));
+ assert_eq!(bewit.mac(), &make_mac());
+ assert_eq!(bewit.ext(), None);
+ }
+
+ #[test]
+ fn test_from_str_invalid_base64() {
+ assert!(Bewit::from_str("!/==").is_err());
+ }
+
+ #[test]
+ fn test_from_str_invalid_too_many_parts() {
+ let bewit = b64::BEWIT_ENGINE.encode("a\\123\\abc\\ext\\WHUT?".as_bytes());
+ assert!(Bewit::from_str(&bewit).is_err());
+ }
+
+ #[test]
+ fn test_from_str_invalid_too_few_parts() {
+ let bewit = b64::BEWIT_ENGINE.encode("a\\123\\abc".as_bytes());
+ assert!(Bewit::from_str(&bewit).is_err());
+ }
+
+ #[test]
+ fn test_from_str_invalid_not_utf8() {
+ let a = b'a';
+ let one = b'1';
+ let slash = b'\\';
+ let invalid1 = 0u8;
+ let invalid2 = 159u8;
+ let bewit = b64::BEWIT_ENGINE.encode([invalid1, invalid2, slash, one, slash, a, slash, a]);
+ assert!(Bewit::from_str(&bewit).is_err());
+ let bewit = b64::BEWIT_ENGINE.encode([a, slash, invalid1, invalid2, slash, a, slash, a]);
+ assert!(Bewit::from_str(&bewit).is_err());
+ let bewit = b64::BEWIT_ENGINE.encode([a, slash, one, slash, invalid1, invalid2, slash, a]);
+ assert!(Bewit::from_str(&bewit).is_err());
+ let bewit = b64::BEWIT_ENGINE.encode([a, slash, one, slash, a, slash, invalid1, invalid2]);
+ assert!(Bewit::from_str(&bewit).is_err());
+ }
+}
diff --git a/third_party/rust/hawk/src/credentials.rs b/third_party/rust/hawk/src/credentials.rs
@@ -0,0 +1,56 @@
+use crate::crypto::{self, HmacKey};
+
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
+#[non_exhaustive]
+pub enum DigestAlgorithm {
+ Sha256,
+ Sha384,
+ Sha512,
+}
+
+/// Hawk key.
+///
+/// While any sequence of bytes can be specified as a key, note that each digest algorithm has
+/// a suggested key length, and that passwords should *not* be used as keys. Keys of incorrect
+/// length are handled according to the digest's implementation.
+pub struct Key(Box<dyn HmacKey>);
+
+impl Key {
+ pub fn new<B>(key: B, algorithm: DigestAlgorithm) -> crate::Result<Key>
+ where
+ B: AsRef<[u8]>,
+ {
+ Ok(Key(crypto::new_key(algorithm, key.as_ref())?))
+ }
+
+ pub fn sign(&self, data: &[u8]) -> crate::Result<Vec<u8>> {
+ Ok(self.0.sign(data)?)
+ }
+}
+
+/// Hawk credentials: an ID and a key associated with that ID. The digest algorithm
+/// must be agreed between the server and the client, and the length of the key is
+/// specific to that algorithm.
+pub struct Credentials {
+ pub id: String,
+ pub key: Key,
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_new_sha256() {
+ let key = vec![77u8; 32];
+ // hmac::SigningKey doesn't allow any visibilty inside, so we just build the
+ // key and assume it works..
+ Key::new(key, DigestAlgorithm::Sha256).unwrap();
+ }
+
+ #[test]
+ fn test_new_sha256_bad_length() {
+ let key = vec![0u8; 99];
+ Key::new(key, DigestAlgorithm::Sha256).unwrap();
+ }
+}
diff --git a/third_party/rust/hawk/src/crypto/holder.rs b/third_party/rust/hawk/src/crypto/holder.rs
@@ -0,0 +1,52 @@
+use super::Cryptographer;
+use once_cell::sync::OnceCell;
+
+static CRYPTOGRAPHER: OnceCell<&'static dyn Cryptographer> = OnceCell::new();
+
+#[derive(Debug, thiserror::Error)]
+#[error("Cryptographer already initialized")]
+pub struct SetCryptographerError(());
+
+/// Sets the global object that will be used for cryptographic operations.
+///
+/// This is a convenience wrapper over [`set_cryptographer`],
+/// but takes a `Box<dyn Cryptographer>` instead.
+#[cfg(not(any(feature = "use_ring", feature = "use_openssl")))]
+pub fn set_boxed_cryptographer(c: Box<dyn Cryptographer>) -> Result<(), SetCryptographerError> {
+ // Just leak the Box. It wouldn't be freed as a `static` anyway, and we
+ // never allow this to be re-assigned (so it's not a meaningful memory leak).
+ set_cryptographer(Box::leak(c))
+}
+
+/// Sets the global object that will be used for cryptographic operations.
+///
+/// This function may only be called once in the lifetime of a program.
+///
+/// Any calls into this crate that perform cryptography prior to calling this
+/// function will panic.
+pub fn set_cryptographer(c: &'static dyn Cryptographer) -> Result<(), SetCryptographerError> {
+ CRYPTOGRAPHER.set(c).map_err(|_| SetCryptographerError(()))
+}
+
+pub(crate) fn get_crypographer() -> &'static dyn Cryptographer {
+ autoinit_crypto();
+ *CRYPTOGRAPHER
+ .get()
+ .expect("`hawk` cryptographer not initialized!")
+}
+
+#[cfg(feature = "use_ring")]
+#[inline]
+fn autoinit_crypto() {
+ let _ = set_cryptographer(&super::ring::RingCryptographer);
+}
+
+#[cfg(feature = "use_openssl")]
+#[inline]
+fn autoinit_crypto() {
+ let _ = set_cryptographer(&super::openssl::OpensslCryptographer);
+}
+
+#[cfg(not(any(feature = "use_openssl", feature = "use_ring")))]
+#[inline]
+fn autoinit_crypto() {}
diff --git a/third_party/rust/hawk/src/crypto/mod.rs b/third_party/rust/hawk/src/crypto/mod.rs
@@ -0,0 +1,83 @@
+//! `hawk` must perform certain cryptographic operations in order to function,
+//! and applications may need control over which library is used for these.
+//!
+//! This module can be used for that purpose. If you do not care, this crate can
+//! be configured so that a default implementation is provided based on either
+//! `ring` or `openssl` (via the `use_ring` and `use_openssl` features respectively).
+//!
+//! Should you need something custom, then you can provide it by implementing
+//! [`Cryptographer`] and using the [`set_cryptographer`] or
+//! [`set_boxed_cryptographer`] functions.
+use crate::DigestAlgorithm;
+
+pub(crate) mod holder;
+pub(crate) use holder::get_crypographer;
+
+#[cfg(feature = "use_openssl")]
+mod openssl;
+#[cfg(feature = "use_ring")]
+mod ring;
+
+#[cfg(not(any(feature = "use_ring", feature = "use_openssl")))]
+pub use self::holder::{set_boxed_cryptographer, set_cryptographer};
+
+#[derive(Debug, thiserror::Error)]
+pub enum CryptoError {
+ /// The configured cryptographer does not support the digest algorithm
+ /// specified. This should only happen for custom `Cryptographer` implementations
+ #[error("Digest algorithm {0:?} is unsupported by this Cryptographer")]
+ UnsupportedDigest(DigestAlgorithm),
+
+ /// The configured cryptographer implementation failed to perform an
+ /// operation in some way.
+ #[error("{0}")]
+ Other(#[source] anyhow::Error),
+}
+
+/// A trait encapsulating the cryptographic operations required by this library.
+///
+/// If you use this library with either the `use_ring` or `use_openssl` features enabled,
+/// then you do not have to worry about this.
+pub trait Cryptographer: Send + Sync + 'static {
+ fn rand_bytes(&self, output: &mut [u8]) -> Result<(), CryptoError>;
+ fn new_key(
+ &self,
+ algorithm: DigestAlgorithm,
+ key: &[u8],
+ ) -> Result<Box<dyn HmacKey>, CryptoError>;
+ fn new_hasher(&self, algo: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError>;
+ fn constant_time_compare(&self, a: &[u8], b: &[u8]) -> bool;
+}
+
+/// Type-erased hmac key type.
+pub trait HmacKey: Send + Sync + 'static {
+ fn sign(&self, data: &[u8]) -> Result<Vec<u8>, CryptoError>;
+}
+
+/// Type-erased hash context type.
+pub trait Hasher: Send + Sync + 'static {
+ fn update(&mut self, data: &[u8]) -> Result<(), CryptoError>;
+ // Note: this would take by move but that's not object safe :(
+ fn finish(&mut self) -> Result<Vec<u8>, CryptoError>;
+}
+
+// For convenience
+
+pub(crate) fn rand_bytes(buffer: &mut [u8]) -> Result<(), CryptoError> {
+ get_crypographer().rand_bytes(buffer)
+}
+
+pub(crate) fn new_key(
+ algorithm: DigestAlgorithm,
+ key: &[u8],
+) -> Result<Box<dyn HmacKey>, CryptoError> {
+ get_crypographer().new_key(algorithm, key)
+}
+
+pub(crate) fn constant_time_compare(a: &[u8], b: &[u8]) -> bool {
+ get_crypographer().constant_time_compare(a, b)
+}
+
+pub(crate) fn new_hasher(algorithm: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError> {
+ get_crypographer().new_hasher(algorithm)
+}
diff --git a/third_party/rust/hawk/src/crypto/openssl.rs b/third_party/rust/hawk/src/crypto/openssl.rs
@@ -0,0 +1,98 @@
+use super::{CryptoError, Cryptographer, Hasher, HmacKey};
+use crate::DigestAlgorithm;
+use std::convert::{TryFrom, TryInto};
+
+use openssl::error::ErrorStack;
+use openssl::hash::MessageDigest;
+use openssl::pkey::{PKey, Private};
+use openssl::sign::Signer;
+
+impl From<ErrorStack> for CryptoError {
+ fn from(e: ErrorStack) -> Self {
+ CryptoError::Other(e.into())
+ }
+}
+
+pub struct OpensslCryptographer;
+
+struct OpensslHmacKey {
+ key: PKey<Private>,
+ digest: MessageDigest,
+}
+
+impl HmacKey for OpensslHmacKey {
+ fn sign(&self, data: &[u8]) -> Result<Vec<u8>, CryptoError> {
+ let mut hmac_signer = Signer::new(self.digest, &self.key)?;
+ hmac_signer.update(&data)?;
+ let digest = hmac_signer.sign_to_vec()?;
+ let mut mac = vec![0; self.digest.size()];
+ mac.clone_from_slice(digest.as_ref());
+ Ok(mac)
+ }
+}
+
+// This is always `Some` until `finish` is called.
+struct OpensslHasher(Option<openssl::hash::Hasher>);
+
+impl Hasher for OpensslHasher {
+ fn update(&mut self, data: &[u8]) -> Result<(), CryptoError> {
+ self.0
+ .as_mut()
+ .expect("update called after `finish`")
+ .update(data)?;
+ Ok(())
+ }
+
+ fn finish(&mut self) -> Result<Vec<u8>, CryptoError> {
+ let digest = self.0.take().expect("`finish` called twice").finish()?;
+ let bytes: &[u8] = digest.as_ref();
+ Ok(bytes.to_owned())
+ }
+}
+
+impl Cryptographer for OpensslCryptographer {
+ fn rand_bytes(&self, output: &mut [u8]) -> Result<(), CryptoError> {
+ openssl::rand::rand_bytes(output)?;
+ Ok(())
+ }
+
+ fn new_key(
+ &self,
+ algorithm: DigestAlgorithm,
+ key: &[u8],
+ ) -> Result<Box<dyn HmacKey>, CryptoError> {
+ let digest = algorithm.try_into()?;
+ Ok(Box::new(OpensslHmacKey {
+ key: PKey::hmac(key)?,
+ digest,
+ }))
+ }
+
+ fn constant_time_compare(&self, a: &[u8], b: &[u8]) -> bool {
+ // openssl::memcmp::eq panics if the lengths are not the same. ring
+ // returns `Err` (and notes in the docs that it is not constant time if
+ // the lengths are not the same). We make this behave like ring.
+ if a.len() != b.len() {
+ false
+ } else {
+ openssl::memcmp::eq(a, b)
+ }
+ }
+
+ fn new_hasher(&self, algorithm: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError> {
+ let ctx = openssl::hash::Hasher::new(algorithm.try_into()?)?;
+ Ok(Box::new(OpensslHasher(Some(ctx))))
+ }
+}
+
+impl TryFrom<DigestAlgorithm> for MessageDigest {
+ type Error = CryptoError;
+ fn try_from(algorithm: DigestAlgorithm) -> Result<Self, CryptoError> {
+ match algorithm {
+ DigestAlgorithm::Sha256 => Ok(MessageDigest::sha256()),
+ DigestAlgorithm::Sha384 => Ok(MessageDigest::sha384()),
+ DigestAlgorithm::Sha512 => Ok(MessageDigest::sha512()),
+ algo => Err(CryptoError::UnsupportedDigest(algo)),
+ }
+ }
+}
diff --git a/third_party/rust/hawk/src/crypto/ring.rs b/third_party/rust/hawk/src/crypto/ring.rs
@@ -0,0 +1,97 @@
+use super::{CryptoError, Cryptographer, Hasher, HmacKey};
+use crate::DigestAlgorithm;
+use ring::{digest, hmac};
+use std::convert::{TryFrom, TryInto};
+
+impl From<ring::error::Unspecified> for CryptoError {
+ // Ring's errors are entirely opaque
+ fn from(_: ring::error::Unspecified) -> Self {
+ CryptoError::Other(anyhow::Error::msg("Unspecified ring error"))
+ }
+}
+
+impl From<std::convert::Infallible> for CryptoError {
+ fn from(_: std::convert::Infallible) -> Self {
+ unreachable!()
+ }
+}
+
+pub struct RingCryptographer;
+
+struct RingHmacKey(hmac::Key);
+
+impl HmacKey for RingHmacKey {
+ fn sign(&self, data: &[u8]) -> Result<Vec<u8>, CryptoError> {
+ let digest = hmac::sign(&self.0, data);
+ let mut mac = vec![0; self.0.algorithm().digest_algorithm().output_len()];
+ mac.copy_from_slice(digest.as_ref());
+ Ok(mac)
+ }
+}
+// This is always `Some` until `finish` is called.
+struct RingHasher(Option<digest::Context>);
+
+impl Hasher for RingHasher {
+ fn update(&mut self, data: &[u8]) -> Result<(), CryptoError> {
+ self.0
+ .as_mut()
+ .expect("update called after `finish`")
+ .update(data);
+ Ok(())
+ }
+
+ fn finish(&mut self) -> Result<Vec<u8>, CryptoError> {
+ let digest = self.0.take().expect("`finish` called twice").finish();
+ let bytes: &[u8] = digest.as_ref();
+ Ok(bytes.to_owned())
+ }
+}
+
+impl Cryptographer for RingCryptographer {
+ fn rand_bytes(&self, output: &mut [u8]) -> Result<(), CryptoError> {
+ use ring::rand::SecureRandom;
+ let rnd = ring::rand::SystemRandom::new();
+ rnd.fill(output)?;
+ Ok(())
+ }
+
+ fn new_key(
+ &self,
+ algorithm: DigestAlgorithm,
+ key: &[u8],
+ ) -> Result<Box<dyn HmacKey>, CryptoError> {
+ let k = hmac::Key::new(algorithm.try_into()?, key);
+ Ok(Box::new(RingHmacKey(k)))
+ }
+
+ fn constant_time_compare(&self, a: &[u8], b: &[u8]) -> bool {
+ ring::constant_time::verify_slices_are_equal(a, b).is_ok()
+ }
+
+ fn new_hasher(&self, algorithm: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError> {
+ let ctx = digest::Context::new(algorithm.try_into()?);
+ Ok(Box::new(RingHasher(Some(ctx))))
+ }
+}
+
+impl TryFrom<DigestAlgorithm> for &'static digest::Algorithm {
+ type Error = CryptoError;
+ fn try_from(algorithm: DigestAlgorithm) -> Result<Self, CryptoError> {
+ match algorithm {
+ DigestAlgorithm::Sha256 => Ok(&digest::SHA256),
+ DigestAlgorithm::Sha384 => Ok(&digest::SHA384),
+ DigestAlgorithm::Sha512 => Ok(&digest::SHA512),
+ }
+ }
+}
+
+impl TryFrom<DigestAlgorithm> for hmac::Algorithm {
+ type Error = CryptoError;
+ fn try_from(algorithm: DigestAlgorithm) -> Result<Self, CryptoError> {
+ match algorithm {
+ DigestAlgorithm::Sha256 => Ok(hmac::HMAC_SHA256),
+ DigestAlgorithm::Sha384 => Ok(hmac::HMAC_SHA384),
+ DigestAlgorithm::Sha512 => Ok(hmac::HMAC_SHA512),
+ }
+ }
+}
diff --git a/third_party/rust/hawk/src/error.rs b/third_party/rust/hawk/src/error.rs
@@ -0,0 +1,72 @@
+use crate::crypto::CryptoError;
+
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+ #[error("Unparseable Hawk header: {0}")]
+ HeaderParseError(String),
+
+ #[error("Invalid url: {0}")]
+ InvalidUrl(String),
+
+ #[error("Missing `ts` attribute in Hawk header")]
+ MissingTs,
+
+ #[error("Missing `nonce` attribute in Hawk header")]
+ MissingNonce,
+
+ #[error("{0}")]
+ InvalidBewit(#[source] InvalidBewit),
+
+ #[error("{0}")]
+ Io(#[source] std::io::Error),
+
+ #[error("Base64 Decode error: {0}")]
+ Decode(String),
+
+ #[error("Crypto error: {0}")]
+ Crypto(#[source] CryptoError),
+}
+
+#[derive(thiserror::Error, Debug, PartialEq)]
+pub enum InvalidBewit {
+ #[error("Multiple bewits in URL")]
+ Multiple,
+ #[error("Invalid bewit format")]
+ Format,
+ #[error("Invalid bewit id")]
+ Id,
+ #[error("Invalid bewit exp")]
+ Exp,
+ #[error("Invalid bewit mac")]
+ Mac,
+ #[error("Invalid bewit ext")]
+ Ext,
+}
+
+impl Error {
+ // this cannot be a `From<..>` implementation as that publicly exposes the version of base64
+ // used in this crate.
+ pub(crate) fn from_base64_error(e: base64::DecodeError) -> Self {
+ Error::Decode(e.to_string())
+ }
+}
+
+impl From<std::io::Error> for Error {
+ fn from(e: std::io::Error) -> Self {
+ Error::Io(e)
+ }
+}
+
+impl From<CryptoError> for Error {
+ fn from(e: CryptoError) -> Self {
+ Error::Crypto(e)
+ }
+}
+
+impl From<InvalidBewit> for Error {
+ fn from(e: InvalidBewit) -> Self {
+ Error::InvalidBewit(e)
+ }
+}
diff --git a/third_party/rust/hawk/src/header.rs b/third_party/rust/hawk/src/header.rs
@@ -0,0 +1,472 @@
+use crate::b64;
+use crate::error::*;
+use crate::mac::Mac;
+use base64::Engine;
+use std::fmt;
+use std::str::FromStr;
+use std::time::{Duration, SystemTime, UNIX_EPOCH};
+
+/// Representation of a Hawk `Authorization` header value (the part following "Hawk ").
+///
+/// Headers can be derived from strings using the `FromStr` trait, and formatted into a
+/// string using the `fmt_header` method.
+///
+/// All fields are optional, although for specific purposes some fields must be present.
+#[derive(Clone, PartialEq, Debug)]
+pub struct Header {
+ pub id: Option<String>,
+ pub ts: Option<SystemTime>,
+ pub nonce: Option<String>,
+ pub mac: Option<Mac>,
+ pub ext: Option<String>,
+ pub hash: Option<Vec<u8>>,
+ pub app: Option<String>,
+ pub dlg: Option<String>,
+}
+
+impl Header {
+ /// Create a new Header with the full set of Hawk fields.
+ ///
+ /// This is a low-level function. Headers are more often created from Requests or Responses.
+ ///
+ /// Note that none of the string-formatted header components can contain the character `\"`.
+ pub fn new<S>(
+ id: Option<S>,
+ ts: Option<SystemTime>,
+ nonce: Option<S>,
+ mac: Option<Mac>,
+ ext: Option<S>,
+ hash: Option<Vec<u8>>,
+ app: Option<S>,
+ dlg: Option<S>,
+ ) -> Result<Header>
+ where
+ S: Into<String>,
+ {
+ Ok(Header {
+ id: Header::check_component(id)?,
+ ts,
+ nonce: Header::check_component(nonce)?,
+ mac,
+ ext: Header::check_component(ext)?,
+ hash,
+ app: Header::check_component(app)?,
+ dlg: Header::check_component(dlg)?,
+ })
+ }
+
+ /// Check a header component for validity.
+ fn check_component<S>(value: Option<S>) -> Result<Option<String>>
+ where
+ S: Into<String>,
+ {
+ if let Some(value) = value {
+ let value = value.into();
+ if value.contains('\"') {
+ return Err(Error::HeaderParseError(
+ "Hawk headers cannot contain `\\`".into(),
+ ));
+ }
+ Ok(Some(value))
+ } else {
+ Ok(None)
+ }
+ }
+
+ /// Format the header for transmission in an Authorization header, omitting the `"Hawk "`
+ /// prefix.
+ pub fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut sep = "";
+ if let Some(ref id) = self.id {
+ write!(f, "{sep}id=\"{id}\"")?;
+ sep = ", ";
+ }
+ if let Some(ref ts) = self.ts {
+ write!(
+ f,
+ "{}ts=\"{}\"",
+ sep,
+ ts.duration_since(UNIX_EPOCH).unwrap_or_default().as_secs()
+ )?;
+ sep = ", ";
+ }
+ if let Some(ref nonce) = self.nonce {
+ write!(f, "{sep}nonce=\"{nonce}\"")?;
+ sep = ", ";
+ }
+ if let Some(ref mac) = self.mac {
+ write!(f, "{}mac=\"{}\"", sep, b64::STANDARD_ENGINE.encode(mac))?;
+ sep = ", ";
+ }
+ if let Some(ref ext) = self.ext {
+ write!(f, "{sep}ext=\"{ext}\"")?;
+ sep = ", ";
+ }
+ if let Some(ref hash) = self.hash {
+ write!(f, "{}hash=\"{}\"", sep, b64::STANDARD_ENGINE.encode(hash))?;
+ sep = ", ";
+ }
+ if let Some(ref app) = self.app {
+ write!(f, "{sep}app=\"{app}\"")?;
+ sep = ", ";
+ }
+ if let Some(ref dlg) = self.dlg {
+ write!(f, "{sep}dlg=\"{dlg}\"")?;
+ }
+ Ok(())
+ }
+}
+
+impl fmt::Display for Header {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.fmt_header(f)
+ }
+}
+
+impl FromStr for Header {
+ type Err = Error;
+ fn from_str(s: &str) -> Result<Header> {
+ let mut p = s;
+
+ // Required attributes
+ let mut id: Option<&str> = None;
+ let mut ts: Option<SystemTime> = None;
+ let mut nonce: Option<&str> = None;
+ let mut mac: Option<Vec<u8>> = None;
+ // Optional attributes
+ let mut hash: Option<Vec<u8>> = None;
+ let mut ext: Option<&str> = None;
+ let mut app: Option<&str> = None;
+ let mut dlg: Option<&str> = None;
+
+ while !p.is_empty() {
+ // Skip whitespace and commas used as separators
+ p = p.trim_start_matches(|c| c == ',' || char::is_whitespace(c));
+ // Find first '=' which delimits attribute name from value
+ let assign_end = p
+ .find('=')
+ .ok_or_else(|| Error::HeaderParseError("Expected '='".into()))?;
+ let attr = &p[..assign_end].trim();
+ if p.len() < assign_end + 1 {
+ return Err(Error::HeaderParseError(
+ "Missing right hand side of =".into(),
+ ));
+ }
+ p = p[assign_end + 1..].trim_start();
+ if !p.starts_with('\"') {
+ return Err(Error::HeaderParseError("Expected opening quote".into()));
+ }
+ p = &p[1..];
+ // We have poor RFC 7235 compliance here as we ought to support backslash
+ // escaped characters, but hawk doesn't allow this we won't either. All
+ // strings must be surrounded by ".." and contain no such characters.
+ let end = p.find('\"');
+ let val_end =
+ end.ok_or_else(|| Error::HeaderParseError("Expected closing quote".into()))?;
+ let val = &p[..val_end];
+ match *attr {
+ "id" => id = Some(val),
+ "ts" => {
+ let epoch = u64::from_str(val)
+ .map_err(|_| Error::HeaderParseError("Error parsing `ts` field".into()))?;
+ ts = Some(UNIX_EPOCH + Duration::new(epoch, 0));
+ }
+ "mac" => {
+ mac = Some(b64::STANDARD_ENGINE.decode(val).map_err(|_| {
+ Error::HeaderParseError("Error parsing `mac` field".into())
+ })?);
+ }
+ "nonce" => nonce = Some(val),
+ "ext" => ext = Some(val),
+ "hash" => {
+ hash = Some(b64::STANDARD_ENGINE.decode(val).map_err(|_| {
+ Error::HeaderParseError("Error parsing `hash` field".into())
+ })?);
+ }
+ "app" => app = Some(val),
+ "dlg" => dlg = Some(val),
+ _ => {
+ return Err(Error::HeaderParseError(format!(
+ "Invalid Hawk field {}",
+ *attr
+ )))
+ }
+ };
+ // Break if we are at end of string, otherwise skip separator
+ if p.len() < val_end + 1 {
+ break;
+ }
+ p = p[val_end + 1..].trim_start();
+ }
+
+ Ok(Header {
+ id: id.map(|id| id.to_string()),
+ ts,
+ nonce: nonce.map(|nonce| nonce.to_string()),
+ mac: mac.map(Mac::from),
+ ext: ext.map(|ext| ext.to_string()),
+ hash,
+ app: app.map(|app| app.to_string()),
+ dlg: dlg.map(|dlg| dlg.to_string()),
+ })
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::Header;
+ use crate::mac::Mac;
+ use std::str::FromStr;
+ use std::time::{Duration, UNIX_EPOCH};
+
+ #[test]
+ fn illegal_id() {
+ assert!(Header::new(
+ Some("ab\"cdef"),
+ Some(UNIX_EPOCH + Duration::new(1234, 0)),
+ Some("nonce"),
+ Some(Mac::from(vec![])),
+ Some("ext"),
+ None,
+ None,
+ None
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn illegal_nonce() {
+ assert!(Header::new(
+ Some("abcdef"),
+ Some(UNIX_EPOCH + Duration::new(1234, 0)),
+ Some("no\"nce"),
+ Some(Mac::from(vec![])),
+ Some("ext"),
+ None,
+ None,
+ None
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn illegal_ext() {
+ assert!(Header::new(
+ Some("abcdef"),
+ Some(UNIX_EPOCH + Duration::new(1234, 0)),
+ Some("nonce"),
+ Some(Mac::from(vec![])),
+ Some("ex\"t"),
+ None,
+ None,
+ None
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn illegal_app() {
+ assert!(Header::new(
+ Some("abcdef"),
+ Some(UNIX_EPOCH + Duration::new(1234, 0)),
+ Some("nonce"),
+ Some(Mac::from(vec![])),
+ None,
+ None,
+ Some("a\"pp"),
+ None
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn illegal_dlg() {
+ assert!(Header::new(
+ Some("abcdef"),
+ Some(UNIX_EPOCH + Duration::new(1234, 0)),
+ Some("nonce"),
+ Some(Mac::from(vec![])),
+ None,
+ None,
+ None,
+ Some("d\"lg")
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn from_str() {
+ let s = Header::from_str(
+ "id=\"dh37fgj492je\", ts=\"1353832234\", \
+ nonce=\"j4h3g2\", ext=\"some-app-ext-data\", \
+ mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\", \
+ hash=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\", \
+ app=\"my-app\", dlg=\"my-authority\"",
+ )
+ .unwrap();
+ assert!(s.id == Some("dh37fgj492je".to_string()));
+ assert!(s.ts == Some(UNIX_EPOCH + Duration::new(1353832234, 0)));
+ assert!(s.nonce == Some("j4h3g2".to_string()));
+ assert!(
+ s.mac
+ == Some(Mac::from(vec![
+ 233, 30, 43, 87, 152, 132, 248, 211, 232, 202, 111, 150, 194, 55, 135, 206, 48,
+ 6, 93, 75, 75, 52, 140, 102, 163, 91, 233, 50, 135, 233, 44, 1
+ ]))
+ );
+ assert!(s.ext == Some("some-app-ext-data".to_string()));
+ assert!(s.app == Some("my-app".to_string()));
+ assert!(s.dlg == Some("my-authority".to_string()));
+ }
+
+ #[test]
+ fn from_str_invalid_mac() {
+ let r = Header::from_str(
+ "id=\"dh37fgj492je\", ts=\"1353832234\", \
+ nonce=\"j4h3g2\", ext=\"some-app-ext-data\", \
+ mac=\"6!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AE=\", \
+ app=\"my-app\", dlg=\"my-authority\"",
+ );
+ assert!(r.is_err());
+ }
+
+ #[test]
+ fn from_str_no_field() {
+ let s = Header::from_str("").unwrap();
+ assert!(s.id.is_none());
+ assert!(s.ts.is_none());
+ assert!(s.nonce.is_none());
+ assert!(s.mac.is_none());
+ assert!(s.ext.is_none());
+ assert!(s.app.is_none());
+ assert!(s.dlg.is_none());
+ }
+
+ #[test]
+ fn from_str_few_field() {
+ let s = Header::from_str(
+ "id=\"xyz\", ts=\"1353832234\", \
+ nonce=\"abc\", \
+ mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"",
+ )
+ .unwrap();
+ assert!(s.id == Some("xyz".to_string()));
+ assert!(s.ts == Some(UNIX_EPOCH + Duration::new(1353832234, 0)));
+ assert!(s.nonce == Some("abc".to_string()));
+ assert!(
+ s.mac
+ == Some(Mac::from(vec![
+ 233, 30, 43, 87, 152, 132, 248, 211, 232, 202, 111, 150, 194, 55, 135, 206, 48,
+ 6, 93, 75, 75, 52, 140, 102, 163, 91, 233, 50, 135, 233, 44, 1
+ ]))
+ );
+ assert!(s.ext.is_none());
+ assert!(s.app.is_none());
+ assert!(s.dlg.is_none());
+ }
+
+ #[test]
+ fn from_str_messy() {
+ let s = Header::from_str(
+ ", id = \"dh37fgj492je\", ts=\"1353832234\", \
+ nonce=\"j4h3g2\" , , ext=\"some-app-ext-data\", \
+ mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"",
+ )
+ .unwrap();
+ assert!(s.id == Some("dh37fgj492je".to_string()));
+ assert!(s.ts == Some(UNIX_EPOCH + Duration::new(1353832234, 0)));
+ assert!(s.nonce == Some("j4h3g2".to_string()));
+ assert!(
+ s.mac
+ == Some(Mac::from(vec![
+ 233, 30, 43, 87, 152, 132, 248, 211, 232, 202, 111, 150, 194, 55, 135, 206, 48,
+ 6, 93, 75, 75, 52, 140, 102, 163, 91, 233, 50, 135, 233, 44, 1
+ ]))
+ );
+ assert!(s.ext == Some("some-app-ext-data".to_string()));
+ assert!(s.app.is_none());
+ assert!(s.dlg.is_none());
+ }
+
+ #[test]
+ fn to_str_no_fields() {
+ // must supply a type for S, since it is otherwise unused
+ let s = Header::new::<String>(None, None, None, None, None, None, None, None).unwrap();
+ let formatted = format!("{s}");
+ println!("got: {formatted}");
+ assert!(formatted.is_empty())
+ }
+
+ #[test]
+ fn to_str_few_fields() {
+ let s = Header::new(
+ Some("dh37fgj492je"),
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ Some(Mac::from(vec![
+ 8, 35, 182, 149, 42, 111, 33, 192, 19, 22, 94, 43, 118, 176, 65, 69, 86, 4, 156,
+ 184, 85, 107, 249, 242, 172, 200, 66, 209, 57, 63, 38, 83,
+ ])),
+ None,
+ None,
+ None,
+ None,
+ )
+ .unwrap();
+ let formatted = format!("{s}");
+ println!("got: {formatted}");
+ assert!(
+ formatted
+ == "id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", \
+ mac=\"CCO2lSpvIcATFl4rdrBBRVYEnLhVa/nyrMhC0Tk/JlM=\""
+ )
+ }
+
+ #[test]
+ fn to_str_maximal() {
+ let s = Header::new(
+ Some("dh37fgj492je"),
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ Some(Mac::from(vec![
+ 8, 35, 182, 149, 42, 111, 33, 192, 19, 22, 94, 43, 118, 176, 65, 69, 86, 4, 156,
+ 184, 85, 107, 249, 242, 172, 200, 66, 209, 57, 63, 38, 83,
+ ])),
+ Some("my-ext-value"),
+ Some(vec![1, 2, 3, 4]),
+ Some("my-app"),
+ Some("my-dlg"),
+ )
+ .unwrap();
+ let formatted = format!("{s}");
+ println!("got: {formatted}");
+ assert!(
+ formatted
+ == "id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", \
+ mac=\"CCO2lSpvIcATFl4rdrBBRVYEnLhVa/nyrMhC0Tk/JlM=\", ext=\"my-ext-value\", \
+ hash=\"AQIDBA==\", app=\"my-app\", dlg=\"my-dlg\""
+ )
+ }
+
+ #[test]
+ fn round_trip() {
+ let s = Header::new(
+ Some("dh37fgj492je"),
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ Some(Mac::from(vec![
+ 8, 35, 182, 149, 42, 111, 33, 192, 19, 22, 94, 43, 118, 176, 65, 69, 86, 4, 156,
+ 184, 85, 107, 249, 242, 172, 200, 66, 209, 57, 63, 38, 83,
+ ])),
+ Some("my-ext-value"),
+ Some(vec![1, 2, 3, 4]),
+ Some("my-app"),
+ Some("my-dlg"),
+ )
+ .unwrap();
+ let formatted = format!("{s}");
+ println!("got: {s}");
+ let s2 = Header::from_str(&formatted).unwrap();
+ assert!(s2 == s);
+ }
+}
diff --git a/third_party/rust/hawk/src/lib.rs b/third_party/rust/hawk/src/lib.rs
@@ -0,0 +1,171 @@
+//! The `hawk` crate provides support for [Hawk](https://github.com/hueniverse/hawk)
+//! authentictation. It is a low-level crate, used by higher-level crates to integrate with various
+//! Rust HTTP libraries. For example `hyper-hawk` integrates Hawk with Hyper.
+//!
+//! # Examples
+//!
+//! ## Hawk Client
+//!
+//! A client can attach a Hawk Authorization header to requests by providing credentials to a
+//! Request instance, which will generate the header.
+//!
+//! ```
+//! use hawk::{RequestBuilder, Credentials, Key, SHA256, PayloadHasher};
+//! use std::time::{Duration, UNIX_EPOCH};
+//!
+//! // provide the Hawk id and key
+//! let credentials = Credentials {
+//! id: "test-client".to_string(),
+//! key: Key::new(vec![99u8; 32], SHA256).unwrap(),
+//! };
+//!
+//! let payload_hash = PayloadHasher::hash("text/plain", SHA256, "request-body").unwrap();
+//!
+//! // provide the details of the request to be authorized
+//! let request = RequestBuilder::new("POST", "example.com", 80, "/v1/users")
+//! .hash(&payload_hash[..])
+//! .request();
+//!
+//! // Get the resulting header, including the calculated MAC; this involves a random
+//! // nonce, so the MAC will be different on every request.
+//! let header = request.make_header(&credentials).unwrap();
+//!
+//! // the header would the be attached to the request
+//! assert_eq!(header.id.unwrap(), "test-client");
+//! assert_eq!(header.mac.unwrap().len(), 32);
+//! assert_eq!(header.hash.unwrap().len(), 32);
+//! ```
+//!
+//! A client that wishes to use a bewit (URL parameter) can do so as follows:
+//!
+//! ```
+//! use hawk::{RequestBuilder, Credentials, Key, SHA256, Bewit};
+//! use std::time::Duration;
+//! use std::borrow::Cow;
+//!
+//! let credentials = Credentials {
+//! id: "me".to_string(),
+//! key: Key::new("tok", SHA256).unwrap(),
+//! };
+//!
+//! let client_req = RequestBuilder::new("GET", "mysite.com", 443, "/resource").request();
+//! let client_bewit = client_req
+//! .make_bewit_with_ttl(&credentials, Duration::from_secs(10))
+//! .unwrap();
+//! let request_path = format!("/resource?bewit={}", client_bewit.to_str());
+//! // .. make the request
+//! ```
+//!
+//! ## Hawk Server
+//!
+//! To act as a server, parse the Hawk Authorization header from the request, generate a new
+//! Request instance, and use the request to validate the header.
+//!
+//! ```
+//! use hawk::{RequestBuilder, Header, Key, SHA256};
+//! use hawk::mac::Mac;
+//! use std::time::{Duration, UNIX_EPOCH};
+//!
+//! let mac = Mac::from(vec![7, 22, 226, 240, 84, 78, 49, 75, 115, 144, 70,
+//! 106, 102, 134, 144, 128, 225, 239, 95, 132, 202,
+//! 154, 213, 118, 19, 63, 183, 108, 215, 134, 118, 115]);
+//! // get the header (usually from the received request; constructed directly here)
+//! let hdr = Header::new(Some("dh37fgj492je"),
+//! Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+//! Some("j4h3g2"),
+//! Some(mac),
+//! Some("my-ext-value"),
+//! Some(vec![1, 2, 3, 4]),
+//! Some("my-app"),
+//! Some("my-dlg")).unwrap();
+//!
+//! // build a request object based on what we know
+//! let hash = vec![1, 2, 3, 4];
+//! let request = RequestBuilder::new("GET", "localhost", 443, "/resource")
+//! .hash(&hash[..])
+//! .request();
+//!
+//! let key = Key::new(vec![99u8; 32], SHA256).unwrap();
+//! let one_week_in_secs = 7 * 24 * 60 * 60;
+//! if !request.validate_header(&hdr, &key, Duration::from_secs(5200 * one_week_in_secs)) {
+//! panic!("header validation failed. Is it 2117 already?");
+//! }
+//! ```
+//!
+//! A server which validates bewits looks like this:
+//!
+//! ```
+//! use hawk::{RequestBuilder, Credentials, Key, SHA256, Bewit};
+//! use std::time::Duration;
+//! use std::borrow::Cow;
+//!
+//! let credentials = Credentials {
+//! id: "me".to_string(),
+//! key: Key::new("tok", SHA256).unwrap(),
+//! };
+//!
+//! // simulate the client generation of a bewit
+//! let client_req = RequestBuilder::new("GET", "mysite.com", 443, "/resource").request();
+//! let client_bewit = client_req
+//! .make_bewit_with_ttl(&credentials, Duration::from_secs(10))
+//! .unwrap();
+//! let request_path = format!("/resource?bewit={}", client_bewit.to_str());
+//!
+//! let mut maybe_bewit = None;
+//! let server_req = RequestBuilder::new("GET", "mysite.com", 443, &request_path)
+//! .extract_bewit(&mut maybe_bewit).unwrap()
+//! .request();
+//! let bewit = maybe_bewit.unwrap();
+//! assert_eq!(bewit.id(), "me");
+//! assert!(server_req.validate_bewit(&bewit, &credentials.key));
+//! ```
+//!
+//! ## Features
+//!
+//! By default, the `use_ring` feature is enabled, which means that this crate will
+//! use `ring` for all cryptographic operations.
+//!
+//! Alternatively, one can configure the crate with the `use_openssl`
+//! feature to use the `openssl` crate.
+//!
+//! If no features are enabled, you must provide a custom implementation of the
+//! [`hawk::crypto::Cryptographer`] trait to the `set_cryptographer` function, or
+//! the cryptographic operations will panic.
+//!
+//! Attempting to configure both the `use_ring` and `use_openssl` features will
+//! result in a build error.
+
+#[cfg(test)]
+#[macro_use]
+extern crate pretty_assertions;
+
+mod header;
+pub use crate::header::Header;
+
+mod credentials;
+pub use crate::credentials::{Credentials, DigestAlgorithm, Key};
+
+mod request;
+pub use crate::request::{Request, RequestBuilder};
+
+mod response;
+pub use crate::response::{Response, ResponseBuilder};
+
+mod error;
+pub use crate::error::*;
+
+mod payload;
+pub use crate::payload::PayloadHasher;
+
+mod bewit;
+pub use crate::bewit::Bewit;
+
+mod b64;
+
+pub mod mac;
+
+pub mod crypto;
+
+pub const SHA256: DigestAlgorithm = DigestAlgorithm::Sha256;
+pub const SHA384: DigestAlgorithm = DigestAlgorithm::Sha384;
+pub const SHA512: DigestAlgorithm = DigestAlgorithm::Sha512;
diff --git a/third_party/rust/hawk/src/mac.rs b/third_party/rust/hawk/src/mac.rs
@@ -0,0 +1,201 @@
+use crate::b64;
+use crate::credentials::Key;
+use crate::error::*;
+use base64::Engine;
+use std::io::Write;
+use std::ops::Deref;
+use std::time::{SystemTime, UNIX_EPOCH};
+
+/// The kind of MAC calcuation (corresponding to the first line of the message)
+pub enum MacType {
+ Header,
+ Response,
+ Bewit,
+}
+
+/// Mac represents a message authentication code, the signature in a Hawk transaction.
+///
+/// This class supports creating Macs using the Hawk specification, and comparing Macs
+/// using a cosntant-time comparison (thus preventing timing side-channel attacks).
+#[derive(Debug, Clone)]
+pub struct Mac(Vec<u8>);
+
+impl Mac {
+ pub fn new(
+ mac_type: MacType,
+ key: &Key,
+ ts: SystemTime,
+ nonce: &str,
+ method: &str,
+ host: &str,
+ port: u16,
+ path: &str,
+ hash: Option<&[u8]>,
+ ext: Option<&str>,
+ ) -> Result<Mac> {
+ // Note: there's a \n after each item.
+ let mut buffer: Vec<u8> = Vec::with_capacity(
+ 15 + 1 + // mac_type (worst case since it doesn't really matter)
+ 10 + 1 + // ts (in practice this will be 10 bytes)
+ nonce.len() + 1 +
+ host.len() + 1 +
+ 6 + 1 + // Longer than 6 bytes of port seems very unlikely
+ path.len() + 1 +
+ hash.map_or(0, |h| h.len() * 4 / 3) + 1 +
+ ext.map_or(0, str::len) + 1,
+ );
+
+ writeln!(
+ buffer,
+ "{mac_type}\n{ts}\n{nonce}\n{method}\n{path}\n{host}\n{port}",
+ mac_type = match mac_type {
+ MacType::Header => "hawk.1.header",
+ MacType::Response => "hawk.1.response",
+ MacType::Bewit => "hawk.1.bewit",
+ },
+ ts = ts.duration_since(UNIX_EPOCH).unwrap_or_default().as_secs(),
+ nonce = nonce,
+ method = method,
+ path = path,
+ host = host,
+ port = port,
+ )?;
+
+ if let Some(h) = hash {
+ writeln!(buffer, "{}", b64::STANDARD_ENGINE.encode(h),)?;
+ } else {
+ writeln!(buffer)?;
+ }
+ writeln!(buffer, "{}", ext.unwrap_or_default())?;
+
+ Ok(Mac(key.sign(buffer.as_ref())?))
+ }
+}
+
+impl AsRef<[u8]> for Mac {
+ fn as_ref(&self) -> &[u8] {
+ &self.0[..]
+ }
+}
+
+impl From<Vec<u8>> for Mac {
+ fn from(original: Vec<u8>) -> Self {
+ Mac(original)
+ }
+}
+
+impl Deref for Mac {
+ type Target = Vec<u8>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl PartialEq for Mac {
+ fn eq(&self, other: &Mac) -> bool {
+ crate::crypto::constant_time_compare(&self.0, &other.0)
+ }
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod test {
+ use super::{Mac, MacType};
+ use crate::credentials::Key;
+ use std::time::{Duration, SystemTime, UNIX_EPOCH};
+
+ fn key() -> Key {
+ Key::new(
+ vec![
+ 11u8, 19, 228, 209, 79, 189, 200, 59, 166, 47, 86, 254, 235, 184, 120, 197, 75,
+ 152, 201, 79, 115, 61, 111, 242, 219, 187, 173, 14, 227, 108, 60, 232,
+ ],
+ crate::SHA256,
+ )
+ .unwrap()
+ }
+
+ fn sys_time(secs: u64, ns: u32) -> SystemTime {
+ UNIX_EPOCH + Duration::new(secs, ns)
+ }
+
+ #[test]
+ fn test_make_mac() {
+ let key = key();
+ let mac = Mac::new(
+ MacType::Header,
+ &key,
+ sys_time(1000, 100),
+ "nonny",
+ "POST",
+ "mysite.com",
+ 443,
+ "/v1/api",
+ None,
+ None,
+ )
+ .unwrap();
+ println!("got {mac:?}");
+ assert!(
+ mac.0
+ == vec![
+ 192, 227, 235, 121, 157, 185, 197, 79, 189, 214, 235, 139, 9, 232, 99, 55, 67,
+ 30, 68, 0, 150, 187, 192, 238, 21, 200, 209, 107, 245, 159, 243, 178
+ ]
+ );
+ }
+
+ #[test]
+ fn test_make_mac_hash() {
+ let key = key();
+ let hash = vec![1, 2, 3, 4, 5];
+ let mac = Mac::new(
+ MacType::Header,
+ &key,
+ sys_time(1000, 100),
+ "nonny",
+ "POST",
+ "mysite.com",
+ 443,
+ "/v1/api",
+ Some(&hash),
+ None,
+ )
+ .unwrap();
+ println!("got {mac:?}");
+ assert!(
+ mac.0
+ == vec![
+ 61, 128, 208, 253, 88, 135, 190, 196, 1, 69, 153, 193, 124, 4, 195, 87, 38, 96,
+ 181, 34, 65, 234, 58, 157, 175, 175, 145, 151, 61, 0, 57, 5
+ ]
+ );
+ }
+
+ #[test]
+ fn test_make_mac_ext() {
+ let key = key();
+ let ext = "ext-data".to_string();
+ let mac = Mac::new(
+ MacType::Header,
+ &key,
+ sys_time(1000, 100),
+ "nonny",
+ "POST",
+ "mysite.com",
+ 443,
+ "/v1/api",
+ None,
+ Some(&ext),
+ )
+ .unwrap();
+ println!("got {mac:?}");
+ assert!(
+ mac.0
+ == vec![
+ 187, 104, 238, 100, 168, 112, 37, 68, 187, 141, 168, 155, 177, 193, 113, 0, 50,
+ 105, 127, 36, 24, 117, 200, 251, 138, 199, 108, 14, 105, 123, 234, 119
+ ]
+ );
+ }
+}
diff --git a/third_party/rust/hawk/src/payload.rs b/third_party/rust/hawk/src/payload.rs
@@ -0,0 +1,87 @@
+use crate::error::*;
+use crate::{crypto, DigestAlgorithm};
+/// A utility for hashing payloads. Feed your entity body to this, then pass the `finish`
+/// result to a request or response.
+pub struct PayloadHasher(Box<dyn crypto::Hasher>);
+
+impl PayloadHasher {
+ /// Create a new PayloadHasher. The `content_type` should be lower-case and should
+ /// not include parameters. The digest is assumed to be the same as the digest used
+ /// for the credentials in the request.
+ pub fn new<B>(content_type: B, algorithm: DigestAlgorithm) -> Result<Self>
+ where
+ B: AsRef<[u8]>,
+ {
+ let mut hasher = PayloadHasher(crypto::new_hasher(algorithm)?);
+ hasher.update(b"hawk.1.payload\n")?;
+ hasher.update(content_type.as_ref())?;
+ hasher.update(b"\n")?;
+ Ok(hasher)
+ }
+
+ /// Hash a single value and return it
+ pub fn hash<B1, B2>(
+ content_type: B1,
+ algorithm: DigestAlgorithm,
+ payload: B2,
+ ) -> Result<Vec<u8>>
+ where
+ B1: AsRef<[u8]>,
+ B2: AsRef<[u8]>,
+ {
+ let mut hasher = PayloadHasher::new(content_type, algorithm)?;
+ hasher.update(payload)?;
+ hasher.finish()
+ }
+
+ /// Update the hash with new data.
+ pub fn update<B>(&mut self, data: B) -> Result<()>
+ where
+ B: AsRef<[u8]>,
+ {
+ self.0.update(data.as_ref())?;
+ Ok(())
+ }
+
+ /// Finish hashing and return the result
+ ///
+ /// Note that this appends a newline to the payload, as does the JS Hawk implementaiton.
+ pub fn finish(mut self) -> Result<Vec<u8>> {
+ self.update(b"\n")?;
+ Ok(self.0.finish()?)
+ }
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod tests {
+ use super::PayloadHasher;
+
+ #[test]
+ fn hash_consistency() -> super::Result<()> {
+ let mut hasher1 = PayloadHasher::new("text/plain", crate::SHA256)?;
+ hasher1.update("pày")?;
+ hasher1.update("load")?;
+ let hash1 = hasher1.finish()?;
+
+ let mut hasher2 = PayloadHasher::new("text/plain", crate::SHA256)?;
+ hasher2.update("pàyload")?;
+ let hash2 = hasher2.finish()?;
+
+ let hash3 = PayloadHasher::hash("text/plain", crate::SHA256, "pàyload")?;
+
+ let hash4 = // "pàyload" as utf-8 bytes
+ PayloadHasher::hash("text/plain", crate::SHA256, vec![112, 195, 160, 121, 108, 111, 97, 100])?;
+
+ assert_eq!(
+ hash1,
+ vec![
+ 228, 238, 241, 224, 235, 114, 158, 112, 211, 254, 118, 89, 25, 236, 87, 176, 181,
+ 54, 61, 135, 42, 223, 188, 103, 194, 59, 83, 36, 136, 31, 198, 50
+ ]
+ );
+ assert_eq!(hash2, hash1);
+ assert_eq!(hash3, hash1);
+ assert_eq!(hash4, hash1);
+ Ok(())
+ }
+}
diff --git a/third_party/rust/hawk/src/request.rs b/third_party/rust/hawk/src/request.rs
@@ -0,0 +1,954 @@
+use crate::b64;
+use crate::bewit::Bewit;
+use crate::credentials::{Credentials, Key};
+use crate::error::*;
+use crate::header::Header;
+use crate::mac::{Mac, MacType};
+use crate::response::ResponseBuilder;
+use base64::Engine;
+use log::debug;
+use std::borrow::Cow;
+use std::str;
+use std::str::FromStr;
+use std::time::{Duration, SystemTime};
+use url::{Position, Url};
+
+/// Request represents a single HTTP request.
+///
+/// The structure is created using (RequestBuilder)[struct.RequestBuilder.html]. Most uses of this
+/// library will hold several of the fields in this structure fixed. Cloning the structure with
+/// these fields applied is a convenient way to avoid repeating those fields. Most fields are
+/// references, since in common use the values already exist and will outlive the request.
+///
+/// A request can be used on the client, to generate a header or a bewit, or on the server, to
+/// validate the same.
+///
+/// # Examples
+///
+/// ```
+/// use hawk::RequestBuilder;
+/// let bldr = RequestBuilder::new("GET", "mysite.com", 443, "/");
+/// let request1 = bldr.clone().method("POST").path("/api/user").request();
+/// let request2 = bldr.path("/api/users").request();
+/// ```
+///
+/// See the documentation in the crate root for examples of creating and validating headers.
+#[derive(Debug, Clone)]
+pub struct Request<'a> {
+ method: &'a str,
+ host: &'a str,
+ port: u16,
+ path: Cow<'a, str>,
+ hash: Option<&'a [u8]>,
+ ext: Option<&'a str>,
+ app: Option<&'a str>,
+ dlg: Option<&'a str>,
+}
+
+impl<'a> Request<'a> {
+ /// Create a new Header for this request, inventing a new nonce and setting the
+ /// timestamp to the current time.
+ pub fn make_header(&self, credentials: &Credentials) -> Result<Header> {
+ let nonce = random_string(10)?;
+ self.make_header_full(credentials, SystemTime::now(), nonce)
+ }
+
+ /// Similar to `make_header`, but allowing specification of the timestamp
+ /// and nonce.
+ pub fn make_header_full<S>(
+ &self,
+ credentials: &Credentials,
+ ts: SystemTime,
+ nonce: S,
+ ) -> Result<Header>
+ where
+ S: Into<String>,
+ {
+ let nonce = nonce.into();
+ let mac = Mac::new(
+ MacType::Header,
+ &credentials.key,
+ ts,
+ &nonce,
+ self.method,
+ self.host,
+ self.port,
+ self.path.as_ref(),
+ self.hash,
+ self.ext,
+ )?;
+ Header::new(
+ Some(credentials.id.clone()),
+ Some(ts),
+ Some(nonce),
+ Some(mac),
+ self.ext.map(|v| v.to_string()),
+ self.hash.map(|v| v.to_vec()),
+ self.app.map(|v| v.to_string()),
+ self.dlg.map(|v| v.to_string()),
+ )
+ }
+
+ /// Make a "bewit" that can be attached to a URL to authenticate GET access.
+ ///
+ /// The ttl gives the time for which this bewit is valid, starting now.
+ pub fn make_bewit(&self, credentials: &'a Credentials, exp: SystemTime) -> Result<Bewit<'a>> {
+ // note that this includes `method` and `hash` even though they must always be GET and None
+ // for bewits. If they aren't, then the bewit just won't validate -- no need to catch
+ // that now
+ let mac = Mac::new(
+ MacType::Bewit,
+ &credentials.key,
+ exp,
+ "",
+ self.method,
+ self.host,
+ self.port,
+ self.path.as_ref(),
+ self.hash,
+ self.ext,
+ )?;
+ let bewit = Bewit::new(&credentials.id, exp, mac, self.ext);
+ Ok(bewit)
+ }
+
+ /// Variant of `make_bewit` that takes a Duration (starting from now)
+ /// instead of a SystemTime, provided for convenience.
+ pub fn make_bewit_with_ttl(
+ &self,
+ credentials: &'a Credentials,
+ ttl: Duration,
+ ) -> Result<Bewit<'a>> {
+ let exp = SystemTime::now() + ttl;
+ self.make_bewit(credentials, exp)
+ }
+
+ /// Validate the given header. This validates that the `mac` field matches that calculated
+ /// using the other header fields and the given request information.
+ ///
+ /// The header's timestamp is verified to be within `ts_skew` of the current time. If any of
+ /// the required header fields are missing, the method will return false.
+ ///
+ /// It is up to the caller to examine the header's `id` field and supply the corresponding key.
+ ///
+ /// If desired, it is up to the caller to validate that `nonce` has not been used before.
+ ///
+ /// If a hash has been supplied, then the header must contain a matching hash. Note that this
+ /// hash must be calculated based on the request body, not copied from the request header!
+ pub fn validate_header(&self, header: &Header, key: &Key, ts_skew: Duration) -> bool {
+ // extract required fields, returning early if they are not present
+ let ts = match header.ts {
+ Some(ts) => ts,
+ None => {
+ debug!("missing timestamp from header");
+ return false;
+ }
+ };
+ let nonce = match header.nonce {
+ Some(ref nonce) => nonce,
+ None => {
+ debug!("missing nonce from header");
+ return false;
+ }
+ };
+ let header_mac = match header.mac {
+ Some(ref mac) => mac,
+ None => {
+ debug!("missing mac from header");
+ return false;
+ }
+ };
+ let header_hash = header.hash.as_ref().map(|hash| &hash[..]);
+ let header_ext = header.ext.as_ref().map(|ext| &ext[..]);
+
+ // first verify the MAC
+ match Mac::new(
+ MacType::Header,
+ key,
+ ts,
+ nonce,
+ self.method,
+ self.host,
+ self.port,
+ self.path.as_ref(),
+ header_hash,
+ header_ext,
+ ) {
+ Ok(calculated_mac) => {
+ if &calculated_mac != header_mac {
+ debug!("calculated mac doesn't match header");
+ return false;
+ }
+ }
+ Err(e) => {
+ debug!("unexpected mac error: {:?}", e);
+ return false;
+ }
+ };
+
+ // ..then the hashes
+ if let Some(local_hash) = self.hash {
+ if let Some(server_hash) = header_hash {
+ if local_hash != server_hash {
+ debug!("server hash doesn't match header");
+ return false;
+ }
+ } else {
+ debug!("missing hash from header");
+ return false;
+ }
+ }
+
+ // ..then the timestamp
+ let now = SystemTime::now();
+ let skew = if now > ts {
+ now.duration_since(ts).unwrap()
+ } else {
+ ts.duration_since(now).unwrap()
+ };
+ if skew > ts_skew {
+ debug!(
+ "bad timestamp skew, timestamp too old? detected skew: {:?}, ts_skew: {:?}",
+ &skew, &ts_skew
+ );
+ return false;
+ }
+
+ true
+ }
+
+ /// Validate the given bewit matches this request.
+ ///
+ /// It is up to the caller to consult the Bewit's `id` and look up the
+ /// corresponding key.
+ ///
+ /// Nonces and hashes do not apply when using bewits.
+ pub fn validate_bewit(&self, bewit: &Bewit, key: &Key) -> bool {
+ let calculated_mac = Mac::new(
+ MacType::Bewit,
+ key,
+ bewit.exp(),
+ "",
+ self.method,
+ self.host,
+ self.port,
+ self.path.as_ref(),
+ self.hash,
+ match bewit.ext() {
+ Some(e) => Some(e),
+ None => None,
+ },
+ );
+ let calculated_mac = match calculated_mac {
+ Ok(m) => m,
+ Err(_) => {
+ return false;
+ }
+ };
+
+ if bewit.mac() != &calculated_mac {
+ return false;
+ }
+
+ let now = SystemTime::now();
+ if bewit.exp() < now {
+ return false;
+ }
+
+ true
+ }
+
+ /// Get a Response instance for a response to this request. This is a convenience
+ /// wrapper around `Response::from_request_header`.
+ pub fn make_response_builder(&'a self, req_header: &'a Header) -> ResponseBuilder<'a> {
+ ResponseBuilder::from_request_header(
+ req_header,
+ self.method,
+ self.host,
+ self.port,
+ self.path.as_ref(),
+ )
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct RequestBuilder<'a>(Request<'a>);
+
+impl<'a> RequestBuilder<'a> {
+ /// Create a new request with the given method, host, port, and path.
+ pub fn new(method: &'a str, host: &'a str, port: u16, path: &'a str) -> Self {
+ RequestBuilder(Request {
+ method,
+ host,
+ port,
+ path: Cow::Borrowed(path),
+ hash: None,
+ ext: None,
+ app: None,
+ dlg: None,
+ })
+ }
+
+ /// Create a new request with the host, port, and path determined from the URL.
+ pub fn from_url(method: &'a str, url: &'a Url) -> Result<Self> {
+ let (host, port, path) = RequestBuilder::parse_url(url)?;
+ Ok(RequestBuilder(Request {
+ method,
+ host,
+ port,
+ path: Cow::Borrowed(path),
+ hash: None,
+ ext: None,
+ app: None,
+ dlg: None,
+ }))
+ }
+
+ /// Set the request method. This should be a capitalized string.
+ pub fn method(mut self, method: &'a str) -> Self {
+ self.0.method = method;
+ self
+ }
+
+ /// Set the URL path for the request.
+ pub fn path(mut self, path: &'a str) -> Self {
+ self.0.path = Cow::Borrowed(path);
+ self
+ }
+
+ /// Set the URL hostname for the request
+ pub fn host(mut self, host: &'a str) -> Self {
+ self.0.host = host;
+ self
+ }
+
+ /// Set the URL port for the request
+ pub fn port(mut self, port: u16) -> Self {
+ self.0.port = port;
+ self
+ }
+
+ /// Set the hostname, port, and path for the request, from a string URL.
+ pub fn url(self, url: &'a Url) -> Result<Self> {
+ let (host, port, path) = RequestBuilder::parse_url(url)?;
+ Ok(self.path(path).host(host).port(port))
+ }
+
+ /// Set the content hash for the request
+ pub fn hash<H: Into<Option<&'a [u8]>>>(mut self, hash: H) -> Self {
+ self.0.hash = hash.into();
+ self
+ }
+
+ /// Set the `ext` Hawk property for the request
+ pub fn ext<S: Into<Option<&'a str>>>(mut self, ext: S) -> Self {
+ self.0.ext = ext.into();
+ self
+ }
+
+ /// Set the `app` Hawk property for the request
+ pub fn app<S: Into<Option<&'a str>>>(mut self, app: S) -> Self {
+ self.0.app = app.into();
+ self
+ }
+
+ /// Set the `dlg` Hawk property for the request
+ pub fn dlg<S: Into<Option<&'a str>>>(mut self, dlg: S) -> Self {
+ self.0.dlg = dlg.into();
+ self
+ }
+
+ /// Get the request from this builder
+ pub fn request(self) -> Request<'a> {
+ self.0
+ }
+
+ /// Extract the `bewit` query parameter, if any, from the path, and return it in the output
+ /// parameter, returning a modified RequestBuilder omitting the `bewit=..` query parameter. If
+ /// no bewit is present, or if an error is returned, the output parameter is reset to None.
+ ///
+ /// The path manipulation is tested to correspond to that preformed by the hueniverse/hawk
+ /// implementation-specification
+ pub fn extract_bewit(mut self, bewit: &mut Option<Bewit<'a>>) -> Result<Self> {
+ const PREFIX: &str = "bewit=";
+ *bewit = None;
+
+ if let Some(query_index) = self.0.path.find('?') {
+ let (bewit_components, components): (Vec<&str>, Vec<&str>) = self.0.path
+ [query_index + 1..]
+ .split('&')
+ .partition(|comp| comp.starts_with(PREFIX));
+
+ if bewit_components.len() == 1 {
+ let bewit_str = bewit_components[0];
+ *bewit = Some(Bewit::from_str(&bewit_str[PREFIX.len()..])?);
+
+ // update the path to omit the bewit=... segment
+ let new_path = if !components.is_empty() {
+ format!("{}{}", &self.0.path[..=query_index], components.join("&"))
+ } else {
+ // no query left, so return the remaining path, omitting the '?'
+ self.0.path[..query_index].to_string()
+ };
+ self.0.path = Cow::Owned(new_path);
+ Ok(self)
+ } else if bewit_components.is_empty() {
+ Ok(self)
+ } else {
+ Err(InvalidBewit::Multiple.into())
+ }
+ } else {
+ Ok(self)
+ }
+ }
+
+ fn parse_url(url: &'a Url) -> Result<(&'a str, u16, &'a str)> {
+ let host = url
+ .host_str()
+ .ok_or_else(|| Error::InvalidUrl(format!("url {url} has no host")))?;
+ let port = url
+ .port_or_known_default()
+ .ok_or_else(|| Error::InvalidUrl(format!("url {url} has no port")))?;
+ let path = &url[Position::BeforePath..];
+ Ok((host, port, path))
+ }
+}
+
+/// Create a random string with `bytes` bytes of entropy. The string
+/// is base64-encoded. so it will be longer than bytes characters.
+fn random_string(bytes: usize) -> Result<String> {
+ let mut bytes = vec![0u8; bytes];
+ crate::crypto::rand_bytes(&mut bytes)?;
+ Ok(b64::BEWIT_ENGINE.encode(&bytes))
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod test {
+ use super::*;
+ use crate::credentials::{Credentials, Key};
+ use crate::header::Header;
+ use std::str::FromStr;
+ use std::time::{Duration, SystemTime, UNIX_EPOCH};
+ use url::Url;
+
+ // this is a header from a real request using the JS Hawk library, to
+ // https://pulse.taskcluster.net:443/v1/namespaces with credentials "me" / "tok"
+ const REAL_HEADER: &str = "id=\"me\", ts=\"1491183061\", nonce=\"RVnYzW\", \
+ mac=\"1kqRT9EoxiZ9AA/ayOCXB+AcjfK/BoJ+n7z0gfvZotQ=\"";
+ const BEWIT_STR: &str =
+ "bWVcMTM1MzgzMjgzNFxmaXk0ZTV3QmRhcEROeEhIZUExOE5yU3JVMVUzaVM2NmdtMFhqVEpwWXlVPVw";
+
+ // this is used as the initial bewit when calling extract_bewit, to verify that it is
+ // not allowing the original value of the parameter to remain in place.
+ const INITIAL_BEWIT_STR: &str =
+ "T0ggTk9FU1wxMzUzODMyODM0XGZpeTRlNXdCZGFwRE54SEhlQTE4TnJTclUxVTNpUzY2Z20wWGpUSnBZeVU9XCZtdXQgYmV3aXQgbm90IHJlc2V0IQ";
+
+ #[test]
+ fn test_empty() {
+ let req = RequestBuilder::new("GET", "site", 80, "/").request();
+ assert_eq!(req.method, "GET");
+ assert_eq!(req.host, "site");
+ assert_eq!(req.port, 80);
+ assert_eq!(req.path, "/");
+ assert_eq!(req.hash, None);
+ assert_eq!(req.ext, None);
+ assert_eq!(req.app, None);
+ assert_eq!(req.dlg, None);
+ }
+
+ #[test]
+ fn test_builder() {
+ let hash = vec![0u8];
+ let req = RequestBuilder::new("GET", "example.com", 443, "/foo")
+ .hash(Some(&hash[..]))
+ .ext("ext")
+ .app("app")
+ .dlg("dlg")
+ .request();
+
+ assert_eq!(req.method, "GET");
+ assert_eq!(req.path, "/foo");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443);
+ assert_eq!(req.hash, Some(&hash[..]));
+ assert_eq!(req.ext, Some("ext"));
+ assert_eq!(req.app, Some("app"));
+ assert_eq!(req.dlg, Some("dlg"));
+ }
+
+ #[test]
+ fn test_builder_clone() {
+ let rb = RequestBuilder::new("GET", "site", 443, "/foo");
+ let req = rb.clone().request();
+ let req2 = rb.path("/bar").request();
+
+ assert_eq!(req.method, "GET");
+ assert_eq!(req.path, "/foo");
+ assert_eq!(req2.method, "GET");
+ assert_eq!(req2.path, "/bar");
+ }
+
+ #[test]
+ fn test_url_builder() {
+ let url = Url::parse("https://example.com/foo").unwrap();
+ let req = RequestBuilder::from_url("GET", &url).unwrap().request();
+
+ assert_eq!(req.path, "/foo");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_query() {
+ let url = Url::parse("https://example.com/foo?foo=bar").unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, None);
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?foo=bar");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_encodable_chars() {
+ let url = Url::parse("https://example.com/ñoo?foo=año").unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, None);
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/%C3%B1oo?foo=a%C3%B1o");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_empty_query() {
+ let url = Url::parse("https://example.com/foo?").unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, None);
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_alone() {
+ let url = Url::parse(&format!("https://example.com/foo?bewit={BEWIT_STR}")).unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, Some(Bewit::from_str(BEWIT_STR).unwrap()));
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo"); // NOTE: strips the `?`
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_first() {
+ let url = Url::parse(&format!("https://example.com/foo?bewit={BEWIT_STR}&a=1")).unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, Some(Bewit::from_str(BEWIT_STR).unwrap()));
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?a=1");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_multiple() {
+ let url = Url::parse(&format!(
+ "https://example.com/foo?bewit={BEWIT_STR}&bewit={BEWIT_STR}"
+ ))
+ .unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ assert!(bldr.extract_bewit(&mut bewit).is_err());
+ assert_eq!(bewit, None);
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_invalid() {
+ let url = Url::parse("https://example.com/foo?bewit=1234").unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ assert!(bldr.extract_bewit(&mut bewit).is_err());
+ assert_eq!(bewit, None);
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_last() {
+ let url = Url::parse(&format!("https://example.com/foo?a=1&bewit={BEWIT_STR}")).unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, Some(Bewit::from_str(BEWIT_STR).unwrap()));
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?a=1");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_middle() {
+ let url = Url::parse(&format!(
+ "https://example.com/foo?a=1&bewit={BEWIT_STR}&b=2"
+ ))
+ .unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, Some(Bewit::from_str(BEWIT_STR).unwrap()));
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?a=1&b=2");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_bewit_percent_encoding() {
+ // Note that this *over*-encodes things. Perfectly legal, but the kind
+ // of thing that incautious libraries can sometimes fail to reproduce,
+ // causing Hawk validation failures
+ let url = Url::parse(&format!(
+ "https://example.com/foo?%66oo=1&bewit={BEWIT_STR}&%62ar=2"
+ ))
+ .unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, Some(Bewit::from_str(BEWIT_STR).unwrap()));
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?%66oo=1&%62ar=2");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_xxxbewit() {
+ // check that we're not doing a simple string search for "bewit=.."
+ let url = Url::parse(&format!(
+ "https://example.com/foo?a=1&xxxbewit={BEWIT_STR}&b=2"
+ ))
+ .unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, None);
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, format!("/foo?a=1&xxxbewit={BEWIT_STR}&b=2"));
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_url_builder_with_username_password() {
+ let url = Url::parse("https://a:b@example.com/foo?x=y").unwrap();
+ let bldr = RequestBuilder::from_url("GET", &url).unwrap();
+
+ let mut bewit = Some(Bewit::from_str(INITIAL_BEWIT_STR).unwrap());
+ let bldr = bldr.extract_bewit(&mut bewit).unwrap();
+ assert_eq!(bewit, None);
+
+ let req = bldr.request();
+
+ assert_eq!(req.path, "/foo?x=y");
+ assert_eq!(req.host, "example.com");
+ assert_eq!(req.port, 443); // default for https
+ }
+
+ #[test]
+ fn test_make_header_full() {
+ let req = RequestBuilder::new("GET", "example.com", 443, "/foo").request();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new(vec![99u8; 32], crate::SHA256).unwrap(),
+ };
+ let header = req
+ .make_header_full(&credentials, UNIX_EPOCH + Duration::new(1000, 100), "nonny")
+ .unwrap();
+ assert_eq!(
+ header,
+ Header {
+ id: Some("me".to_string()),
+ ts: Some(UNIX_EPOCH + Duration::new(1000, 100)),
+ nonce: Some("nonny".to_string()),
+ mac: Some(Mac::from(vec![
+ 122, 47, 2, 53, 195, 247, 185, 107, 133, 250, 61, 134, 200, 35, 118, 94, 48,
+ 175, 237, 108, 60, 71, 4, 2, 244, 66, 41, 172, 91, 7, 233, 140
+ ])),
+ ext: None,
+ hash: None,
+ app: None,
+ dlg: None,
+ }
+ );
+ }
+
+ #[test]
+ fn test_make_header_full_with_optional_fields() {
+ let hash = vec![0u8];
+ let req = RequestBuilder::new("GET", "example.com", 443, "/foo")
+ .hash(Some(&hash[..]))
+ .ext("ext")
+ .app("app")
+ .dlg("dlg")
+ .request();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new(vec![99u8; 32], crate::SHA256).unwrap(),
+ };
+ let header = req
+ .make_header_full(&credentials, UNIX_EPOCH + Duration::new(1000, 100), "nonny")
+ .unwrap();
+ assert_eq!(
+ header,
+ Header {
+ id: Some("me".to_string()),
+ ts: Some(UNIX_EPOCH + Duration::new(1000, 100)),
+ nonce: Some("nonny".to_string()),
+ mac: Some(Mac::from(vec![
+ 72, 123, 243, 214, 145, 81, 129, 54, 183, 90, 22, 136, 192, 146, 208, 53, 216,
+ 138, 145, 94, 175, 204, 217, 8, 77, 16, 202, 50, 10, 144, 133, 162
+ ])),
+ ext: Some("ext".to_string()),
+ hash: Some(hash.clone()),
+ app: Some("app".to_string()),
+ dlg: Some("dlg".to_string()),
+ }
+ );
+ }
+
+ #[test]
+ fn test_validate_matches_generated() {
+ let req = RequestBuilder::new("GET", "example.com", 443, "/foo").request();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new(vec![99u8; 32], crate::SHA256).unwrap(),
+ };
+ let header = req
+ .make_header_full(&credentials, SystemTime::now(), "nonny")
+ .unwrap();
+ assert!(req.validate_header(&header, &credentials.key, Duration::from_secs(60)));
+ }
+
+ // Well, close enough.
+ const ONE_YEAR_IN_SECS: u64 = 365 * 24 * 60 * 60;
+
+ #[test]
+ fn test_validate_real_request() {
+ let header = Header::from_str(REAL_HEADER).unwrap();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new("tok", crate::SHA256).unwrap(),
+ };
+ let req =
+ RequestBuilder::new("GET", "pulse.taskcluster.net", 443, "/v1/namespaces").request();
+ // allow 1000 years skew, since this was a real request that
+ // happened back in 2017, when life was simple and carefree
+ assert!(req.validate_header(
+ &header,
+ &credentials.key,
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ #[test]
+ fn test_validate_real_request_bad_creds() {
+ let header = Header::from_str(REAL_HEADER).unwrap();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new("WRONG", crate::SHA256).unwrap(),
+ };
+ let req =
+ RequestBuilder::new("GET", "pulse.taskcluster.net", 443, "/v1/namespaces").request();
+ assert!(!req.validate_header(
+ &header,
+ &credentials.key,
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ #[test]
+ fn test_validate_real_request_bad_req_info() {
+ let header = Header::from_str(REAL_HEADER).unwrap();
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new("tok", crate::SHA256).unwrap(),
+ };
+ let req = RequestBuilder::new("GET", "pulse.taskcluster.net", 443, "WRONG PATH").request();
+ assert!(!req.validate_header(
+ &header,
+ &credentials.key,
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ fn make_header_without_hash() -> Header {
+ Header::new(
+ Some("dh37fgj492je"),
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ Some(Mac::from(vec![
+ 161, 105, 122, 110, 248, 62, 129, 193, 148, 206, 239, 193, 219, 46, 137, 221, 51,
+ 170, 135, 114, 81, 68, 145, 182, 15, 165, 145, 168, 114, 237, 52, 35,
+ ])),
+ None,
+ None,
+ None,
+ None,
+ )
+ .unwrap()
+ }
+
+ fn make_header_with_hash() -> Header {
+ Header::new(
+ Some("dh37fgj492je"),
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ Some(Mac::from(vec![
+ 189, 53, 155, 244, 203, 150, 255, 238, 135, 144, 186, 93, 6, 189, 184, 21, 150,
+ 210, 226, 61, 93, 154, 17, 218, 142, 250, 254, 193, 123, 132, 131, 195,
+ ])),
+ None,
+ Some(vec![1, 2, 3, 4]),
+ None,
+ None,
+ )
+ .unwrap()
+ }
+
+ #[test]
+ fn test_validate_no_hash() {
+ let header = make_header_without_hash();
+ let req = RequestBuilder::new("", "", 0, "").request();
+ assert!(req.validate_header(
+ &header,
+ &Key::new("tok", crate::SHA256).unwrap(),
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ #[test]
+ fn test_validate_hash_in_header() {
+ let header = make_header_with_hash();
+ let req = RequestBuilder::new("", "", 0, "").request();
+ assert!(req.validate_header(
+ &header,
+ &Key::new("tok", crate::SHA256).unwrap(),
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ #[test]
+ fn test_validate_hash_required_but_not_given() {
+ let header = make_header_without_hash();
+ let hash = vec![1, 2, 3, 4];
+ let req = RequestBuilder::new("", "", 0, "")
+ .hash(Some(&hash[..]))
+ .request();
+ assert!(!req.validate_header(
+ &header,
+ &Key::new("tok", crate::SHA256).unwrap(),
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ #[test]
+ fn test_validate_hash_validated() {
+ let header = make_header_with_hash();
+ let hash = vec![1, 2, 3, 4];
+ let req = RequestBuilder::new("", "", 0, "")
+ .hash(Some(&hash[..]))
+ .request();
+ assert!(req.validate_header(
+ &header,
+ &Key::new("tok", crate::SHA256).unwrap(),
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+
+ // ..but supplying the wrong hash will cause validation to fail
+ let hash = vec![99, 99, 99, 99];
+ let req = RequestBuilder::new("", "", 0, "")
+ .hash(Some(&hash[..]))
+ .request();
+ assert!(!req.validate_header(
+ &header,
+ &Key::new("tok", crate::SHA256).unwrap(),
+ Duration::from_secs(1000 * ONE_YEAR_IN_SECS)
+ ));
+ }
+
+ fn round_trip_bewit(req: Request, ts: SystemTime, expected: bool) {
+ let credentials = Credentials {
+ id: "me".to_string(),
+ key: Key::new("tok", crate::SHA256).unwrap(),
+ };
+
+ let bewit = req.make_bewit(&credentials, ts).unwrap();
+
+ // convert to a string and back
+ let bewit = bewit.to_str();
+ let bewit = Bewit::from_str(&bewit).unwrap();
+
+ // and validate it maches the original request
+ assert_eq!(req.validate_bewit(&bewit, &credentials.key), expected);
+ }
+
+ #[test]
+ fn test_validate_bewit() {
+ let req = RequestBuilder::new("GET", "foo.com", 443, "/x/y/z").request();
+ round_trip_bewit(req, SystemTime::now() + Duration::from_secs(10 * 60), true);
+ }
+
+ #[test]
+ fn test_validate_bewit_ext() {
+ let req = RequestBuilder::new("GET", "foo.com", 443, "/x/y/z")
+ .ext("abcd")
+ .request();
+ round_trip_bewit(req, SystemTime::now() + Duration::from_secs(10 * 60), true);
+ }
+
+ #[test]
+ fn test_validate_bewit_expired() {
+ let req = RequestBuilder::new("GET", "foo.com", 443, "/x/y/z").request();
+ round_trip_bewit(req, SystemTime::now() - Duration::from_secs(10 * 60), false);
+ }
+}
diff --git a/third_party/rust/hawk/src/response.rs b/third_party/rust/hawk/src/response.rs
@@ -0,0 +1,307 @@
+use crate::credentials::Key;
+use crate::error::*;
+use crate::header::Header;
+use crate::mac::{Mac, MacType};
+
+/// A Response represents a response from an HTTP server.
+///
+/// The structure is created from a request and then used to either create (server) or validate
+/// (client) a `Server-Authentication` header.
+///
+/// Like `Request`, Responses are built with `ResponseBuilders`.
+///
+/// # Examples
+///
+/// See the documentation in the crate root for examples.
+#[derive(Debug, Clone)]
+pub struct Response<'a> {
+ method: &'a str,
+ host: &'a str,
+ port: u16,
+ path: &'a str,
+ req_header: &'a Header,
+ hash: Option<&'a [u8]>,
+ ext: Option<&'a str>,
+}
+
+impl<'a> Response<'a> {
+ /// Create a new Header for this response, based on the given request and request header
+ pub fn make_header(&self, key: &Key) -> Result<Header> {
+ let ts = self.req_header.ts.ok_or(Error::MissingTs)?;
+ let nonce = self.req_header.nonce.as_ref().ok_or(Error::MissingNonce)?;
+ let mac = Mac::new(
+ MacType::Response,
+ key,
+ ts,
+ nonce,
+ self.method,
+ self.host,
+ self.port,
+ self.path,
+ self.hash,
+ self.ext,
+ )?;
+
+ // Per JS implementation, the Server-Authorization header includes only mac, hash, and ext
+ Header::new(
+ None,
+ None,
+ None,
+ Some(mac),
+ self.ext.map(|v| v.to_string()),
+ self.hash.map(|v| v.to_vec()),
+ None,
+ None,
+ )
+ }
+
+ /// Validate a Server-Authorization header.
+ ///
+ /// This checks that the MAC matches and, if a hash has been supplied locally,
+ /// checks that one was provided from the server and that it, too, matches.
+ pub fn validate_header(&self, response_header: &Header, key: &Key) -> bool {
+ // extract required fields, returning early if they are not present
+ let ts = match self.req_header.ts {
+ Some(ts) => ts,
+ None => {
+ return false;
+ }
+ };
+ let nonce = match self.req_header.nonce {
+ Some(ref nonce) => nonce,
+ None => {
+ return false;
+ }
+ };
+ let header_mac = match response_header.mac {
+ Some(ref mac) => mac,
+ None => {
+ return false;
+ }
+ };
+ let header_ext = response_header.ext.as_ref().map(|ext| &ext[..]);
+ let header_hash = response_header.hash.as_ref().map(|hash| &hash[..]);
+
+ // first verify the MAC
+ match Mac::new(
+ MacType::Response,
+ key,
+ ts,
+ nonce,
+ self.method,
+ self.host,
+ self.port,
+ self.path,
+ header_hash,
+ header_ext,
+ ) {
+ Ok(calculated_mac) => {
+ if &calculated_mac != header_mac {
+ return false;
+ }
+ }
+ Err(_) => {
+ return false;
+ }
+ };
+
+ // ..then the hashes
+ if let Some(local_hash) = self.hash {
+ if let Some(server_hash) = header_hash {
+ if local_hash != server_hash {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // NOTE: the timestamp self.req_header.ts was generated locally, so
+ // there is no need to verify it
+
+ true
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct ResponseBuilder<'a>(Response<'a>);
+
+impl<'a> ResponseBuilder<'a> {
+ /// Generate a new Response from a request header.
+ ///
+ /// This is more commonly accessed through `Request::make_response`.
+ pub fn from_request_header(
+ req_header: &'a Header,
+ method: &'a str,
+ host: &'a str,
+ port: u16,
+ path: &'a str,
+ ) -> Self {
+ ResponseBuilder(Response {
+ method,
+ host,
+ port,
+ path,
+ req_header,
+ hash: None,
+ ext: None,
+ })
+ }
+
+ /// Set the content hash for the response.
+ ///
+ /// This should always be calculated from the response payload, not copied from a header.
+ pub fn hash<H: Into<Option<&'a [u8]>>>(mut self, hash: H) -> Self {
+ self.0.hash = hash.into();
+ self
+ }
+
+ /// Set the `ext` Hawk property for the response.
+ ///
+ /// This need only be set on the server; it is ignored in validating responses on the client.
+ pub fn ext<S: Into<Option<&'a str>>>(mut self, ext: S) -> Self {
+ self.0.ext = ext.into();
+ self
+ }
+
+ /// Get the response from this builder
+ pub fn response(self) -> Response<'a> {
+ self.0
+ }
+}
+
+#[cfg(all(test, any(feature = "use_ring", feature = "use_openssl")))]
+mod test {
+ use super::ResponseBuilder;
+ use crate::credentials::Key;
+ use crate::header::Header;
+ use crate::mac::Mac;
+ use std::time::{Duration, UNIX_EPOCH};
+
+ fn make_req_header() -> Header {
+ Header::new(
+ None,
+ Some(UNIX_EPOCH + Duration::new(1353832234, 0)),
+ Some("j4h3g2"),
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+ .unwrap()
+ }
+
+ #[test]
+ fn test_validation_no_hash() {
+ let req_header = make_req_header();
+ let resp =
+ ResponseBuilder::from_request_header(&req_header, "POST", "localhost", 9988, "/a/b")
+ .response();
+ let mac: Mac = Mac::from(vec![
+ 48, 133, 228, 163, 224, 197, 222, 77, 117, 81, 143, 73, 71, 120, 68, 238, 228, 40, 55,
+ 64, 190, 73, 102, 123, 79, 185, 199, 26, 62, 1, 137, 170,
+ ]);
+ let server_header = Header::new(
+ None,
+ None,
+ None,
+ Some(mac),
+ Some("server-ext"),
+ None,
+ None,
+ None,
+ )
+ .unwrap();
+ assert!(resp.validate_header(&server_header, &Key::new("tok", crate::SHA256).unwrap()));
+ }
+
+ #[test]
+ fn test_validation_hash_in_header() {
+ // When a hash is provided in the response header, but no hash is added to the Response,
+ // it is ignored (so validation succeeds)
+ let req_header = make_req_header();
+ let resp =
+ ResponseBuilder::from_request_header(&req_header, "POST", "localhost", 9988, "/a/b")
+ .response();
+ let mac: Mac = Mac::from(vec![
+ 33, 147, 159, 211, 184, 194, 189, 74, 53, 229, 241, 161, 215, 145, 22, 34, 206, 207,
+ 242, 100, 33, 193, 36, 96, 149, 133, 180, 4, 132, 87, 207, 238,
+ ]);
+ let server_header = Header::new(
+ None,
+ None,
+ None,
+ Some(mac),
+ Some("server-ext"),
+ Some(vec![1, 2, 3, 4]),
+ None,
+ None,
+ )
+ .unwrap();
+ assert!(resp.validate_header(&server_header, &Key::new("tok", crate::SHA256).unwrap()));
+ }
+
+ #[test]
+ fn test_validation_hash_required_but_not_given() {
+ // When Response.hash is called, but no hash is in the hader, validation fails.
+ let req_header = make_req_header();
+ let hash = vec![1, 2, 3, 4];
+ let resp =
+ ResponseBuilder::from_request_header(&req_header, "POST", "localhost", 9988, "/a/b")
+ .hash(&hash[..])
+ .response();
+ let mac: Mac = Mac::from(vec![
+ 48, 133, 228, 163, 224, 197, 222, 77, 117, 81, 143, 73, 71, 120, 68, 238, 228, 40, 55,
+ 64, 190, 73, 102, 123, 79, 185, 199, 26, 62, 1, 137, 170,
+ ]);
+ let server_header = Header::new(
+ None,
+ None,
+ None,
+ Some(mac),
+ Some("server-ext"),
+ None,
+ None,
+ None,
+ )
+ .unwrap();
+ assert!(!resp.validate_header(&server_header, &Key::new("tok", crate::SHA256).unwrap()));
+ }
+
+ #[test]
+ fn test_validation_hash_validated() {
+ // When a hash is provided in the response header and the Response.hash method is called,
+ // the two must match
+ let req_header = make_req_header();
+ let hash = vec![1, 2, 3, 4];
+ let resp =
+ ResponseBuilder::from_request_header(&req_header, "POST", "localhost", 9988, "/a/b")
+ .hash(&hash[..])
+ .response();
+ let mac: Mac = Mac::from(vec![
+ 33, 147, 159, 211, 184, 194, 189, 74, 53, 229, 241, 161, 215, 145, 22, 34, 206, 207,
+ 242, 100, 33, 193, 36, 96, 149, 133, 180, 4, 132, 87, 207, 238,
+ ]);
+ let server_header = Header::new(
+ None,
+ None,
+ None,
+ Some(mac),
+ Some("server-ext"),
+ Some(vec![1, 2, 3, 4]),
+ None,
+ None,
+ )
+ .unwrap();
+ assert!(resp.validate_header(&server_header, &Key::new("tok", crate::SHA256).unwrap()));
+
+ // a different supplied hash won't match..
+ let hash = vec![99, 99, 99, 99];
+ let resp =
+ ResponseBuilder::from_request_header(&req_header, "POST", "localhost", 9988, "/a/b")
+ .hash(&hash[..])
+ .response();
+ assert!(!resp.validate_header(&server_header, &Key::new("tok", crate::SHA256).unwrap()));
+ }
+}
diff --git a/third_party/rust/init_rust_components/.cargo-checksum.json b/third_party/rust/init_rust_components/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"4fec7d9fed833f35258bbde30b032257bc1967ab8ddb9987c307c8a9c1ee323f","README.md":"4c4ba1a04d445dca0507eef3ff8cd79e0954474d2a75feadd98946187fd8374f","src/lib.rs":"a296a8e15e029e513501fe40f3df5ebc59d3817b4a3242d5eb5e4f7b59d2d832","uniffi.toml":"2e98a909732dc83db0c0b41438b0935c1fd5f869cea327e3ef5501fae5fa5d01"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/init_rust_components/Cargo.toml b/third_party/rust/init_rust_components/Cargo.toml
@@ -0,0 +1,38 @@
+# 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 = "init_rust_components"
+version = "0.1.0"
+authors = ["Johannes Schmidt <joschmidt@mozilla.com>"]
+build = false
+exclude = ["/android"]
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = "README.md"
+license = "MPL-2.0"
+
+[features]
+keydb = ["nss/keydb"]
+
+[lib]
+name = "init_rust_components"
+path = "src/lib.rs"
+
+[dependencies.nss]
+path = "../support/rc_crypto/nss"
+
+[dependencies.uniffi]
+version = "0.29.0"
diff --git a/third_party/rust/init_rust_components/README.md b/third_party/rust/init_rust_components/README.md
@@ -0,0 +1,24 @@
+# Init Rust Components
+
+This component is used to initialize the other Rust components globally.
+
+Some services, such as logging and cryptography, are used in several components
+and require explicit initialization. This component was created for this
+purpose.
+
+Currently, the Init Rust Componentes component only handles the initialization
+of NSS.
+
+If you encounter the error message 'NSS not initialized' in your code, it is
+probably because you have not called the initialization routine of this
+component before calling a method that uses NSS.
+
+Therefore, call the initialization method as early as possible in your code:
+```
+init_rust_components::initialize();
+```
+
+When using the `logins/keydb` feature to use NSS for keymanagement, provide a path to the initialization function:
+```
+init_rust_components::initialize(profile_path.to_string());
+```
diff --git a/third_party/rust/init_rust_components/src/lib.rs b/third_party/rust/init_rust_components/src/lib.rs
@@ -0,0 +1,37 @@
+/* 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(not(feature = "keydb"))]
+use nss::ensure_initialized as ensure_nss_initialized;
+#[cfg(feature = "keydb")]
+use nss::ensure_initialized_with_profile_dir as ensure_nss_initialized_with_profile_dir;
+
+uniffi::setup_scaffolding!();
+
+/// Global initialization routines for Rust components. Must be called before any other calls to
+/// Rust components.
+///
+/// For adding additional initialization code: Note that this function is called very early in the
+/// app lifetime and therefore affects the startup time. Only the most necessary things should be
+/// done here.
+#[cfg(not(feature = "keydb"))]
+#[uniffi::export]
+pub fn initialize() {
+ ensure_nss_initialized();
+}
+
+/// Global initialization routines for Rust components, when `logins/keydb` feature is activated. Must be
+/// called before any other calls to Rust components.
+///
+/// Receives the path to the profile directory.
+///
+/// For adding additional initialization code: Note that this function is called very early in the
+/// app lifetime and therefore affects the startup time. Only the most necessary things should be
+/// done here.
+#[cfg(feature = "keydb")]
+#[uniffi::export]
+pub fn initialize(profile_path: String) {
+ ensure_nss_initialized_with_profile_dir(profile_path);
+}
diff --git a/third_party/rust/init_rust_components/uniffi.toml b/third_party/rust/init_rust_components/uniffi.toml
@@ -0,0 +1,6 @@
+[bindings.kotlin]
+package_name = "mozilla.appservices.init_rust_components"
+
+[bindings.swift]
+ffi_module_name = "MozillaRustComponents"
+ffi_module_filename = "init_rust_componentsFFI"
diff --git a/third_party/rust/jwcrypto/.cargo-checksum.json b/third_party/rust/jwcrypto/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"19e1ca5fdbc89a5ad9e87e7d2f37ef081056b886661bddd28538a29a8bdcdc58","src/aes.rs":"2bb4d236ee2962365f81dc44b314cdcc9c186e0fac3a87a354ca198cdc59478b","src/direct.rs":"2f4065ba0939ca111054e295fc36956d217720c319f34e49b420fb363cf95989","src/ec.rs":"0b19519dce70c091c8060fd544c0e52a98d3110b6f7f54bab9aae30af77a6676","src/encdec.rs":"49aa30c70087ffa9fe28fa7304840670d4aa777902be28b402769121c8e1b459","src/error.rs":"ed6729b7ec07a37559069ab366cbbdf0869be2fefdec54e27550ef6a41397111","src/lib.rs":"440a04e5ed04eca90775ba1e5717c3c066572dd195d4ca08ac37c3f48da6fb62"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/jwcrypto/Cargo.toml b/third_party/rust/jwcrypto/Cargo.toml
@@ -0,0 +1,45 @@
+# 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 = "jwcrypto"
+version = "0.1.0"
+authors = ["Edouard Oger <eoger@fastmail.com>"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = false
+license = "MPL-2.0"
+
+[lib]
+name = "jwcrypto"
+crate-type = ["lib"]
+path = "src/lib.rs"
+
+[dependencies]
+base64 = "0.21"
+serde = "1"
+serde_derive = "1"
+serde_json = "1"
+thiserror = "2"
+
+[dependencies.error-support]
+path = "../error"
+
+[dependencies.rc_crypto]
+path = "../rc_crypto"
+
+[dev-dependencies.nss]
+path = "../rc_crypto/nss"
diff --git a/third_party/rust/jwcrypto/src/aes.rs b/third_party/rust/jwcrypto/src/aes.rs
@@ -0,0 +1,75 @@
+/* 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/. */
+
+// Wrappers we use around rc_crypto's AES implementation. Specifically,
+// "enc=A256GCM" from RFC7518, Section 4.7 - for all the gory details, see
+// https://tools.ietf.org/html/rfc7518#section-4.7.
+
+use crate::{
+ error::{JwCryptoError, Result},
+ CompactJwe, EncryptionAlgorithm, JweHeader,
+};
+use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+use rc_crypto::{aead, rand};
+
+/// Does the AES-encrypt heavy-lifting for the schemes supported by this crate.
+pub(crate) fn aes_gcm_encrypt(
+ data: &[u8],
+ protected_header: JweHeader,
+ content_encryption_key: &[u8],
+) -> Result<CompactJwe> {
+ assert_eq!(protected_header.enc, EncryptionAlgorithm::A256GCM);
+ let sealing_key = aead::SealingKey::new(&aead::AES_256_GCM, content_encryption_key)?;
+ let additional_data = serde_json::to_string(&protected_header)?;
+ let additional_data = URL_SAFE_NO_PAD.encode(additional_data.as_bytes());
+ let additional_data = additional_data.as_bytes();
+ let aad = aead::Aad::from(additional_data);
+ // Note that RFC7518 specifies an IV of 96 bits == 12 bytes - which means
+ // that a random IV generally isn't safe with AESGCM due to the risk of
+ // collisions in this many bits. However, for the use-cases supported by
+ // this crate, the keys are either ephemeral, or the number of encryptions
+ // for the same key is expected to be low enough to not collide in
+ // practice.
+ let mut iv: Vec<u8> = vec![0; 12];
+ rand::fill(&mut iv)?;
+ let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_256_GCM, &iv)?;
+ let mut encrypted = aead::seal(&sealing_key, nonce, aad, data)?;
+
+ let tag_idx = encrypted.len() - aead::AES_256_GCM.tag_len();
+ let auth_tag = encrypted.split_off(tag_idx);
+ let ciphertext = encrypted;
+
+ CompactJwe::new(
+ Some(protected_header),
+ None,
+ Some(iv),
+ ciphertext,
+ Some(auth_tag),
+ )
+}
+
+/// Does the AES-decrypt heavy-lifting for the schemes supported by this crate
+pub(crate) fn aes_gcm_decrypt(jwe: &CompactJwe, content_encryption_key: &[u8]) -> Result<String> {
+ let protected_header = jwe
+ .protected_header()?
+ .ok_or(JwCryptoError::IllegalState("missing protected_header"))?;
+ assert_eq!(protected_header.enc, EncryptionAlgorithm::A256GCM);
+ let auth_tag = jwe
+ .auth_tag()?
+ .ok_or(JwCryptoError::IllegalState("auth_tag must be present."))?;
+ if auth_tag.len() != aead::AES_256_GCM.tag_len() {
+ return Err(JwCryptoError::IllegalState(
+ "The auth tag length is incorrect",
+ ));
+ }
+ let iv = jwe
+ .iv()?
+ .ok_or(JwCryptoError::IllegalState("iv must be present."))?;
+ let opening_key = aead::OpeningKey::new(&aead::AES_256_GCM, content_encryption_key)?;
+ let ciphertext_and_tag: Vec<u8> = [jwe.ciphertext()?, auth_tag].concat();
+ let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_256_GCM, &iv)?;
+ let aad = aead::Aad::from(jwe.protected_header_raw().as_bytes());
+ let plaintext = aead::open(&opening_key, nonce, aad, &ciphertext_and_tag)?;
+ Ok(String::from_utf8(plaintext.to_vec())?)
+}
diff --git a/third_party/rust/jwcrypto/src/direct.rs b/third_party/rust/jwcrypto/src/direct.rs
@@ -0,0 +1,281 @@
+/* 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/. */
+
+//! Support for "Direct Encryption with a Shared Symmetric Key"
+//! See https://tools.ietf.org/html/rfc7518#section-4.5 for all the details.
+
+use crate::{
+ aes,
+ error::{JwCryptoError, Result},
+ Algorithm, CompactJwe, EncryptionAlgorithm, JweHeader, Jwk, JwkKeyParameters,
+};
+use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+use rc_crypto::rand;
+
+impl Jwk {
+ /// Create a new random key suitable for `Direct` symmetric encryption.
+ /// Consumers can store this for later use, probably via serde serialization.
+ pub fn new_direct_key(kid: Option<String>) -> Result<Self> {
+ // We only support AES256 which has a 32byte key.
+ let mut bytes: Vec<u8> = vec![0; 32];
+ rand::fill(&mut bytes)?;
+ Ok(Jwk {
+ kid,
+ key_parameters: JwkKeyParameters::Direct {
+ k: URL_SAFE_NO_PAD.encode(&bytes),
+ },
+ })
+ }
+
+ // Create a new Jwk given the raw bytes of a `Direct` key. We generally
+ // prefer consumers to use serde with the entire key.
+ pub fn new_direct_from_bytes(kid: Option<String>, key: &[u8]) -> Self {
+ Jwk {
+ kid,
+ key_parameters: JwkKeyParameters::Direct {
+ k: URL_SAFE_NO_PAD.encode(key),
+ },
+ }
+ }
+}
+
+pub(crate) fn encrypt_to_jwe(
+ data: &[u8],
+ enc: EncryptionAlgorithm,
+ jwk: &Jwk,
+) -> Result<CompactJwe> {
+ // It's slightly unfortunate we need to supply a struct with ECDH specific
+ // values all specified as None, but doesn't seem likely to ever actually hurt.
+ let protected_header = JweHeader {
+ kid: jwk.kid.clone(),
+ alg: Algorithm::Direct,
+ enc,
+ epk: None,
+ apu: None,
+ apv: None,
+ };
+ let secret = match &jwk.key_parameters {
+ JwkKeyParameters::Direct { k } => URL_SAFE_NO_PAD.decode(k)?,
+ _ => return Err(JwCryptoError::IllegalState("Not a Direct key")),
+ };
+ aes::aes_gcm_encrypt(data, protected_header, &secret)
+}
+
+pub(crate) fn decrypt_jwe(jwe: &CompactJwe, jwk: Jwk) -> Result<String> {
+ let secret = match jwk.key_parameters {
+ JwkKeyParameters::Direct { k } => URL_SAFE_NO_PAD.decode(k)?,
+ _ => return Err(JwCryptoError::IllegalState("Not a Direct key")),
+ };
+ // `alg="dir"` mandates no encrypted key.
+ if jwe.encrypted_key()?.is_some() {
+ return Err(JwCryptoError::IllegalState(
+ "The Encrypted Key must be empty.",
+ ));
+ }
+ aes::aes_gcm_decrypt(jwe, &secret)
+}
+
+#[test]
+fn test_simple_roundtrip() {
+ // We should be able to round-trip data.
+ use super::{decrypt_jwe, encrypt_to_jwe, DecryptionParameters, EncryptionParameters};
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_key(Some("my key".to_string())).unwrap();
+ let data = "to be, or not 🐝🐝";
+ let encrypted = encrypt_to_jwe(
+ data.as_bytes(),
+ EncryptionParameters::Direct {
+ jwk: &jwk,
+ enc: EncryptionAlgorithm::A256GCM,
+ },
+ )
+ .unwrap();
+ let decrypted = decrypt_jwe(&encrypted, DecryptionParameters::Direct { jwk }).unwrap();
+ assert_eq!(data, decrypted);
+}
+
+#[test]
+fn test_modified_ciphertext() {
+ // Modifying the ciphertext will fail.
+ use super::{decrypt_jwe, encrypt_to_jwe, DecryptionParameters, EncryptionParameters};
+ use nss::ensure_initialized;
+ use std::str::FromStr;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_key(Some("my key".to_string())).unwrap();
+ let data = "to be, or not 🐝🐝";
+ let encrypted = encrypt_to_jwe(
+ data.as_bytes(),
+ EncryptionParameters::Direct {
+ jwk: &jwk,
+ enc: EncryptionAlgorithm::A256GCM,
+ },
+ )
+ .unwrap();
+ // additional text
+ assert!(matches!(
+ decrypt_jwe(
+ &(encrypted.clone() + "A"),
+ DecryptionParameters::Direct { jwk: jwk.clone() }
+ ),
+ Err(JwCryptoError::IllegalState(_))
+ ));
+ // truncated text
+ assert!(matches!(
+ decrypt_jwe(
+ &(encrypted[0..encrypted.len() - 2]),
+ DecryptionParameters::Direct { jwk: jwk.clone() }
+ ),
+ Err(JwCryptoError::IllegalState(_))
+ ));
+ // modified ciphertext - to make this test meaningful we need to
+ // reconsitute the CompactJwe and modify that, otherwise we are just going
+ // to get a base64 or json error.
+ let jwe = CompactJwe::from_str(&encrypted).unwrap();
+ let mut new_ciphertext = jwe.ciphertext().unwrap();
+ new_ciphertext[0] = new_ciphertext[0].wrapping_add(1);
+ let jwe_modified = CompactJwe::new(
+ jwe.protected_header().unwrap(),
+ jwe.encrypted_key().unwrap(),
+ jwe.iv().unwrap(),
+ new_ciphertext,
+ jwe.auth_tag().unwrap(),
+ )
+ .unwrap();
+
+ // phew - finally (fail to) decrypt the modified ciphertext.
+ assert!(matches!(
+ decrypt_jwe(
+ &jwe_modified.to_string(),
+ DecryptionParameters::Direct { jwk }
+ ),
+ Err(JwCryptoError::CryptoError(_))
+ ));
+}
+
+#[test]
+fn test_iv() {
+ // Encrypting the same thing twice should give different payloads due to
+ // different IV.
+ use super::{encrypt_to_jwe, EncryptionParameters};
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_key(Some("my key".to_string())).unwrap();
+ let data = "to be, or not 🐝🐝";
+ let e1 = encrypt_to_jwe(
+ data.as_bytes(),
+ EncryptionParameters::Direct {
+ enc: EncryptionAlgorithm::A256GCM,
+ jwk: &jwk,
+ },
+ )
+ .unwrap();
+ let e2 = encrypt_to_jwe(
+ data.as_bytes(),
+ EncryptionParameters::Direct {
+ jwk: &jwk,
+ enc: EncryptionAlgorithm::A256GCM,
+ },
+ )
+ .unwrap();
+ assert_ne!(e1, e2);
+}
+
+#[test]
+fn test_jose() {
+ // ciphertext generated by node-jose via:
+ /*
+ const parseJwk = require("jose/jwk/parse").default;
+ const CompactEncrypt = require("jose/jwe/compact/encrypt").default;
+ const encoder = new TextEncoder();
+ const payload = "Hello, World!";
+ const key = "asecret256bitkeyasecret256bitkey";
+ parseJwk({kty: "oct", k: Buffer.from(key).toString("base64")}, "A256GCM").then(key => {
+ new CompactEncrypt(encoder.encode(payload))
+ .setProtectedHeader({ alg: "dir", enc: "A256GCM" })
+ .encrypt(key)
+ .then(jwe => {
+ console.log(jwe);
+ });
+ })
+ */
+ // (A note for future readers - we tried using python-jose, but it
+ // generated a 16 byte nonce, where the spec clearly calls for exactly 12
+ // bytes. We could decrypt that python-jose payload if we modified
+ // `Nonce::try_assume_unique_for_key()` to allow a longer key, but we don't
+ // want to do that until we have evidence it's actually spec compliant.)
+ use super::{decrypt_jwe, DecryptionParameters};
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_from_bytes(None, "asecret256bitkeyasecret256bitkey".as_bytes());
+ let ciphertext = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..nhKdQEKqoKPzfCda.rQOj0Nfs6wO5Gj4Quw.CMJFS9YBADLLePdj1sssSg";
+ let decrypted = decrypt_jwe(ciphertext, DecryptionParameters::Direct { jwk }).unwrap();
+ assert_eq!(decrypted, "Hello, World!");
+}
+
+#[test]
+fn test_bad_key() {
+ use super::{decrypt_jwe, DecryptionParameters};
+ use crate::error::JwCryptoError;
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_from_bytes(None, "a_wrong256bitkeya_wrong256bitkey".as_bytes());
+ let ciphertext = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..nhKdQEKqoKPzfCda.rQOj0Nfs6wO5Gj4Quw.CMJFS9YBADLLePdj1sssSg";
+ assert!(matches!(
+ decrypt_jwe(ciphertext, DecryptionParameters::Direct { jwk }),
+ Err(JwCryptoError::CryptoError(_))
+ ));
+}
+
+#[test]
+fn test_bad_key_type() {
+ use super::{encrypt_to_jwe, EncryptionParameters};
+ use crate::error::JwCryptoError;
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let jwk = Jwk::new_direct_key(Some("my key".to_string())).unwrap();
+ let data = b"The big brown fox fell down";
+ assert!(matches!(
+ encrypt_to_jwe(
+ data,
+ EncryptionParameters::ECDH_ES {
+ enc: EncryptionAlgorithm::A256GCM,
+ peer_jwk: &jwk,
+ },
+ ),
+ Err(JwCryptoError::IllegalState(_))
+ ));
+}
+
+#[test]
+fn test_bad_key_type_direct() {
+ use super::{EncryptionAlgorithm, EphemeralKeyPair};
+ use nss::ensure_initialized;
+ use rc_crypto::agreement;
+
+ use crate::error::JwCryptoError;
+
+ ensure_initialized();
+
+ let key_pair = EphemeralKeyPair::generate(&agreement::ECDH_P256).unwrap();
+ let jwk = crate::ec::extract_pub_key_jwk(&key_pair).unwrap();
+
+ let data = b"The big brown fox fell down";
+ assert!(matches!(
+ encrypt_to_jwe(data, EncryptionAlgorithm::A256GCM, &jwk,),
+ Err(JwCryptoError::IllegalState(_))
+ ));
+}
diff --git a/third_party/rust/jwcrypto/src/ec.rs b/third_party/rust/jwcrypto/src/ec.rs
@@ -0,0 +1,227 @@
+/* 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/. */
+
+//! Implements Elliptic-Curve Diffie-Hellman for JWE - specifically, the
+//! "Ephemeral-Static direct key agreement" mode described in
+//! https://tools.ietf.org/html/rfc7518#section-4.6
+
+use crate::{
+ aes,
+ error::{JwCryptoError, Result},
+ Algorithm, CompactJwe, EncryptionAlgorithm, JweHeader, Jwk, JwkKeyParameters,
+};
+use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+use rc_crypto::{
+ agreement::{self, EphemeralKeyPair, InputKeyMaterial, UnparsedPublicKey},
+ digest,
+};
+use serde_derive::{Deserialize, Serialize};
+
+/// Key params specific to ECDH encryption.
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct ECKeysParameters {
+ pub crv: String,
+ pub x: String,
+ pub y: String,
+}
+
+/// The ECDH helper that takes the cleartext and key, creates the appropriate
+/// header, then calls the `aes` module to do the actual encryption.
+pub(crate) fn encrypt_to_jwe(
+ data: &[u8],
+ enc: EncryptionAlgorithm,
+ peer_jwk: &Jwk,
+) -> Result<CompactJwe> {
+ let local_key_pair = EphemeralKeyPair::generate(&agreement::ECDH_P256)?;
+ let local_public_key = extract_pub_key_jwk(&local_key_pair)?;
+ let ec_key_params = match peer_jwk.key_parameters {
+ JwkKeyParameters::EC(ref params) => params,
+ _ => return Err(JwCryptoError::IllegalState("Not an EC key")),
+ };
+ let protected_header = JweHeader {
+ kid: peer_jwk.kid.clone(),
+ alg: Algorithm::ECDH_ES,
+ enc,
+ epk: Some(local_public_key),
+ apu: None,
+ apv: None,
+ };
+ let secret = derive_shared_secret(&protected_header, local_key_pair, ec_key_params)?;
+ match protected_header.enc {
+ EncryptionAlgorithm::A256GCM => {
+ aes::aes_gcm_encrypt(data, protected_header, secret.as_ref())
+ }
+ }
+}
+
+/// The ECDH helper that takes the ciphertext in the form of a CompactJwe,
+/// and the keys, creates the appropriate header, then calls the `aes` module to
+/// do the actual decryption.
+pub(crate) fn decrypt_jwe(jwe: &CompactJwe, local_key_pair: EphemeralKeyPair) -> Result<String> {
+ // Part 0: Validate inputs.
+ let protected_header = jwe.protected_header()?.ok_or(JwCryptoError::IllegalState(
+ "protected_header must be present.",
+ ))?;
+ if protected_header.alg != Algorithm::ECDH_ES {
+ return Err(JwCryptoError::IllegalState("alg mismatch."));
+ }
+ // `alg="ECDH-ES"` mandates no encrypted key.
+ if jwe.encrypted_key()?.is_some() {
+ return Err(JwCryptoError::IllegalState(
+ "The Encrypted Key must be empty.",
+ ));
+ }
+
+ // Part 1: Reconstruct the secret.
+ let peer_jwk = protected_header
+ .epk
+ .as_ref()
+ .ok_or(JwCryptoError::IllegalState("epk not present"))?;
+
+ let ec_key_params = match peer_jwk.key_parameters {
+ JwkKeyParameters::EC(ref params) => params,
+ _ => return Err(JwCryptoError::IllegalState("Not an EC key")),
+ };
+
+ let secret = derive_shared_secret(&protected_header, local_key_pair, ec_key_params)?;
+
+ // Part 2: decrypt the payload
+ match protected_header.enc {
+ EncryptionAlgorithm::A256GCM => aes::aes_gcm_decrypt(jwe, secret.as_ref()),
+ }
+}
+
+fn derive_shared_secret(
+ protected_header: &JweHeader,
+ local_key_pair: EphemeralKeyPair,
+ peer_key: &ECKeysParameters,
+) -> Result<digest::Digest> {
+ let (private_key, _) = local_key_pair.split();
+ let peer_public_key_raw_bytes = public_key_from_ec_params(peer_key)?;
+ let peer_public_key = UnparsedPublicKey::new(&agreement::ECDH_P256, &peer_public_key_raw_bytes);
+ // Note: We don't support key-wrapping, but if we did `algorithm_id` would be `alg` instead.
+ let algorithm_id = protected_header.enc.algorithm_id();
+ let ikm = private_key.agree(&peer_public_key)?;
+ let apu = protected_header.apu.as_deref().unwrap_or_default();
+ let apv = protected_header.apv.as_deref().unwrap_or_default();
+ get_secret_from_ikm(ikm, apu, apv, algorithm_id)
+}
+
+fn public_key_from_ec_params(jwk: &ECKeysParameters) -> Result<Vec<u8>> {
+ let x = URL_SAFE_NO_PAD.decode(&jwk.x)?;
+ let y = URL_SAFE_NO_PAD.decode(&jwk.y)?;
+ if jwk.crv != "P-256" {
+ return Err(JwCryptoError::PartialImplementation(
+ "Only P-256 curves are supported.",
+ ));
+ }
+ if x.len() != (256 / 8) {
+ return Err(JwCryptoError::IllegalState("X must be 32 bytes long."));
+ }
+ if y.len() != (256 / 8) {
+ return Err(JwCryptoError::IllegalState("Y must be 32 bytes long."));
+ }
+ let mut peer_pub_key: Vec<u8> = vec![0x04];
+ peer_pub_key.extend_from_slice(&x);
+ peer_pub_key.extend_from_slice(&y);
+ Ok(peer_pub_key)
+}
+
+fn get_secret_from_ikm(
+ ikm: InputKeyMaterial,
+ apu: &str,
+ apv: &str,
+ alg: &str,
+) -> Result<digest::Digest> {
+ let secret = ikm.derive(|z| {
+ let mut buf: Vec<u8> = vec![];
+ // ConcatKDF (1 iteration since keyLen <= hashLen).
+ // See rfc7518 section 4.6 for reference.
+ buf.extend_from_slice(&1u32.to_be_bytes());
+ buf.extend_from_slice(z);
+ // otherinfo
+ buf.extend_from_slice(&(alg.len() as u32).to_be_bytes());
+ buf.extend_from_slice(alg.as_bytes());
+ buf.extend_from_slice(&(apu.len() as u32).to_be_bytes());
+ buf.extend_from_slice(apu.as_bytes());
+ buf.extend_from_slice(&(apv.len() as u32).to_be_bytes());
+ buf.extend_from_slice(apv.as_bytes());
+ buf.extend_from_slice(&256u32.to_be_bytes());
+ digest::digest(&digest::SHA256, &buf)
+ })?;
+ Ok(secret)
+}
+
+/// Extracts the public key from an [EphemeralKeyPair] as a [Jwk].
+pub fn extract_pub_key_jwk(key_pair: &EphemeralKeyPair) -> Result<Jwk> {
+ let pub_key_bytes = key_pair.public_key().to_bytes()?;
+ // Uncompressed form (see SECG SEC1 section 2.3.3).
+ // First byte is 4, then 32 bytes for x, and 32 bytes for y.
+ assert_eq!(pub_key_bytes.len(), 1 + 32 + 32);
+ assert_eq!(pub_key_bytes[0], 0x04);
+ let x = Vec::from(&pub_key_bytes[1..33]);
+ let x = URL_SAFE_NO_PAD.encode(x);
+ let y = Vec::from(&pub_key_bytes[33..]);
+ let y = URL_SAFE_NO_PAD.encode(y);
+ Ok(Jwk {
+ kid: None,
+ key_parameters: JwkKeyParameters::EC(ECKeysParameters {
+ crv: "P-256".to_owned(),
+ x,
+ y,
+ }),
+ })
+}
+
+#[test]
+fn test_encrypt_decrypt_jwe_ecdh_es() {
+ use super::{decrypt_jwe, encrypt_to_jwe, DecryptionParameters, EncryptionParameters};
+ use nss::ensure_initialized;
+ use rc_crypto::agreement;
+
+ ensure_initialized();
+
+ let key_pair = EphemeralKeyPair::generate(&agreement::ECDH_P256).unwrap();
+ let jwk = extract_pub_key_jwk(&key_pair).unwrap();
+ let data = b"The big brown fox jumped over... What?";
+ let encrypted = encrypt_to_jwe(
+ data,
+ EncryptionParameters::ECDH_ES {
+ enc: EncryptionAlgorithm::A256GCM,
+ peer_jwk: &jwk,
+ },
+ )
+ .unwrap();
+ let decrypted = decrypt_jwe(
+ &encrypted,
+ DecryptionParameters::ECDH_ES {
+ local_key_pair: key_pair,
+ },
+ )
+ .unwrap();
+ assert_eq!(decrypted, std::str::from_utf8(data).unwrap());
+}
+
+#[test]
+fn test_bad_key_type() {
+ use super::{encrypt_to_jwe, EncryptionParameters};
+ use crate::error::JwCryptoError;
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+
+ let key_pair = EphemeralKeyPair::generate(&agreement::ECDH_P256).unwrap();
+ let jwk = extract_pub_key_jwk(&key_pair).unwrap();
+ let data = b"The big brown fox fell down";
+ assert!(matches!(
+ encrypt_to_jwe(
+ data,
+ EncryptionParameters::Direct {
+ enc: EncryptionAlgorithm::A256GCM,
+ jwk: &jwk
+ },
+ ),
+ Err(JwCryptoError::IllegalState(_))
+ ));
+}
diff --git a/third_party/rust/jwcrypto/src/encdec.rs b/third_party/rust/jwcrypto/src/encdec.rs
@@ -0,0 +1,101 @@
+/* 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 crate::{JwCryptoError, Jwk};
+use serde::{de::DeserializeOwned, Serialize};
+
+/// High-level struct for handling Encryption/Decryption
+pub struct EncryptorDecryptor {
+ jwk: Jwk,
+}
+
+impl EncryptorDecryptor {
+ /// Create a key that can be used to construct an EncryptorDecryptor
+ pub fn create_key() -> Result<String, JwCryptoError> {
+ let key = crate::Jwk::new_direct_key(None)?;
+ Ok(serde_json::to_string(&key)?)
+ }
+
+ pub fn new(key: &str) -> Result<Self, JwCryptoError> {
+ match serde_json::from_str(key) {
+ Ok(jwk) => Ok(Self { jwk }),
+ Err(_) => Err(JwCryptoError::InvalidKey),
+ }
+ }
+
+ pub fn new_with_random_key() -> Result<Self, JwCryptoError> {
+ Self::new(&Self::create_key()?)
+ }
+
+ /// Encrypt a string
+ ///
+ /// `description` is a developer-friendly description of the operation that gets reported to Sentry
+ /// on crypto errors.
+ pub fn encrypt(&self, cleartext: &str) -> Result<String, JwCryptoError> {
+ crate::encrypt_to_jwe(
+ cleartext.as_bytes(),
+ crate::EncryptionParameters::Direct {
+ enc: crate::EncryptionAlgorithm::A256GCM,
+ jwk: &self.jwk,
+ },
+ )
+ }
+
+ /// Encrypt a struct
+ ///
+ /// `description` is a developer-friendly description of the operation that gets reported to Sentry
+ /// on crypto errors.
+ pub fn encrypt_struct<T: Serialize>(&self, fields: &T) -> Result<String, JwCryptoError> {
+ let str = serde_json::to_string(fields)?;
+ self.encrypt(&str)
+ }
+
+ /// Decrypt a string
+ ///
+ /// `description` is a developer-friendly description of the operation that gets reported to Sentry
+ /// on crypto errors.
+ pub fn decrypt(&self, ciphertext: &str) -> Result<String, JwCryptoError> {
+ if ciphertext.is_empty() {
+ return Err(JwCryptoError::EmptyCyphertext);
+ }
+ crate::decrypt_jwe(
+ ciphertext,
+ crate::DecryptionParameters::Direct {
+ jwk: self.jwk.clone(),
+ },
+ )
+ }
+
+ /// Decrypt a struct
+ ///
+ /// `description` is a developer-friendly description of the operation that gets reported to Sentry
+ /// on crypto errors.
+ pub fn decrypt_struct<T: DeserializeOwned>(
+ &self,
+ ciphertext: &str,
+ ) -> Result<T, JwCryptoError> {
+ let json = self.decrypt(ciphertext)?;
+ Ok(serde_json::from_str(&json)?)
+ }
+
+ // Create canary text.
+ //
+ // These are used to check if a key is still valid for a database. Call this when opening a
+ // database for the first time and save the result.
+ pub fn create_canary(&self, text: &str) -> Result<String, JwCryptoError> {
+ self.encrypt(text)
+ }
+
+ // Create canary text.
+ //
+ // These are used to check if a key is still valid for a database. Call this when re-opening a
+ // database, using the same text parameter and the return value of the initial check_canary call.
+ //
+ // - If check_canary() returns true, then it's safe to assume the key can decrypt the DB data
+ // - If check_canary() returns false, then the key is no longer valid. It should be
+ // regenerated and the DB data should be wiped since we can no longer read it properly
+ pub fn check_canary(&self, canary: &str, text: &str) -> Result<bool, JwCryptoError> {
+ Ok(self.decrypt(canary)? == text)
+ }
+}
diff --git a/third_party/rust/jwcrypto/src/error.rs b/third_party/rust/jwcrypto/src/error.rs
@@ -0,0 +1,29 @@
+/* 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 thiserror::Error;
+
+pub(crate) type Result<T> = std::result::Result<T, JwCryptoError>;
+
+#[derive(Error, Debug)]
+pub enum JwCryptoError {
+ #[error("Deserialization error")]
+ DeserializationError,
+ #[error("Illegal state error: {0}")]
+ IllegalState(&'static str),
+ #[error("Partial implementation error: {0}")]
+ PartialImplementation(&'static str),
+ #[error("Base64 decode error: {0}")]
+ Base64Decode(#[from] base64::DecodeError),
+ #[error("Crypto error: {0}")]
+ CryptoError(#[from] rc_crypto::Error),
+ #[error("JSON error: {0}")]
+ JsonError(#[from] serde_json::Error),
+ #[error("UTF8 decode error: {0}")]
+ UTF8DecodeError(#[from] std::string::FromUtf8Error),
+ #[error("InvalidKey")]
+ InvalidKey,
+ #[error("EmptyCyphertext")]
+ EmptyCyphertext,
+}
diff --git a/third_party/rust/jwcrypto/src/lib.rs b/third_party/rust/jwcrypto/src/lib.rs
@@ -0,0 +1,323 @@
+/* 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/. */
+
+//! A library for using JSON Object Signing and Encryption (JOSE) data formats
+//! such as JWE and JWK, as described in https://tools.ietf.org/html/rfc7518
+//! and related standards.
+//! The encryption is done by [rc_crypto] - this crate just does the JOSE
+//! wrappers around this crypto. As a result, most of the structs etc here
+//! support serialization and deserialization to and from JSON via serde in
+//! a way that's compatible with rfc7518 etc.
+
+// Theoretically, everything done in this crate could and should be done in a JWT library.
+// However, none of the existing rust JWT libraries can handle ECDH-ES encryption, and API choices
+// made by their authors make it difficult to add this feature.
+// In the past, we chose cjose to do that job, but it added three C dependencies to build and link
+// against: jansson, openssl and cjose itself.
+// So now, this *is* our JWT library.
+
+use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+pub use error::JwCryptoError;
+use error::Result;
+use rc_crypto::agreement::EphemeralKeyPair;
+use serde_derive::{Deserialize, Serialize};
+use std::{fmt, str::FromStr};
+
+mod aes;
+mod direct;
+pub mod ec;
+mod encdec;
+mod error;
+
+pub use encdec::EncryptorDecryptor;
+
+/// Specifies the mode, algorithm and keys of the encryption operation.
+pub enum EncryptionParameters<'a> {
+ // ECDH-ES in Direct Key Agreement mode.
+ #[allow(non_camel_case_types)]
+ ECDH_ES {
+ enc: EncryptionAlgorithm,
+ peer_jwk: &'a Jwk,
+ },
+ // Direct Encryption with a shared symmetric key.
+ Direct {
+ enc: EncryptionAlgorithm,
+ jwk: &'a Jwk,
+ },
+}
+
+/// Specifies the mode and keys of the decryption operation.
+pub enum DecryptionParameters {
+ // ECDH-ES in Direct Key Agreement mode.
+ #[allow(non_camel_case_types)]
+ ECDH_ES {
+ local_key_pair: EphemeralKeyPair,
+ },
+ // Direct with a shared symmetric key.
+ Direct {
+ jwk: Jwk,
+ },
+}
+
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
+enum Algorithm {
+ #[serde(rename = "ECDH-ES")]
+ #[allow(non_camel_case_types)]
+ ECDH_ES,
+ #[serde(rename = "dir")]
+ Direct,
+}
+
+/// The encryption algorithms supported by this crate.
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
+pub enum EncryptionAlgorithm {
+ A256GCM,
+}
+
+impl EncryptionAlgorithm {
+ fn algorithm_id(&self) -> &'static str {
+ match self {
+ Self::A256GCM => "A256GCM",
+ }
+ }
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+struct JweHeader {
+ alg: Algorithm,
+ enc: EncryptionAlgorithm,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ kid: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ epk: Option<Jwk>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ apu: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ apv: Option<String>,
+}
+
+/// Defines the key to use for all operations in this crate.
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct Jwk {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub kid: Option<String>,
+ #[serde(flatten)]
+ pub key_parameters: JwkKeyParameters,
+}
+
+/// The enum passed in to hold the encryption and decryption keys. The variant
+/// of the enum must match the variant of the Encryption/Decryption parameters
+/// or the encryption/decryption operations will fail.
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+#[serde(tag = "kty")]
+pub enum JwkKeyParameters {
+ /// When doing ECDH (asymmetric) encryption, you specify elliptic curve points.
+ EC(ec::ECKeysParameters),
+ /// When doing Direct (symmetric) encryption, you specify random bytes of
+ /// the appropriate length, base64 encoded.
+ #[serde(rename = "oct")] // rfc7518 section-6.1 specifies "oct" as key-type...
+ Direct { k: String }, // ...and "k" for the base64 value.
+}
+
+/// Internal representation of a CompactJwe. The public interface of this
+/// crate is all via strings, so it's not public.
+#[derive(Debug)]
+struct CompactJwe {
+ jwe_segments: Vec<String>,
+}
+
+impl CompactJwe {
+ // A builder pattern would be nicer, but this will do for now.
+ fn new(
+ protected_header: Option<JweHeader>,
+ encrypted_key: Option<Vec<u8>>,
+ iv: Option<Vec<u8>>,
+ ciphertext: Vec<u8>,
+ auth_tag: Option<Vec<u8>>,
+ ) -> Result<Self> {
+ let protected_header = protected_header
+ .as_ref()
+ .map(|h| serde_json::to_string(&h))
+ .transpose()?
+ .map(|h| URL_SAFE_NO_PAD.encode(h))
+ .unwrap_or_default();
+ let encrypted_key = encrypted_key
+ .as_ref()
+ .map(|k| URL_SAFE_NO_PAD.encode(k))
+ .unwrap_or_default();
+ let iv = iv
+ .as_ref()
+ .map(|iv| URL_SAFE_NO_PAD.encode(iv))
+ .unwrap_or_default();
+ let ciphertext = URL_SAFE_NO_PAD.encode(ciphertext);
+ let auth_tag = auth_tag
+ .as_ref()
+ .map(|t| URL_SAFE_NO_PAD.encode(t))
+ .unwrap_or_default();
+ let jwe_segments = vec![protected_header, encrypted_key, iv, ciphertext, auth_tag];
+ Ok(Self { jwe_segments })
+ }
+
+ fn protected_header(&self) -> Result<Option<JweHeader>> {
+ Ok(self
+ .try_deserialize_base64_segment(0)?
+ .map(|s| serde_json::from_slice(&s))
+ .transpose()?)
+ }
+
+ fn protected_header_raw(&self) -> &str {
+ &self.jwe_segments[0]
+ }
+
+ fn encrypted_key(&self) -> Result<Option<Vec<u8>>> {
+ self.try_deserialize_base64_segment(1)
+ }
+
+ fn iv(&self) -> Result<Option<Vec<u8>>> {
+ self.try_deserialize_base64_segment(2)
+ }
+
+ fn ciphertext(&self) -> Result<Vec<u8>> {
+ self.try_deserialize_base64_segment(3)?
+ .ok_or(JwCryptoError::IllegalState("Ciphertext is empty"))
+ }
+
+ fn auth_tag(&self) -> Result<Option<Vec<u8>>> {
+ self.try_deserialize_base64_segment(4)
+ }
+
+ fn try_deserialize_base64_segment(&self, index: usize) -> Result<Option<Vec<u8>>> {
+ Ok(match self.jwe_segments[index].is_empty() {
+ true => None,
+ false => Some(URL_SAFE_NO_PAD.decode(&self.jwe_segments[index])?),
+ })
+ }
+}
+
+impl FromStr for CompactJwe {
+ type Err = JwCryptoError;
+ fn from_str(str: &str) -> Result<Self> {
+ let jwe_segments: Vec<String> = str.split('.').map(|s| s.to_owned()).collect();
+ if jwe_segments.len() != 5 {
+ error_support::breadcrumb!(
+ "Error in CompactJwe::from_str ({})",
+ error_support::redact_compact_jwe(str)
+ );
+ return Err(JwCryptoError::DeserializationError);
+ }
+ Ok(Self { jwe_segments })
+ }
+}
+
+impl fmt::Display for CompactJwe {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ assert!(self.jwe_segments.len() == 5);
+ write!(f, "{}", self.jwe_segments.join("."))
+ }
+}
+
+/// Encrypt and serialize data in the JWE compact form.
+pub fn encrypt_to_jwe(data: &[u8], encryption_params: EncryptionParameters) -> Result<String> {
+ let jwe = match encryption_params {
+ EncryptionParameters::ECDH_ES { enc, peer_jwk } => ec::encrypt_to_jwe(data, enc, peer_jwk),
+ EncryptionParameters::Direct { enc, jwk } => direct::encrypt_to_jwe(data, enc, jwk),
+ }?;
+ Ok(jwe.to_string())
+}
+
+/// Deserialize and decrypt data in the JWE compact form.
+pub fn decrypt_jwe(jwe: &str, decryption_params: DecryptionParameters) -> Result<String> {
+ let jwe = jwe.parse()?;
+ match decryption_params {
+ DecryptionParameters::ECDH_ES { local_key_pair } => ec::decrypt_jwe(&jwe, local_key_pair),
+ DecryptionParameters::Direct { jwk } => direct::decrypt_jwe(&jwe, jwk),
+ }
+}
+
+#[test]
+fn test_jwk_ec_deser_with_kid() {
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+ let jwk = Jwk {
+ kid: Some("the-key-id".to_string()),
+ key_parameters: JwkKeyParameters::EC(ec::ECKeysParameters {
+ crv: "CRV".to_string(),
+ x: "X".to_string(),
+ y: "Y".to_string(),
+ }),
+ };
+ let jstr = serde_json::to_string(&jwk).unwrap();
+ // Make sure all the tags get the right info by checking the literal string.
+ assert_eq!(
+ jstr,
+ r#"{"kid":"the-key-id","kty":"EC","crv":"CRV","x":"X","y":"Y"}"#
+ );
+ // And check it round-trips.
+ assert_eq!(jwk, serde_json::from_str(&jstr).unwrap());
+}
+
+#[test]
+fn test_jwk_deser_no_kid() {
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+ let jwk = Jwk {
+ kid: None,
+ key_parameters: JwkKeyParameters::EC(ec::ECKeysParameters {
+ crv: "CRV".to_string(),
+ x: "X".to_string(),
+ y: "Y".to_string(),
+ }),
+ };
+ let jstr = serde_json::to_string(&jwk).unwrap();
+ // Make sure all the tags get the right info by checking the literal string.
+ assert_eq!(jstr, r#"{"kty":"EC","crv":"CRV","x":"X","y":"Y"}"#);
+ // And check it round-trips.
+ assert_eq!(jwk, serde_json::from_str(&jstr).unwrap());
+}
+
+#[test]
+fn test_jwk_direct_deser_with_kid() {
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+ let jwk = Jwk::new_direct_from_bytes(Some("key-id".to_string()), &[0, 1, 2, 3]);
+ let jstr = serde_json::to_string(&jwk).unwrap();
+ // Make sure all the tags get the right info by checking the literal string.
+ assert_eq!(jstr, r#"{"kid":"key-id","kty":"oct","k":"AAECAw"}"#);
+ // And check it round-trips.
+ assert_eq!(jwk, serde_json::from_str(&jstr).unwrap());
+}
+
+#[test]
+fn test_compact_jwe_roundtrip() {
+ use nss::ensure_initialized;
+
+ ensure_initialized();
+ let mut iv = [0u8; 16];
+ rc_crypto::rand::fill(&mut iv).unwrap();
+ let mut ciphertext = [0u8; 243];
+ rc_crypto::rand::fill(&mut ciphertext).unwrap();
+ let mut auth_tag = [0u8; 16];
+ rc_crypto::rand::fill(&mut auth_tag).unwrap();
+ let jwe = CompactJwe::new(
+ Some(JweHeader {
+ alg: Algorithm::ECDH_ES,
+ enc: EncryptionAlgorithm::A256GCM,
+ kid: None,
+ epk: None,
+ apu: None,
+ apv: None,
+ }),
+ None,
+ Some(iv.to_vec()),
+ ciphertext.to_vec(),
+ Some(auth_tag.to_vec()),
+ )
+ .unwrap();
+ let compacted = jwe.to_string();
+ let jwe2: CompactJwe = compacted.parse().unwrap();
+ assert_eq!(jwe.jwe_segments, jwe2.jwe_segments);
+}
diff --git a/third_party/rust/logins/.cargo-checksum.json b/third_party/rust/logins/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"932aaba3c932b809da6c86cc2c808cbba983011b923545674e62dc3a164867eb","README.md":"2c25808f8371b5d9ceb58e51f71304a270d5b33dad5a280a6e95e06e606f4492","build.rs":"63ff52215682b7d516679e7aaeaaaf5d3ac98ebdf0c08361193c34c99506bfdf","fixtures/profile/.gitignore":"611878d7fde9ba090134c1d0caffe525e69d63a46b7f6060ce8ca061b8524e59","fixtures/profile/README.md":"a801e141cf954b809aed59d7a0f3a573dce23231035dbab95c6350117c346a75","fixtures/profile/key4.db":"065522fb32423422a99ed096bee267f28068881b186a9258c8f0efc19f7bd89b","metrics.yaml":"a875db3d9d759935f43131bd5c830307f8fe5d42df0e47768deb91e4568d0f6b","src/db.rs":"0c52daac61d9d91d2197e3033e19fea0c62545776e92ba138d5e2708ebe13825","src/encryption.rs":"30d4683ba394b61f52713c05bc96296333f5eda0e841820b7b4f82be7bbd9381","src/error.rs":"236b8d9b5b497204cbe7a528adb07ceed16c421706a36ebeb88e1bfe259d0ded","src/lib.rs":"31e8775f54fc3871b9096140df80df538bbe13b3f7263841affe365c7862ae8f","src/login.rs":"ef152c51b38be6ae6edb2890fd5972dd1fe66d7fdb5af803f8709375e3860fa4","src/logins.udl":"92efe79861974a15e42a889e7ea2bc0d44f1089b78d23122f490fd2cf9020828","src/schema.rs":"a652eec0b5ada90b8ed9ac481616d070f212ebd1b4238b0bc1b7768700c55ffc","src/store.rs":"772bba97f3f8fc579be850e6647d4c9b36f8d0a8b9488c06a6be93c3e02ebe77","src/sync/engine.rs":"62f4812b68962b7c55857314afd30adc3e00bd18335b71b40e110284679c6c29","src/sync/merge.rs":"6469f8bd582358c96bc35579ac228c95ad4bd64e84a29dda0cde0d87d2dcc5ed","src/sync/mod.rs":"00eb3bdd5fcac411fb314400a3d66aea874aa117db1003caf75ea43d385e372e","src/sync/payload.rs":"202f56cf0af9ffc3cc3d57c72ad61e4fa006bf5104386d9ef58a2611d539accb","src/sync/update_plan.rs":"c1d45f5972237785e274b1ecbd350cef7c1d7f530e66b9068d707eb1dfa1304e","src/util.rs":"1ced78e185164640e9859b0316f4798ccacd30bad9d6c549f9f650350a5f97b6","uniffi.toml":"1b1ea1a488fc051b9fe5a289e474462f7c676bcd02ca176713d885d280414bf6"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/logins/Cargo.toml b/third_party/rust/logins/Cargo.toml
@@ -0,0 +1,110 @@
+# 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 = "logins"
+version = "0.1.0"
+authors = ["Thom Chiovoloni <tchiovoloni@mozilla.com>"]
+build = "build.rs"
+exclude = [
+ "/android",
+ "/ios",
+]
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = "README.md"
+license = "MPL-2.0"
+
+[features]
+default = []
+keydb = [
+ "nss/keydb",
+ "dep:async-trait",
+ "dep:futures",
+]
+
+[lib]
+name = "logins"
+path = "src/lib.rs"
+
+[dependencies]
+anyhow = "1.0"
+lazy_static = "1.4"
+parking_lot = ">=0.11,<=0.12"
+serde = "1"
+serde_derive = "1"
+serde_json = "1"
+thiserror = "2"
+url = "2.2"
+
+[dependencies.async-trait]
+version = "0.1"
+optional = true
+
+[dependencies.error-support]
+path = "../support/error"
+
+[dependencies.futures]
+version = "0.3"
+features = ["executor"]
+optional = true
+
+[dependencies.interrupt-support]
+path = "../support/interrupt"
+
+[dependencies.jwcrypto]
+path = "../support/jwcrypto"
+
+[dependencies.nss]
+path = "../support/rc_crypto/nss"
+default-features = false
+
+[dependencies.rusqlite]
+version = "0.37.0"
+features = [
+ "limits",
+ "unlock_notify",
+]
+
+[dependencies.sql-support]
+path = "../support/sql"
+
+[dependencies.sync-guid]
+path = "../support/guid"
+features = [
+ "rusqlite_support",
+ "random",
+]
+
+[dependencies.sync15]
+path = "../sync15"
+features = ["standalone-sync"]
+
+[dependencies.uniffi]
+version = "0.29.0"
+
+[dev-dependencies]
+tempfile = "3.2.0"
+
+[dev-dependencies.error-support]
+path = "../support/error"
+features = ["testing"]
+
+[dev-dependencies.nss]
+path = "../support/rc_crypto/nss"
+
+[build-dependencies.uniffi]
+version = "0.29.0"
+features = ["build"]
diff --git a/third_party/rust/logins/README.md b/third_party/rust/logins/README.md
@@ -0,0 +1,178 @@
+# Logins Component
+
+
+
+
+
+
+The Logins component can be used to store website logins (i.e. usernames, passwords, and related metadata)
+and to sync them between applications using [Firefox Sync](../sync_manager/README.md).
+
+* [Features](#features)
+* [Using the Logins component](#using-the-logins-component)
+* [Working on the Logins component](#working-on-the-logins-component)
+
+## Features
+
+The Logins component offers:
+
+1. Local encrypted storage of login records (including usernames, passwords, and website metadata).
+1. Basic Create, Read, Update and Delete (CRUD) operations for login data.
+1. Syncing of logins data between applications, via Firefox Sync.
+1. Import functionality from existing login storage (ex: Fx Desktop or Fennec).
+1. Data migration functionality from Fennec to Firefox Preview storage.
+
+The Logins component ***does not*** offer, and we have no concrete plans to offer:
+
+1. Any form-autofill of other UI-level functionality.
+1. Storage of other secret data, such as credit card numbers.
+
+If you'd like to see new capabilities added to this component, please file an issue for discussion,
+but on the understanding that it may be a lengthy discussion.
+
+## Using the Logins component
+
+### Before using this component
+
+Products sending telemetry and using this component *must request* a data-review following
+[this process](https://wiki.mozilla.org/Firefox/Data_Collection).
+This component provides data collection using the [Glean SDK](https://mozilla.github.io/glean/book/index.html).
+The list of metrics being collected is available in the [metrics documentation](../../docs/metrics/logins/metrics.md).
+
+### Prerequisites
+
+To use this component for local storage of logins data, you will need to know how to integrate appservices components
+into an application on your target platform:
+* **Android**: integrate via the
+ [sync-logins](https://github.com/mozilla-mobile/android-components/blob/main/components/service/sync-logins/README.md)
+ component from android-components.
+* **iOS**: start with the [guide to consuming rust components on
+ iOS](https://github.com/mozilla/application-services/blob/main/docs/howtos/consuming-rust-components-on-ios.md).
+* **Other Platforms**: we don't know yet; please reach out on slack to discuss!
+
+To sync logins data between devices, you will additionally need to integrate the
+[FxAClient component](../fxa-client/README.md) in order to obtain the necessary user credentials and encryption keys,
+and the [SyncManager component](../sync_manager/README.md) in order to orchestrate the syncing process.
+
+### Core Concepts
+
+* A **login record** contains a single saved password along with other metadata about where it should be used.
+Each record is uniquely identified by an opaque string id, and contains fields such as username, password and origin.
+You can read about the fields on a login record in the code [here](./src/login.rs).
+* A **logins store** is a syncable encrypted database containing login records. In order to use the logins store,
+the application must first *unlock* it by providing a secret key (preferably obtained from an OS-level keystore
+mechanism). It can then create, read, update and delete login records from the database.
+ * If the application is connected to Firefox Sync, it can instruct the store to sync itself with the user's
+ server-side logins data. This will upload any local modifications as well as download any new logins data
+ from the server, automatically reconciling records in the case of conflict.
+
+### Examples
+- [Android integration](https://github.com/mozilla-mobile/android-components/blob/main/components/service/sync-logins/README.md)
+
+
+### API Documentation
+- TODO [Expand and update API docs](https://github.com/mozilla/application-services/issues/1747)
+
+
+## Working on the Logins component
+
+### Prerequisites
+
+To effectively work on the Logins component, you will need to be familiar with:
+
+* Our general [guidelines for contributors](../../docs/contributing.md).
+* The [core concepts](#core-concepts) for users of the component, outlined above.
+* The way we [generate ffi bindings](../../docs/howtos/building-a-rust-component.md) and expose them to
+ [Kotlin](../../docs/howtos/exposing-rust-components-to-kotlin.md) and
+ [Swift](../../docs/howtos/exposing-rust-components-to-swift.md).
+* The key ideas behind [how Firefox Sync works](../../docs/synconomicon/) and the [sync15 crate](../sync15/README.md).
+
+### Implementation Overview
+
+Logins implements encrypted storage for login records on top of a consumer
+implemented EncryptorDecryptor, or via ManagedEncryptorDecryptor, using NSS
+based crypto algorithms (AES256-GCM).
+
+The `EncryptorDecryptor` trait defines an interface for encrypting and decrypting data. It allows consumers to either implement their own encryption mechanism or use the built in functionality provided by the component.
+- **Implementations**:
+ The component provides a default implementation in the form of `ManagedEncryptorDecryptor`, which leverages NSS for encryption/decryption. This implementation delegates key retrieval to a `KeyManager`.
+
+The `KeyManager` trait abstracts the process of obtaining an encryption key. This allows encryption to be decoupled from the specifics of key storage or generation.
+- **Implementations**:
+ - `StaticKeyManager`, which is used in contexts where the key is fixed during runtime (e.g. in tests).
+ - `NSSKeyManager`, which uses this trait to dynamically obtain keys that may be wrapped with user-provided credentials.
+
+The `NSSKeyManager` is responsible for managing encryption keys via NSS. Its responsibilities include:
+- Checking if primary password authentication is needed.
+- Coordinating with `PrimaryPasswordAuthenticator` to obtain the primary password when required.
+- Retrieving or creating an AES-256 key that is wrapped with the primary password if one is set.
+- Serializing the key into a JSON format for use by encryption and decryption routines.
+
+The `PrimaryPasswordAuthenticator` is a foreign trait that is used to supply the primary password necessary for unlocking the NSS key database.
+
+See the header comment in [`src/encryption.rs`](./src/encryption.rs) for a more detailed explanation of encryption options and key management in the logins component.
+
+The storage schema is based on the one
+originally used in [Firefox for
+iOS](https://github.com/mozilla-mobile/firefox-ios/blob/faa6a2839abf4da2c54ff1b3291174b50b31ab2c/Storage/SQL/SQLiteLogins.swift),
+but with the following notable differences:
+- the queries; they've been substantially modified for our needs here.
+- how sync is performed; the version here allows syncs to complete with fewer database operations.
+- timestamps; iOS uses microseconds, where the Logins component uses milliseconds.
+
+See the header comment in [`src/schema.rs`](./src/schema.rs) for an overview of the schema.
+
+### Directory structure
+The relevant directories are as follows:
+
+- [`src`](./src): The meat of the library. This contains cross-platform rust code that
+ implements the actual storage and sync of login records.
+- [`examples`](./examples): This contains example rust code that implements a command-line app
+ for syncing, displaying, and editing logins using the code in `src`. You can run it via
+ cargo like so: `cargo run --example sync_pass_sql`.
+- [`ffi`](./ffi): The Rust public FFI bindings. This is a (memory-unsafe, by necessity)
+ API that is exposed to Kotlin and Swift. It leverages the [`ffi_support`](https://github.com/mozilla/ffi-support)
+ crate to avoid many issues and make it more safe than it otherwise would be. At the
+ time of this writing, it uses JSON for marshalling data over the FFI, however
+ in the future we will likely use protocol buffers.
+- [`android`](./android): This contains android bindings to logins, written in Kotlin. These
+ use JNA to call into to the code in `ffi`.
+- [`ios`](./ios): This contains the iOS binding to logins, written in Swift. These use
+ Swift's native support for calling code written in C to call into the code in
+ `ffi`.
+
+### Business Logic
+
+#### Record storage
+
+At any given time records can exist in 3 places, the local storage, the remote record, and the shared parent. The shared parent refers to a record that has been synced previously and is referred to in the code as the mirror. Login records are encrypted and stored locally. For any record that does not have a shared parent the login component tracks that the record has never been synced.
+
+Reference the [Logins chapter of the synconomicon](https://mozilla.github.io/application-services/synconomicon/ch01.1-logins.html) for detailed information on the record storage format.
+
+#### Sign-out behavior
+When the user signs out of their Firefox Account, we reset the storage and clear the shared parent.
+
+#### Merging records
+When records are added, the logins component performs a three-way merge between the local record, the remote record and the shared parent (last update on the server). Details on the merging algorithm are contained in the [generic sync rfc](https://github.com/mozilla/application-services/blob/1e2ba102ee1709f51d200a2dd5e96155581a81b2/docs/design/remerge/rfc.md#three-way-merge-algorithm).
+
+#### Record de-duplication
+
+De-duplication compares the records for same the username and same url, but with different passwords.
+Deduplication logic is based on age, the username and hostname:
+- If the changes are more recent than the local record it performs an update.
+- If the change is older than our local records, and you have changed the same field on both, the record is not updated.
+
+### Testing
+
+
+
+Our goal is to seek an _acceptable_ level of test coverage. When making changes in an area, make an effort to improve (or minimally not reduce) coverage. Test coverage assessment includes:
+* [rust tests](https://github.com/mozilla/application-services/blob/main/testing/sync-test/src/logins.rs)
+* [android tests](https://github.com/mozilla/application-services/tree/main/components/logins/android/src/test/java/mozilla/appservices/logins)
+* [ios tests](https://github.com/mozilla/application-services/blob/main/megazords/ios-rust/MozillaTestServicesTests/LoginsTests.swift)
+* TODO [measure and report test coverage of logins component](https://github.com/mozilla/application-services/issues/1745)
+
+### Telemetry
+- TODO [implement logins sync ping telemety via glean](https://github.com/mozilla/application-services/issues/1867)
+- TODO [Define instrument and measure success metrics](https://github.com/mozilla/application-services/issues/1749)
+- TODO [Define instrument and measure quality metrics](https://github.com/mozilla/application-services/issues/1748)
diff --git a/third_party/rust/logins/build.rs b/third_party/rust/logins/build.rs
@@ -0,0 +1,8 @@
+/* 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/.
+ */
+
+fn main() {
+ uniffi::generate_scaffolding("./src/logins.udl").unwrap();
+}
diff --git a/third_party/rust/logins/fixtures/profile/.gitignore b/third_party/rust/logins/fixtures/profile/.gitignore
@@ -0,0 +1 @@
+pkcs11.txt
diff --git a/third_party/rust/logins/fixtures/profile/README.md b/third_party/rust/logins/fixtures/profile/README.md
@@ -0,0 +1,6 @@
+# Profile Fixture
+
+To test the integration of logins using the `keydb` feature in a profile with
+an activated primary password, we use this profile, which was created
+externally as long as Rust-side bindings for setting a primary password are not
+yet implemented.
diff --git a/third_party/rust/logins/fixtures/profile/key4.db b/third_party/rust/logins/fixtures/profile/key4.db
Binary files differ.
diff --git a/third_party/rust/logins/metrics.yaml b/third_party/rust/logins/metrics.yaml
@@ -0,0 +1,200 @@
+# 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/.
+
+# This file defines the metrics that will be gathered for the "logins"
+# storage component.
+# These are emitted for all users of the component. Additional metrics
+# specific to the *syncing* of logins are defined in a separate "sync_ping"
+# package.
+#
+# Changes to these metrics require data review, which should take into
+# consideration the following known consumers of the logins component
+# Android bindings:
+#
+# * Fenix for Android
+
+---
+$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
+
+logins_store:
+ # These track when we need to regenerate the encryption key which causes all
+ # local data to be lost
+ key_regenerated_lost:
+ type: event
+ description: >
+ The encryption key was regenerated because it was lost
+ bugs:
+ - https://github.com/mozilla/application-services/issues/4554
+ data_reviews:
+ - https://github.com/mozilla/application-services/issues/4582
+ - https://github.com/mozilla/application-services/issues/4899
+ - https://github.com/mozilla/application-services/issues/5051
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - synced-client-integrations@mozilla.com
+ - bdk@mozilla.com
+ expires: never
+
+ key_regenerated_corrupt:
+ type: event
+ description: >
+ The encryption key was regenerated because it didn't match the encrypted
+ data
+ bugs:
+ - https://github.com/mozilla/application-services/issues/4554
+ data_reviews:
+ - https://github.com/mozilla/application-services/issues/4582
+ - https://github.com/mozilla/application-services/issues/4899
+ - https://github.com/mozilla/application-services/issues/5051
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - synced-client-integrations@mozilla.com
+ - bdk@mozilla.com
+ expires: never
+
+ key_regenerated_other:
+ type: event
+ description: >
+ The encryption key was regenerated for an unknown reason
+ bugs:
+ - https://github.com/mozilla/application-services/issues/4554
+ data_reviews:
+ - https://github.com/mozilla/application-services/issues/4582
+ - https://github.com/mozilla/application-services/issues/4899
+ - https://github.com/mozilla/application-services/issues/5051
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - synced-client-integrations@mozilla.com
+ - bdk@mozilla.com
+ expires: never
+
+ # These help us understand how much the logins store is being used, and
+ # whether it's succeeding in the duties asked of it. We'll use them to
+ # graph e.g. the error rate of applications trying to use the logins store,
+ # and identify application or platform features that lead to unusually
+ # high error rates.
+ read_query_count:
+ type: counter
+ description: >
+ The total number of read operations performed on the logins store.
+ The count only includes operations triggered by the application, not
+ e.g. incidental reads performed as part of a sync. It is intended to be
+ used together with `read_query_error_count` to measure the overall error
+ rate of read operations on the logins store.
+ bugs:
+ - https://github.com/mozilla/application-services/issues/2225
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1597895
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1649044
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1694316
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - mhammond@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
+
+ read_query_error_count:
+ type: labeled_counter
+ description: >
+ The total number of errors encountered during read operations on the
+ logins store, labeled by type.
+ It is intended to be used together with `read_query_count` to measure
+ the overall error rate of read operations on the logins store.
+ labels:
+ - interrupted
+ - storage_error
+ bugs:
+ - https://github.com/mozilla/application-services/issues/2225
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1597895
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1649044
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1694316
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - mhammond@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
+
+ write_query_count:
+ type: counter
+ description: >
+ The total number of write operations performed on the logins store.
+ The count only includes operations triggered by the application, not
+ e.g. incidental writes performed as part of a sync. It is intended to
+ be used together with `write_query_error_count` to measure the overall
+ error rate of write operations on the logins store.
+ bugs:
+ - https://github.com/mozilla/application-services/issues/2225
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1597895
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1649044
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1694316
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - mhammond@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
+
+ write_query_error_count:
+ type: labeled_counter
+ description: >
+ The total number of errors encountered during write operations on the
+ logins store, labeled by type.
+ It is intended to be used together with `write_query_count` to measure
+ the overall error rate of write operations on the logins store.
+ labels:
+ - no_such_record
+ - interrupted
+ - invalid_record
+ - storage_error
+ bugs:
+ - https://github.com/mozilla/application-services/issues/2225
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1597895
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1649044
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1694316
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - mhammond@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
+
+ local_undecryptable_deleted:
+ type: counter
+ description: >
+ Track how many logins we deleted locally due to various reasons
+ that prevent us from decrypting the login
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1972437
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1972437
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - skhamis@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
+
+ mirror_undecryptable_deleted:
+ type: counter
+ description: >
+ Track how many logins we deleted in the mirror table due to various reasons
+ that prevent us from decrypting the login
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1972437
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1972437
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - skhamis@mozilla.com
+ - synced-client-integrations@mozilla.com
+ expires: "never"
diff --git a/third_party/rust/logins/src/db.rs b/third_party/rust/logins/src/db.rs
@@ -0,0 +1,1896 @@
+/* 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/. */
+
+/// Logins DB handling
+///
+/// The logins database works differently than other components because "mirror" and "local" mean
+/// different things. At some point we should probably refactor to make it match them, but here's
+/// how it works for now:
+///
+/// - loginsM is the mirror table, which means it stores what we believe is on the server. This
+/// means either the last record we fetched from the server or the last record we uploaded.
+/// - loginsL is the local table, which means it stores local changes that have not been sent to
+/// the server.
+/// - When we want to fetch a record, we need to look in both loginsL and loginsM for the data.
+/// If a record is in both tables, then we prefer the loginsL data. GET_BY_GUID_SQL contains a
+/// clever UNION query to accomplish this.
+/// - If a record is in both the local and mirror tables, we call the local record the "overlay"
+/// and set the is_overridden flag on the mirror record.
+/// - When we sync, the presence of a record in loginsL means that there was a local change that
+/// we need to send to the the server and/or reconcile it with incoming changes from the
+/// server.
+/// - After we sync, we move all records from loginsL to loginsM, overwriting any previous data.
+/// loginsL will be an empty table after this. See mark_as_synchronized() for the details.
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::login::*;
+use crate::schema;
+use crate::sync::SyncStatus;
+use crate::util;
+use interrupt_support::{SqlInterruptHandle, SqlInterruptScope};
+use lazy_static::lazy_static;
+use rusqlite::{
+ named_params,
+ types::{FromSql, ToSql},
+ Connection,
+};
+use sql_support::ConnExt;
+use std::ops::Deref;
+use std::path::Path;
+use std::sync::Arc;
+use std::time::SystemTime;
+use sync_guid::Guid;
+use url::{Host, Url};
+
+pub struct LoginDb {
+ pub db: Connection,
+ pub encdec: Arc<dyn EncryptorDecryptor>,
+ interrupt_handle: Arc<SqlInterruptHandle>,
+}
+
+pub struct LoginsDeletionMetrics {
+ pub local_deleted: u64,
+ pub mirror_deleted: u64,
+}
+
+impl LoginDb {
+ pub fn with_connection(db: Connection, encdec: Arc<dyn EncryptorDecryptor>) -> Result<Self> {
+ #[cfg(test)]
+ {
+ util::init_test_logging();
+ }
+
+ // `temp_store = 2` is required on Android to force the DB to keep temp
+ // files in memory, since on Android there's no tmp partition. See
+ // https://github.com/mozilla/mentat/issues/505. Ideally we'd only
+ // do this on Android, or allow caller to configure it.
+ db.set_pragma("temp_store", 2)?;
+
+ let mut logins = Self {
+ interrupt_handle: Arc::new(SqlInterruptHandle::new(&db)),
+ encdec,
+ db,
+ };
+ let tx = logins.db.transaction()?;
+ schema::init(&tx)?;
+ tx.commit()?;
+ Ok(logins)
+ }
+
+ pub fn open(path: impl AsRef<Path>, encdec: Arc<dyn EncryptorDecryptor>) -> Result<Self> {
+ Self::with_connection(Connection::open(path)?, encdec)
+ }
+
+ #[cfg(test)]
+ pub fn open_in_memory() -> Self {
+ let encdec: Arc<dyn EncryptorDecryptor> =
+ crate::encryption::test_utils::TEST_ENCDEC.clone();
+ Self::with_connection(Connection::open_in_memory().unwrap(), encdec).unwrap()
+ }
+
+ pub fn new_interrupt_handle(&self) -> Arc<SqlInterruptHandle> {
+ Arc::clone(&self.interrupt_handle)
+ }
+
+ #[inline]
+ pub fn begin_interrupt_scope(&self) -> Result<SqlInterruptScope> {
+ Ok(self.interrupt_handle.begin_interrupt_scope()?)
+ }
+}
+
+impl ConnExt for LoginDb {
+ #[inline]
+ fn conn(&self) -> &Connection {
+ &self.db
+ }
+}
+
+impl Deref for LoginDb {
+ type Target = Connection;
+ #[inline]
+ fn deref(&self) -> &Connection {
+ &self.db
+ }
+}
+
+// login specific stuff.
+
+impl LoginDb {
+ pub(crate) fn put_meta(&self, key: &str, value: &dyn ToSql) -> Result<()> {
+ self.execute_cached(
+ "REPLACE INTO loginsSyncMeta (key, value) VALUES (:key, :value)",
+ named_params! { ":key": key, ":value": value },
+ )?;
+ Ok(())
+ }
+
+ pub(crate) fn get_meta<T: FromSql>(&self, key: &str) -> Result<Option<T>> {
+ self.try_query_row(
+ "SELECT value FROM loginsSyncMeta WHERE key = :key",
+ named_params! { ":key": key },
+ |row| Ok::<_, Error>(row.get(0)?),
+ true,
+ )
+ }
+
+ pub(crate) fn delete_meta(&self, key: &str) -> Result<()> {
+ self.execute_cached(
+ "DELETE FROM loginsSyncMeta WHERE key = :key",
+ named_params! { ":key": key },
+ )?;
+ Ok(())
+ }
+
+ pub fn count_all(&self) -> Result<i64> {
+ let mut stmt = self.db.prepare_cached(&COUNT_ALL_SQL)?;
+
+ let count: i64 = stmt.query_row([], |row| row.get(0))?;
+ Ok(count)
+ }
+
+ pub fn count_by_origin(&self, origin: &str) -> Result<i64> {
+ let mut stmt = self.db.prepare_cached(&COUNT_BY_ORIGIN_SQL)?;
+
+ let count: i64 = stmt.query_row(named_params! { ":origin": origin }, |row| row.get(0))?;
+ Ok(count)
+ }
+
+ pub fn count_by_form_action_origin(&self, form_action_origin: &str) -> Result<i64> {
+ let mut stmt = self.db.prepare_cached(&COUNT_BY_FORM_ACTION_ORIGIN_SQL)?;
+
+ let count: i64 = stmt.query_row(
+ named_params! { ":form_action_origin": form_action_origin },
+ |row| row.get(0),
+ )?;
+ Ok(count)
+ }
+
+ pub fn get_all(&self) -> Result<Vec<EncryptedLogin>> {
+ let mut stmt = self.db.prepare_cached(&GET_ALL_SQL)?;
+ let rows = stmt.query_and_then([], EncryptedLogin::from_row)?;
+ rows.collect::<Result<_>>()
+ }
+
+ pub fn get_by_base_domain(&self, base_domain: &str) -> Result<Vec<EncryptedLogin>> {
+ // We first parse the input string as a host so it is normalized.
+ let base_host = match Host::parse(base_domain) {
+ Ok(d) => d,
+ Err(e) => {
+ // don't log the input string as it's PII.
+ warn!("get_by_base_domain was passed an invalid domain: {}", e);
+ return Ok(vec![]);
+ }
+ };
+ // We just do a linear scan. Another option is to have an indexed
+ // reverse-host column or similar, but current thinking is that it's
+ // extra complexity for (probably) zero actual benefit given the record
+ // counts are expected to be so low.
+ // A regex would probably make this simpler, but we don't want to drag
+ // in a regex lib just for this.
+ let mut stmt = self.db.prepare_cached(&GET_ALL_SQL)?;
+ let rows = stmt
+ .query_and_then([], EncryptedLogin::from_row)?
+ .filter(|r| {
+ let login = r
+ .as_ref()
+ .ok()
+ .and_then(|login| Url::parse(&login.fields.origin).ok());
+ let this_host = login.as_ref().and_then(|url| url.host());
+ match (&base_host, this_host) {
+ (Host::Domain(base), Some(Host::Domain(look))) => {
+ // a fairly long-winded way of saying
+ // `login.fields.origin == base_domain ||
+ // login.fields.origin.ends_with('.' + base_domain);`
+ let mut rev_input = base.chars().rev();
+ let mut rev_host = look.chars().rev();
+ loop {
+ match (rev_input.next(), rev_host.next()) {
+ (Some(ref a), Some(ref b)) if a == b => continue,
+ (None, None) => return true, // exactly equal
+ (None, Some(ref h)) => return *h == '.',
+ _ => return false,
+ }
+ }
+ }
+ // ip addresses must match exactly.
+ (Host::Ipv4(base), Some(Host::Ipv4(look))) => *base == look,
+ (Host::Ipv6(base), Some(Host::Ipv6(look))) => *base == look,
+ // all "mismatches" in domain types are false.
+ _ => false,
+ }
+ });
+ rows.collect::<Result<_>>()
+ }
+
+ pub fn get_by_id(&self, id: &str) -> Result<Option<EncryptedLogin>> {
+ self.try_query_row(
+ &GET_BY_GUID_SQL,
+ &[(":guid", &id as &dyn ToSql)],
+ EncryptedLogin::from_row,
+ true,
+ )
+ }
+
+ // Match a `LoginEntry` being saved to existing logins in the DB
+ //
+ // When a user is saving new login, there are several cases for how we want to save the data:
+ //
+ // - Adding a new login: `None` will be returned
+ // - Updating an existing login: `Some(login)` will be returned and the username will match
+ // the one for look.
+ // - Filling in a blank username for an existing login: `Some(login)` will be returned
+ // with a blank username.
+ //
+ // Returns an Err if the new login is not valid and could not be fixed up
+ pub fn find_login_to_update(
+ &self,
+ look: LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<Option<Login>> {
+ let look = look.fixup()?;
+ let logins = self
+ .get_by_entry_target(&look)?
+ .into_iter()
+ .map(|enc_login| enc_login.decrypt(encdec))
+ .collect::<Result<Vec<Login>>>()?;
+ Ok(logins
+ // First, try to match the username
+ .iter()
+ .find(|login| login.username == look.username)
+ // Fall back on a blank username
+ .or_else(|| logins.iter().find(|login| login.username.is_empty()))
+ // Clone the login to avoid ref issues when returning across the FFI
+ .cloned())
+ }
+
+ pub fn touch(&self, id: &str) -> Result<()> {
+ let tx = self.unchecked_transaction()?;
+ self.ensure_local_overlay_exists(id)?;
+ self.mark_mirror_overridden(id)?;
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+ // As on iOS, just using a record doesn't flip it's status to changed.
+ // TODO: this might be wrong for lockbox!
+ self.execute_cached(
+ "UPDATE loginsL
+ SET timeLastUsed = :now_millis,
+ timesUsed = timesUsed + 1,
+ local_modified = :now_millis
+ WHERE guid = :guid
+ AND is_deleted = 0",
+ named_params! {
+ ":now_millis": now_ms,
+ ":guid": id,
+ },
+ )?;
+ tx.commit()?;
+ Ok(())
+ }
+
+ // The single place we insert new rows or update existing local rows.
+ // just the SQL - no validation or anything.
+ fn insert_new_login(&self, login: &EncryptedLogin) -> Result<()> {
+ let sql = format!(
+ "INSERT OR REPLACE INTO loginsL (
+ origin,
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ timesUsed,
+ secFields,
+ guid,
+ timeCreated,
+ timeLastUsed,
+ timePasswordChanged,
+ local_modified,
+ is_deleted,
+ sync_status
+ ) VALUES (
+ :origin,
+ :http_realm,
+ :form_action_origin,
+ :username_field,
+ :password_field,
+ :times_used,
+ :sec_fields,
+ :guid,
+ :time_created,
+ :time_last_used,
+ :time_password_changed,
+ :local_modified,
+ 0, -- is_deleted
+ {new} -- sync_status
+ )",
+ new = SyncStatus::New as u8
+ );
+
+ self.execute(
+ &sql,
+ named_params! {
+ ":origin": login.fields.origin,
+ ":http_realm": login.fields.http_realm,
+ ":form_action_origin": login.fields.form_action_origin,
+ ":username_field": login.fields.username_field,
+ ":password_field": login.fields.password_field,
+ ":time_created": login.meta.time_created,
+ ":times_used": login.meta.times_used,
+ ":time_last_used": login.meta.time_last_used,
+ ":time_password_changed": login.meta.time_password_changed,
+ ":local_modified": login.meta.time_created,
+ ":sec_fields": login.sec_fields,
+ ":guid": login.guid(),
+ },
+ )?;
+ Ok(())
+ }
+
+ fn update_existing_login(&self, login: &EncryptedLogin) -> Result<()> {
+ // assumes the "local overlay" exists, so the guid must too.
+ let sql = format!(
+ "UPDATE loginsL
+ SET local_modified = :now_millis,
+ timeLastUsed = :time_last_used,
+ timePasswordChanged = :time_password_changed,
+ httpRealm = :http_realm,
+ formActionOrigin = :form_action_origin,
+ usernameField = :username_field,
+ passwordField = :password_field,
+ timesUsed = :times_used,
+ secFields = :sec_fields,
+ origin = :origin,
+ -- leave New records as they are, otherwise update them to `changed`
+ sync_status = max(sync_status, {changed})
+ WHERE guid = :guid",
+ changed = SyncStatus::Changed as u8
+ );
+
+ self.db.execute(
+ &sql,
+ named_params! {
+ ":origin": login.fields.origin,
+ ":http_realm": login.fields.http_realm,
+ ":form_action_origin": login.fields.form_action_origin,
+ ":username_field": login.fields.username_field,
+ ":password_field": login.fields.password_field,
+ ":time_last_used": login.meta.time_last_used,
+ ":times_used": login.meta.times_used,
+ ":time_password_changed": login.meta.time_password_changed,
+ ":sec_fields": login.sec_fields,
+ ":guid": &login.meta.id,
+ // time_last_used has been set to now.
+ ":now_millis": login.meta.time_last_used,
+ },
+ )?;
+ Ok(())
+ }
+
+ /// Adds multiple logins within a single transaction and returns the successfully saved logins.
+ pub fn add_many(
+ &self,
+ entries: Vec<LoginEntry>,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<Vec<Result<EncryptedLogin>>> {
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+
+ let entries_with_meta = entries
+ .into_iter()
+ .map(|entry| {
+ let guid = Guid::random();
+ LoginEntryWithMeta {
+ entry,
+ meta: LoginMeta {
+ id: guid.to_string(),
+ time_created: now_ms,
+ time_password_changed: now_ms,
+ time_last_used: now_ms,
+ times_used: 1,
+ },
+ }
+ })
+ .collect();
+
+ self.add_many_with_meta(entries_with_meta, encdec)
+ }
+
+ /// Adds multiple logins **including metadata** within a single transaction and returns the successfully saved logins.
+ /// Normally, you will use `add_many` instead, and AS Logins will take care of the metadata (setting timestamps, generating an ID) itself.
+ /// However, in some cases, this method is necessary, for example when migrating data from another store that already contains the metadata.
+ pub fn add_many_with_meta(
+ &self,
+ entries_with_meta: Vec<LoginEntryWithMeta>,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<Vec<Result<EncryptedLogin>>> {
+ let tx = self.unchecked_transaction()?;
+ let mut results = vec![];
+ for entry_with_meta in entries_with_meta {
+ let guid = Guid::from_string(entry_with_meta.meta.id.clone());
+ match self.fixup_and_check_for_dupes(&guid, entry_with_meta.entry, encdec) {
+ Ok(new_entry) => {
+ let sec_fields = SecureLoginFields {
+ username: new_entry.username,
+ password: new_entry.password,
+ }
+ .encrypt(encdec, &entry_with_meta.meta.id)?;
+ let encrypted_login = EncryptedLogin {
+ meta: entry_with_meta.meta,
+ fields: LoginFields {
+ origin: new_entry.origin,
+ form_action_origin: new_entry.form_action_origin,
+ http_realm: new_entry.http_realm,
+ username_field: new_entry.username_field,
+ password_field: new_entry.password_field,
+ },
+ sec_fields,
+ };
+ let result = self
+ .insert_new_login(&encrypted_login)
+ .map(|_| encrypted_login);
+ results.push(result);
+ }
+
+ Err(error) => results.push(Err(error)),
+ }
+ }
+ tx.commit()?;
+ Ok(results)
+ }
+
+ pub fn add(
+ &self,
+ entry: LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<EncryptedLogin> {
+ let guid = Guid::random();
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+
+ let entry_with_meta = LoginEntryWithMeta {
+ entry,
+ meta: LoginMeta {
+ id: guid.to_string(),
+ time_created: now_ms,
+ time_password_changed: now_ms,
+ time_last_used: now_ms,
+ times_used: 1,
+ },
+ };
+
+ self.add_with_meta(entry_with_meta, encdec)
+ }
+
+ /// Adds a login **including metadata**.
+ /// Normally, you will use `add` instead, and AS Logins will take care of the metadata (setting timestamps, generating an ID) itself.
+ /// However, in some cases, this method is necessary, for example when migrating data from another store that already contains the metadata.
+ pub fn add_with_meta(
+ &self,
+ entry_with_meta: LoginEntryWithMeta,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<EncryptedLogin> {
+ let mut results = self.add_many_with_meta(vec![entry_with_meta], encdec)?;
+ results.pop().expect("there should be a single result")
+ }
+
+ pub fn update(
+ &self,
+ sguid: &str,
+ entry: LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<EncryptedLogin> {
+ let guid = Guid::new(sguid);
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+ let tx = self.unchecked_transaction()?;
+
+ let entry = entry.fixup()?;
+
+ // Check if there's an existing login that's the dupe of this login. That indicates that
+ // something has gone wrong with our underlying logic. However, if we do see a dupe login,
+ // just log an error and continue. This avoids a crash on android-components
+ // (mozilla-mobile/android-components#11251).
+
+ if self.check_for_dupes(&guid, &entry, encdec).is_err() {
+ // Try to detect if sync is enabled by checking if there are any mirror logins
+ let has_mirror_row: bool = self
+ .db
+ .conn_ext_query_one("SELECT EXISTS (SELECT 1 FROM loginsM)")?;
+ let has_http_realm = entry.http_realm.is_some();
+ let has_form_action_origin = entry.form_action_origin.is_some();
+ report_error!(
+ "logins-duplicate-in-update",
+ "(mirror: {has_mirror_row}, realm: {has_http_realm}, form_origin: {has_form_action_origin})");
+ }
+
+ // Note: This fail with NoSuchRecord if the record doesn't exist.
+ self.ensure_local_overlay_exists(&guid)?;
+ self.mark_mirror_overridden(&guid)?;
+
+ // We must read the existing record so we can correctly manage timePasswordChanged.
+ let existing = match self.get_by_id(sguid)? {
+ Some(e) => e.decrypt(encdec)?,
+ None => return Err(Error::NoSuchRecord(sguid.to_owned())),
+ };
+ let time_password_changed = if existing.password == entry.password {
+ existing.time_password_changed
+ } else {
+ now_ms
+ };
+
+ // Make the final object here - every column will be updated.
+ let sec_fields = SecureLoginFields {
+ username: entry.username,
+ password: entry.password,
+ }
+ .encrypt(encdec, &existing.id)?;
+ let result = EncryptedLogin {
+ meta: LoginMeta {
+ id: existing.id,
+ time_created: existing.time_created,
+ time_password_changed,
+ time_last_used: now_ms,
+ times_used: existing.times_used + 1,
+ },
+ fields: LoginFields {
+ origin: entry.origin,
+ form_action_origin: entry.form_action_origin,
+ http_realm: entry.http_realm,
+ username_field: entry.username_field,
+ password_field: entry.password_field,
+ },
+ sec_fields,
+ };
+
+ self.update_existing_login(&result)?;
+ tx.commit()?;
+ Ok(result)
+ }
+
+ pub fn add_or_update(
+ &self,
+ entry: LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<EncryptedLogin> {
+ // Make sure to fixup the entry first, in case that changes the username
+ let entry = entry.fixup()?;
+ match self.find_login_to_update(entry.clone(), encdec)? {
+ Some(login) => self.update(&login.id, entry, encdec),
+ None => self.add(entry, encdec),
+ }
+ }
+
+ pub fn fixup_and_check_for_dupes(
+ &self,
+ guid: &Guid,
+ entry: LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<LoginEntry> {
+ let entry = entry.fixup()?;
+ self.check_for_dupes(guid, &entry, encdec)?;
+ Ok(entry)
+ }
+
+ pub fn check_for_dupes(
+ &self,
+ guid: &Guid,
+ entry: &LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<()> {
+ if self.dupe_exists(guid, entry, encdec)? {
+ return Err(InvalidLogin::DuplicateLogin.into());
+ }
+ Ok(())
+ }
+
+ pub fn dupe_exists(
+ &self,
+ guid: &Guid,
+ entry: &LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<bool> {
+ Ok(self.find_dupe(guid, entry, encdec)?.is_some())
+ }
+
+ pub fn find_dupe(
+ &self,
+ guid: &Guid,
+ entry: &LoginEntry,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<Option<Guid>> {
+ for possible in self.get_by_entry_target(entry)? {
+ if possible.guid() != *guid {
+ let pos_sec_fields = possible.decrypt_fields(encdec)?;
+ if pos_sec_fields.username == entry.username {
+ return Ok(Some(possible.guid()));
+ }
+ }
+ }
+ Ok(None)
+ }
+
+ // Find saved logins that match the target for a `LoginEntry`
+ //
+ // This means that:
+ // - `origin` matches
+ // - Either `form_action_origin` or `http_realm` matches, depending on which one is non-null
+ //
+ // This is used for dupe-checking and `find_login_to_update()`
+ fn get_by_entry_target(&self, entry: &LoginEntry) -> Result<Vec<EncryptedLogin>> {
+ // Could be lazy_static-ed...
+ lazy_static::lazy_static! {
+ static ref GET_BY_FORM_ACTION_ORIGIN: String = format!(
+ "SELECT {common_cols} FROM loginsL
+ WHERE is_deleted = 0
+ AND origin = :origin
+ AND formActionOrigin = :form_action_origin
+
+ UNION ALL
+
+ SELECT {common_cols} FROM loginsM
+ WHERE is_overridden = 0
+ AND origin = :origin
+ AND formActionOrigin = :form_action_origin
+ ",
+ common_cols = schema::COMMON_COLS
+ );
+ static ref GET_BY_HTTP_REALM: String = format!(
+ "SELECT {common_cols} FROM loginsL
+ WHERE is_deleted = 0
+ AND origin = :origin
+ AND httpRealm = :http_realm
+
+ UNION ALL
+
+ SELECT {common_cols} FROM loginsM
+ WHERE is_overridden = 0
+ AND origin = :origin
+ AND httpRealm = :http_realm
+ ",
+ common_cols = schema::COMMON_COLS
+ );
+ }
+ match (entry.form_action_origin.as_ref(), entry.http_realm.as_ref()) {
+ (Some(form_action_origin), None) => {
+ let params = named_params! {
+ ":origin": &entry.origin,
+ ":form_action_origin": form_action_origin,
+ };
+ self.db
+ .prepare_cached(&GET_BY_FORM_ACTION_ORIGIN)?
+ .query_and_then(params, EncryptedLogin::from_row)?
+ .collect()
+ }
+ (None, Some(http_realm)) => {
+ let params = named_params! {
+ ":origin": &entry.origin,
+ ":http_realm": http_realm,
+ };
+ self.db
+ .prepare_cached(&GET_BY_HTTP_REALM)?
+ .query_and_then(params, EncryptedLogin::from_row)?
+ .collect()
+ }
+ (Some(_), Some(_)) => Err(InvalidLogin::BothTargets.into()),
+ (None, None) => Err(InvalidLogin::NoTarget.into()),
+ }
+ }
+
+ pub fn exists(&self, id: &str) -> Result<bool> {
+ Ok(self.db.query_row(
+ "SELECT EXISTS(
+ SELECT 1 FROM loginsL
+ WHERE guid = :guid AND is_deleted = 0
+ UNION ALL
+ SELECT 1 FROM loginsM
+ WHERE guid = :guid AND is_overridden IS NOT 1
+ )",
+ named_params! { ":guid": id },
+ |row| row.get(0),
+ )?)
+ }
+
+ /// Delete the record with the provided id. Returns true if the record
+ /// existed already.
+ pub fn delete(&self, id: &str) -> Result<bool> {
+ let mut results = self.delete_many(vec![id])?;
+ Ok(results.pop().expect("there should be a single result"))
+ }
+
+ /// Delete the records with the specified IDs. Returns a list of Boolean values
+ /// indicating whether the respective records already existed.
+ pub fn delete_many(&self, ids: Vec<&str>) -> Result<Vec<bool>> {
+ let tx = self.unchecked_transaction_imm()?;
+ let sql = format!(
+ "
+ UPDATE loginsL
+ SET local_modified = :now_ms,
+ sync_status = {status_changed},
+ is_deleted = 1,
+ secFields = '',
+ origin = '',
+ httpRealm = NULL,
+ formActionOrigin = NULL
+ WHERE guid = :guid AND is_deleted IS FALSE
+ ",
+ status_changed = SyncStatus::Changed as u8
+ );
+ let mut stmt = self.db.prepare_cached(&sql)?;
+
+ let mut result = vec![];
+
+ for id in ids {
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+
+ // For IDs that have, mark is_deleted and clear sensitive fields
+ let update_result = stmt.execute(named_params! { ":now_ms": now_ms, ":guid": id })?;
+
+ let exists = update_result == 1;
+
+ // Mark the mirror as overridden
+ self.execute(
+ "UPDATE loginsM SET is_overridden = 1 WHERE guid = :guid",
+ named_params! { ":guid": id },
+ )?;
+
+ // If we don't have a local record for this ID, but do have it in the mirror
+ // insert a tombstone.
+ self.execute(&format!("
+ INSERT OR IGNORE INTO loginsL
+ (guid, local_modified, is_deleted, sync_status, origin, timeCreated, timePasswordChanged, secFields)
+ SELECT guid, :now_ms, 1, {changed}, '', timeCreated, :now_ms, ''
+ FROM loginsM
+ WHERE guid = :guid",
+ changed = SyncStatus::Changed as u8),
+ named_params! { ":now_ms": now_ms, ":guid": id })?;
+
+ result.push(exists);
+ }
+
+ tx.commit()?;
+
+ Ok(result)
+ }
+
+ pub fn delete_undecryptable_records_for_remote_replacement(
+ &self,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<LoginsDeletionMetrics> {
+ // Retrieve a list of guids for logins that cannot be decrypted
+ let corrupted_logins = self
+ .get_all()?
+ .into_iter()
+ .filter(|login| login.clone().decrypt(encdec).is_err())
+ .collect::<Vec<_>>();
+ let ids = corrupted_logins
+ .iter()
+ .map(|login| login.guid_str())
+ .collect::<Vec<_>>();
+
+ self.delete_local_records_for_remote_replacement(ids)
+ }
+
+ pub fn delete_local_records_for_remote_replacement(
+ &self,
+ ids: Vec<&str>,
+ ) -> Result<LoginsDeletionMetrics> {
+ let tx = self.unchecked_transaction_imm()?;
+ let mut local_deleted = 0;
+ let mut mirror_deleted = 0;
+
+ sql_support::each_chunk(&ids, |chunk, _| -> Result<()> {
+ let deleted = self.execute(
+ &format!(
+ "DELETE FROM loginsL WHERE guid IN ({})",
+ sql_support::repeat_sql_values(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ local_deleted += deleted;
+ Ok(())
+ })?;
+
+ sql_support::each_chunk(&ids, |chunk, _| -> Result<()> {
+ let deleted = self.execute(
+ &format!(
+ "DELETE FROM loginsM WHERE guid IN ({})",
+ sql_support::repeat_sql_values(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ mirror_deleted += deleted;
+ Ok(())
+ })?;
+
+ tx.commit()?;
+ Ok(LoginsDeletionMetrics {
+ local_deleted: local_deleted as u64,
+ mirror_deleted: mirror_deleted as u64,
+ })
+ }
+
+ fn mark_mirror_overridden(&self, guid: &str) -> Result<()> {
+ self.execute_cached(
+ "UPDATE loginsM SET is_overridden = 1 WHERE guid = :guid",
+ named_params! { ":guid": guid },
+ )?;
+ Ok(())
+ }
+
+ fn ensure_local_overlay_exists(&self, guid: &str) -> Result<()> {
+ let already_have_local: bool = self.db.query_row(
+ "SELECT EXISTS(SELECT 1 FROM loginsL WHERE guid = :guid)",
+ named_params! { ":guid": guid },
+ |row| row.get(0),
+ )?;
+
+ if already_have_local {
+ return Ok(());
+ }
+
+ debug!("No overlay; cloning one for {:?}.", guid);
+ let changed = self.clone_mirror_to_overlay(guid)?;
+ if changed == 0 {
+ report_error!(
+ "logins-local-overlay-error",
+ "Failed to create local overlay for GUID {guid:?}."
+ );
+ return Err(Error::NoSuchRecord(guid.to_owned()));
+ }
+ Ok(())
+ }
+
+ fn clone_mirror_to_overlay(&self, guid: &str) -> Result<usize> {
+ Ok(self.execute_cached(&CLONE_SINGLE_MIRROR_SQL, &[(":guid", &guid as &dyn ToSql)])?)
+ }
+
+ /// Wipe all local data, returns the number of rows deleted
+ pub fn wipe_local(&self) -> Result<usize> {
+ info!("Executing wipe_local on password engine!");
+ let tx = self.unchecked_transaction()?;
+ let mut row_count = 0;
+ row_count += self.execute("DELETE FROM loginsL", [])?;
+ row_count += self.execute("DELETE FROM loginsM", [])?;
+ row_count += self.execute("DELETE FROM loginsSyncMeta", [])?;
+ tx.commit()?;
+ Ok(row_count)
+ }
+
+ pub fn shutdown(self) -> Result<()> {
+ self.db.close().map_err(|(_, e)| Error::SqlError(e))
+ }
+}
+
+lazy_static! {
+ static ref GET_ALL_SQL: String = format!(
+ "SELECT {common_cols} FROM loginsL WHERE is_deleted = 0
+ UNION ALL
+ SELECT {common_cols} FROM loginsM WHERE is_overridden = 0",
+ common_cols = schema::COMMON_COLS,
+ );
+ static ref COUNT_ALL_SQL: String = format!(
+ "SELECT COUNT(*) FROM (
+ SELECT guid FROM loginsL WHERE is_deleted = 0
+ UNION ALL
+ SELECT guid FROM loginsM WHERE is_overridden = 0
+ )"
+ );
+ static ref COUNT_BY_ORIGIN_SQL: String = format!(
+ "SELECT COUNT(*) FROM (
+ SELECT guid FROM loginsL WHERE is_deleted = 0 AND origin = :origin
+ UNION ALL
+ SELECT guid FROM loginsM WHERE is_overridden = 0 AND origin = :origin
+ )"
+ );
+ static ref COUNT_BY_FORM_ACTION_ORIGIN_SQL: String = format!(
+ "SELECT COUNT(*) FROM (
+ SELECT guid FROM loginsL WHERE is_deleted = 0 AND formActionOrigin = :form_action_origin
+ UNION ALL
+ SELECT guid FROM loginsM WHERE is_overridden = 0 AND formActionOrigin = :form_action_origin
+ )"
+ );
+ static ref GET_BY_GUID_SQL: String = format!(
+ "SELECT {common_cols}
+ FROM loginsL
+ WHERE is_deleted = 0
+ AND guid = :guid
+
+ UNION ALL
+
+ SELECT {common_cols}
+ FROM loginsM
+ WHERE is_overridden IS NOT 1
+ AND guid = :guid
+ ORDER BY origin ASC
+
+ LIMIT 1",
+ common_cols = schema::COMMON_COLS,
+ );
+ pub static ref CLONE_ENTIRE_MIRROR_SQL: String = format!(
+ "INSERT OR IGNORE INTO loginsL ({common_cols}, local_modified, is_deleted, sync_status)
+ SELECT {common_cols}, NULL AS local_modified, 0 AS is_deleted, 0 AS sync_status
+ FROM loginsM",
+ common_cols = schema::COMMON_COLS,
+ );
+ static ref CLONE_SINGLE_MIRROR_SQL: String =
+ format!("{} WHERE guid = :guid", &*CLONE_ENTIRE_MIRROR_SQL,);
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+pub mod test_utils {
+ use super::*;
+ use crate::encryption::test_utils::decrypt_struct;
+ use crate::login::test_utils::enc_login;
+ use crate::SecureLoginFields;
+ use sync15::ServerTimestamp;
+
+ // Insert a login into the local and/or mirror tables.
+ //
+ // local_login and mirror_login are specified as Some(password_string)
+ pub fn insert_login(
+ db: &LoginDb,
+ guid: &str,
+ local_login: Option<&str>,
+ mirror_login: Option<&str>,
+ ) {
+ if let Some(password) = mirror_login {
+ add_mirror(
+ db,
+ &enc_login(guid, password),
+ &ServerTimestamp(util::system_time_ms_i64(std::time::SystemTime::now())),
+ local_login.is_some(),
+ )
+ .unwrap();
+ }
+ if let Some(password) = local_login {
+ db.insert_new_login(&enc_login(guid, password)).unwrap();
+ }
+ }
+
+ pub fn insert_encrypted_login(
+ db: &LoginDb,
+ local: &EncryptedLogin,
+ mirror: &EncryptedLogin,
+ server_modified: &ServerTimestamp,
+ ) {
+ db.insert_new_login(local).unwrap();
+ add_mirror(db, mirror, server_modified, true).unwrap();
+ }
+
+ pub fn add_mirror(
+ db: &LoginDb,
+ login: &EncryptedLogin,
+ server_modified: &ServerTimestamp,
+ is_overridden: bool,
+ ) -> Result<()> {
+ let sql = "
+ INSERT OR IGNORE INTO loginsM (
+ is_overridden,
+ server_modified,
+
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ secFields,
+ origin,
+
+ timesUsed,
+ timeLastUsed,
+ timePasswordChanged,
+ timeCreated,
+
+ guid
+ ) VALUES (
+ :is_overridden,
+ :server_modified,
+
+ :http_realm,
+ :form_action_origin,
+ :username_field,
+ :password_field,
+ :sec_fields,
+ :origin,
+
+ :times_used,
+ :time_last_used,
+ :time_password_changed,
+ :time_created,
+
+ :guid
+ )";
+ let mut stmt = db.prepare_cached(sql)?;
+
+ stmt.execute(named_params! {
+ ":is_overridden": is_overridden,
+ ":server_modified": server_modified.as_millis(),
+ ":http_realm": login.fields.http_realm,
+ ":form_action_origin": login.fields.form_action_origin,
+ ":username_field": login.fields.username_field,
+ ":password_field": login.fields.password_field,
+ ":origin": login.fields.origin,
+ ":sec_fields": login.sec_fields,
+ ":times_used": login.meta.times_used,
+ ":time_last_used": login.meta.time_last_used,
+ ":time_password_changed": login.meta.time_password_changed,
+ ":time_created": login.meta.time_created,
+ ":guid": login.guid_str(),
+ })?;
+ Ok(())
+ }
+
+ pub fn get_local_guids(db: &LoginDb) -> Vec<String> {
+ get_guids(db, "SELECT guid FROM loginsL")
+ }
+
+ pub fn get_mirror_guids(db: &LoginDb) -> Vec<String> {
+ get_guids(db, "SELECT guid FROM loginsM")
+ }
+
+ fn get_guids(db: &LoginDb, sql: &str) -> Vec<String> {
+ let mut stmt = db.prepare_cached(sql).unwrap();
+ let mut res: Vec<String> = stmt
+ .query_map([], |r| r.get(0))
+ .unwrap()
+ .map(|r| r.unwrap())
+ .collect();
+ res.sort();
+ res
+ }
+
+ pub fn get_server_modified(db: &LoginDb, guid: &str) -> i64 {
+ db.conn_ext_query_one(&format!(
+ "SELECT server_modified FROM loginsM WHERE guid='{}'",
+ guid
+ ))
+ .unwrap()
+ }
+
+ pub fn check_local_login(db: &LoginDb, guid: &str, password: &str, local_modified_gte: i64) {
+ let row: (String, i64, bool) = db
+ .query_row(
+ "SELECT secFields, local_modified, is_deleted FROM loginsL WHERE guid=?",
+ [guid],
+ |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
+ )
+ .unwrap();
+ let enc: SecureLoginFields = decrypt_struct(row.0);
+ assert_eq!(enc.password, password);
+ assert!(row.1 >= local_modified_gte);
+ assert!(!row.2);
+ }
+
+ pub fn check_mirror_login(
+ db: &LoginDb,
+ guid: &str,
+ password: &str,
+ server_modified: i64,
+ is_overridden: bool,
+ ) {
+ let row: (String, i64, bool) = db
+ .query_row(
+ "SELECT secFields, server_modified, is_overridden FROM loginsM WHERE guid=?",
+ [guid],
+ |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
+ )
+ .unwrap();
+ let enc: SecureLoginFields = decrypt_struct(row.0);
+ assert_eq!(enc.password, password);
+ assert_eq!(row.1, server_modified);
+ assert_eq!(row.2, is_overridden);
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::db::test_utils::{get_local_guids, get_mirror_guids};
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use crate::sync::merge::LocalLogin;
+ use nss::ensure_initialized;
+ use std::{thread, time};
+
+ #[test]
+ fn test_username_dupe_semantics() {
+ ensure_initialized();
+ let mut login = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let db = LoginDb::open_in_memory();
+ db.add(login.clone(), &*TEST_ENCDEC)
+ .expect("should be able to add first login");
+
+ // We will reject new logins with the same username value...
+ let exp_err = "Invalid login: Login already exists";
+ assert_eq!(
+ db.add(login.clone(), &*TEST_ENCDEC)
+ .unwrap_err()
+ .to_string(),
+ exp_err
+ );
+
+ // Add one with an empty username - not a dupe.
+ login.username = "".to_string();
+ db.add(login.clone(), &*TEST_ENCDEC)
+ .expect("empty login isn't a dupe");
+
+ assert_eq!(
+ db.add(login, &*TEST_ENCDEC).unwrap_err().to_string(),
+ exp_err
+ );
+
+ // one with a username, 1 without.
+ assert_eq!(db.get_all().unwrap().len(), 2);
+ }
+
+ #[test]
+ fn test_add_many() {
+ ensure_initialized();
+
+ let login_a = LoginEntry {
+ origin: "https://a.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let login_b = LoginEntry {
+ origin: "https://b.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let db = LoginDb::open_in_memory();
+ let added = db
+ .add_many(vec![login_a.clone(), login_b.clone()], &*TEST_ENCDEC)
+ .expect("should be able to add logins");
+
+ let [added_a, added_b] = added.as_slice() else {
+ panic!("there should really be 2")
+ };
+
+ let fetched_a = db
+ .get_by_id(&added_a.as_ref().unwrap().meta.id)
+ .expect("should work")
+ .expect("should get a record");
+
+ assert_eq!(fetched_a.fields.origin, login_a.origin);
+
+ let fetched_b = db
+ .get_by_id(&added_b.as_ref().unwrap().meta.id)
+ .expect("should work")
+ .expect("should get a record");
+
+ assert_eq!(fetched_b.fields.origin, login_b.origin);
+
+ assert_eq!(db.count_all().unwrap(), 2);
+ }
+
+ #[test]
+ fn test_count_by_origin() {
+ ensure_initialized();
+
+ let origin_a = "https://a.example.com";
+ let login_a = LoginEntry {
+ origin: origin_a.into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let login_b = LoginEntry {
+ origin: "https://b.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let db = LoginDb::open_in_memory();
+ db.add_many(vec![login_a.clone(), login_b.clone()], &*TEST_ENCDEC)
+ .expect("should be able to add logins");
+
+ assert_eq!(db.count_by_origin(origin_a).unwrap(), 1);
+ }
+
+ #[test]
+ fn test_count_by_form_action_origin() {
+ ensure_initialized();
+
+ let origin_a = "https://a.example.com";
+ let login_a = LoginEntry {
+ origin: origin_a.into(),
+ form_action_origin: Some(origin_a.into()),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let login_b = LoginEntry {
+ origin: "https://b.example.com".into(),
+ form_action_origin: Some("https://b.example.com".into()),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let db = LoginDb::open_in_memory();
+ db.add_many(vec![login_a.clone(), login_b.clone()], &*TEST_ENCDEC)
+ .expect("should be able to add logins");
+
+ assert_eq!(db.count_by_form_action_origin(origin_a).unwrap(), 1);
+ }
+
+ #[test]
+ fn test_add_many_with_failed_constraint() {
+ ensure_initialized();
+
+ let login_a = LoginEntry {
+ origin: "https://example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let login_b = LoginEntry {
+ // same origin will result in duplicate error
+ origin: "https://example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+
+ let db = LoginDb::open_in_memory();
+ let added = db
+ .add_many(vec![login_a.clone(), login_b.clone()], &*TEST_ENCDEC)
+ .expect("should be able to add logins");
+
+ let [added_a, added_b] = added.as_slice() else {
+ panic!("there should really be 2")
+ };
+
+ // first entry has been saved successfully
+ let fetched_a = db
+ .get_by_id(&added_a.as_ref().unwrap().meta.id)
+ .expect("should work")
+ .expect("should get a record");
+
+ assert_eq!(fetched_a.fields.origin, login_a.origin);
+
+ // second entry failed
+ assert!(!added_b.is_ok());
+ }
+
+ #[test]
+ fn test_add_with_meta() {
+ ensure_initialized();
+
+ let guid = Guid::random();
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+ let login = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+ let meta = LoginMeta {
+ id: guid.to_string(),
+ time_created: now_ms,
+ time_password_changed: now_ms + 100,
+ time_last_used: now_ms + 10,
+ times_used: 42,
+ };
+
+ let db = LoginDb::open_in_memory();
+ let entry_with_meta = LoginEntryWithMeta {
+ entry: login.clone(),
+ meta: meta.clone(),
+ };
+
+ db.add_with_meta(entry_with_meta, &*TEST_ENCDEC)
+ .expect("should be able to add login with record");
+
+ let fetched = db
+ .get_by_id(&guid)
+ .expect("should work")
+ .expect("should get a record");
+
+ assert_eq!(fetched.meta, meta);
+ }
+
+ #[test]
+ fn test_add_with_meta_deleted() {
+ ensure_initialized();
+
+ let guid = Guid::random();
+ let now_ms = util::system_time_ms_i64(SystemTime::now());
+ let login = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "sekret".into(),
+ ..LoginEntry::default()
+ };
+ let meta = LoginMeta {
+ id: guid.to_string(),
+ time_created: now_ms,
+ time_password_changed: now_ms + 100,
+ time_last_used: now_ms + 10,
+ times_used: 42,
+ };
+
+ let db = LoginDb::open_in_memory();
+ let entry_with_meta = LoginEntryWithMeta {
+ entry: login.clone(),
+ meta: meta.clone(),
+ };
+
+ db.add_with_meta(entry_with_meta, &*TEST_ENCDEC)
+ .expect("should be able to add login with record");
+
+ db.delete(&guid).expect("should be able to delete login");
+
+ let entry_with_meta2 = LoginEntryWithMeta {
+ entry: login.clone(),
+ meta: meta.clone(),
+ };
+
+ db.add_with_meta(entry_with_meta2, &*TEST_ENCDEC)
+ .expect("should be able to re-add login with record");
+
+ let fetched = db
+ .get_by_id(&guid)
+ .expect("should work")
+ .expect("should get a record");
+
+ assert_eq!(fetched.meta, meta);
+ }
+
+ #[test]
+ fn test_unicode_submit() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let added = db
+ .add(
+ LoginEntry {
+ form_action_origin: Some("http://😍.com".into()),
+ origin: "http://😍.com".into(),
+ http_realm: None,
+ username_field: "😍".into(),
+ password_field: "😍".into(),
+ username: "😍".into(),
+ password: "😍".into(),
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ let fetched = db
+ .get_by_id(&added.meta.id)
+ .expect("should work")
+ .expect("should get a record");
+ assert_eq!(added, fetched);
+ assert_eq!(fetched.fields.origin, "http://xn--r28h.com");
+ assert_eq!(
+ fetched.fields.form_action_origin,
+ Some("http://xn--r28h.com".to_string())
+ );
+ assert_eq!(fetched.fields.username_field, "😍");
+ assert_eq!(fetched.fields.password_field, "😍");
+ let sec_fields = fetched.decrypt_fields(&*TEST_ENCDEC).unwrap();
+ assert_eq!(sec_fields.username, "😍");
+ assert_eq!(sec_fields.password, "😍");
+ }
+
+ #[test]
+ fn test_unicode_realm() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let added = db
+ .add(
+ LoginEntry {
+ form_action_origin: None,
+ origin: "http://😍.com".into(),
+ http_realm: Some("😍😍".into()),
+ username: "😍".into(),
+ password: "😍".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ let fetched = db
+ .get_by_id(&added.meta.id)
+ .expect("should work")
+ .expect("should get a record");
+ assert_eq!(added, fetched);
+ assert_eq!(fetched.fields.origin, "http://xn--r28h.com");
+ assert_eq!(fetched.fields.http_realm.unwrap(), "😍😍");
+ }
+
+ fn check_matches(db: &LoginDb, query: &str, expected: &[&str]) {
+ let mut results = db
+ .get_by_base_domain(query)
+ .unwrap()
+ .into_iter()
+ .map(|l| l.fields.origin)
+ .collect::<Vec<String>>();
+ results.sort_unstable();
+ let mut sorted = expected.to_owned();
+ sorted.sort_unstable();
+ assert_eq!(sorted, results);
+ }
+
+ fn check_good_bad(
+ good: Vec<&str>,
+ bad: Vec<&str>,
+ good_queries: Vec<&str>,
+ zero_queries: Vec<&str>,
+ ) {
+ let db = LoginDb::open_in_memory();
+ for h in good.iter().chain(bad.iter()) {
+ db.add(
+ LoginEntry {
+ origin: (*h).into(),
+ http_realm: Some((*h).into()),
+ password: "test".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ }
+ for query in good_queries {
+ check_matches(&db, query, &good);
+ }
+ for query in zero_queries {
+ check_matches(&db, query, &[]);
+ }
+ }
+
+ #[test]
+ fn test_get_by_base_domain_invalid() {
+ check_good_bad(
+ vec!["https://example.com"],
+ vec![],
+ vec![],
+ vec!["invalid query"],
+ );
+ }
+
+ #[test]
+ fn test_get_by_base_domain() {
+ check_good_bad(
+ vec![
+ "https://example.com",
+ "https://www.example.com",
+ "http://www.example.com",
+ "http://www.example.com:8080",
+ "http://sub.example.com:8080",
+ "https://sub.example.com:8080",
+ "https://sub.sub.example.com",
+ "ftp://sub.example.com",
+ ],
+ vec![
+ "https://badexample.com",
+ "https://example.co",
+ "https://example.com.au",
+ ],
+ vec!["example.com"],
+ vec!["foo.com"],
+ );
+ // punycode! This is likely to need adjusting once we normalize
+ // on insert.
+ check_good_bad(
+ vec![
+ "http://xn--r28h.com", // punycoded version of "http://😍.com"
+ ],
+ vec!["http://💖.com"],
+ vec!["😍.com", "xn--r28h.com"],
+ vec![],
+ );
+ }
+
+ #[test]
+ fn test_get_by_base_domain_ipv4() {
+ check_good_bad(
+ vec!["http://127.0.0.1", "https://127.0.0.1:8000"],
+ vec!["https://127.0.0.0", "https://example.com"],
+ vec!["127.0.0.1"],
+ vec!["127.0.0.2"],
+ );
+ }
+
+ #[test]
+ fn test_get_by_base_domain_ipv6() {
+ check_good_bad(
+ vec!["http://[::1]", "https://[::1]:8000"],
+ vec!["https://[0:0:0:0:0:0:1:1]", "https://example.com"],
+ vec!["[::1]", "[0:0:0:0:0:0:0:1]"],
+ vec!["[0:0:0:0:0:0:1:2]"],
+ );
+ }
+
+ #[test]
+ fn test_add() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let to_add = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ };
+ let login = db.add(to_add, &*TEST_ENCDEC).unwrap();
+ let login2 = db.get_by_id(&login.meta.id).unwrap().unwrap();
+
+ assert_eq!(login.fields.origin, login2.fields.origin);
+ assert_eq!(login.fields.http_realm, login2.fields.http_realm);
+ assert_eq!(login.sec_fields, login2.sec_fields);
+ }
+
+ #[test]
+ fn test_update() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = db
+ .add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "user1".into(),
+ password: "password1".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ db.update(
+ &login.meta.id,
+ LoginEntry {
+ origin: "https://www.example2.com".into(),
+ http_realm: Some("https://www.example2.com".into()),
+ username: "user2".into(),
+ password: "password2".into(),
+ ..Default::default() // TODO: check and fix if needed
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ let login2 = db.get_by_id(&login.meta.id).unwrap().unwrap();
+
+ assert_eq!(login2.fields.origin, "https://www.example2.com");
+ assert_eq!(
+ login2.fields.http_realm,
+ Some("https://www.example2.com".into())
+ );
+ let sec_fields = login2.decrypt_fields(&*TEST_ENCDEC).unwrap();
+ assert_eq!(sec_fields.username, "user2");
+ assert_eq!(sec_fields.password, "password2");
+ }
+
+ #[test]
+ fn test_touch() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = db
+ .add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "user1".into(),
+ password: "password1".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ // Simulate touch happening at another "time"
+ thread::sleep(time::Duration::from_millis(50));
+ db.touch(&login.meta.id).unwrap();
+ let login2 = db.get_by_id(&login.meta.id).unwrap().unwrap();
+ assert!(login2.meta.time_last_used > login.meta.time_last_used);
+ assert_eq!(login2.meta.times_used, login.meta.times_used + 1);
+ }
+
+ #[test]
+ fn test_delete() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = db
+ .add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ assert!(db.delete(login.guid_str()).unwrap());
+
+ let local_login = db
+ .query_row(
+ "SELECT * FROM loginsL WHERE guid = :guid",
+ named_params! { ":guid": login.guid_str() },
+ |row| Ok(LocalLogin::test_raw_from_row(row).unwrap()),
+ )
+ .unwrap();
+ assert_eq!(local_login.fields.http_realm, None);
+ assert_eq!(local_login.fields.form_action_origin, None);
+
+ assert!(!db.exists(login.guid_str()).unwrap());
+ }
+
+ #[test]
+ fn test_delete_many() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+
+ let login_a = db
+ .add(
+ LoginEntry {
+ origin: "https://a.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ let login_b = db
+ .add(
+ LoginEntry {
+ origin: "https://b.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ let result = db
+ .delete_many(vec![login_a.guid_str(), login_b.guid_str()])
+ .unwrap();
+ assert!(result[0]);
+ assert!(result[1]);
+ assert!(!db.exists(login_a.guid_str()).unwrap());
+ assert!(!db.exists(login_b.guid_str()).unwrap());
+ }
+
+ #[test]
+ fn test_subsequent_delete_many() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+
+ let login = db
+ .add(
+ LoginEntry {
+ origin: "https://a.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ let result = db.delete_many(vec![login.guid_str()]).unwrap();
+ assert!(result[0]);
+ assert!(!db.exists(login.guid_str()).unwrap());
+
+ let result = db.delete_many(vec![login.guid_str()]).unwrap();
+ assert!(!result[0]);
+ }
+
+ #[test]
+ fn test_delete_many_with_non_existent_id() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+
+ let result = db.delete_many(vec![&Guid::random()]).unwrap();
+ assert!(!result[0]);
+ }
+
+ #[test]
+ fn test_delete_local_for_remote_replacement() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = db
+ .add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test_user".into(),
+ password: "test_password".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+
+ let result = db
+ .delete_local_records_for_remote_replacement(vec![login.guid_str()])
+ .unwrap();
+
+ let local_guids = get_local_guids(&db);
+ assert_eq!(local_guids.len(), 0);
+
+ let mirror_guids = get_mirror_guids(&db);
+ assert_eq!(mirror_guids.len(), 0);
+
+ assert_eq!(result.local_deleted, 1);
+ }
+
+ mod test_find_login_to_update {
+ use super::*;
+
+ fn make_entry(username: &str, password: &str) -> LoginEntry {
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("the website".into()),
+ username: username.into(),
+ password: password.into(),
+ ..Default::default()
+ }
+ }
+
+ fn make_saved_login(db: &LoginDb, username: &str, password: &str) -> Login {
+ db.add(make_entry(username, password), &*TEST_ENCDEC)
+ .unwrap()
+ .decrypt(&*TEST_ENCDEC)
+ .unwrap()
+ }
+
+ #[test]
+ fn test_match() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = make_saved_login(&db, "user", "pass");
+ assert_eq!(
+ Some(login),
+ db.find_login_to_update(make_entry("user", "pass"), &*TEST_ENCDEC)
+ .unwrap(),
+ );
+ }
+
+ #[test]
+ fn test_non_matches() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ // Non-match because the username is different
+ make_saved_login(&db, "other-user", "pass");
+ // Non-match because the http_realm is different
+ db.add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("the other website".into()),
+ username: "user".into(),
+ password: "pass".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ // Non-match because it uses form_action_origin instead of http_realm
+ db.add(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ form_action_origin: Some("https://www.example.com/".into()),
+ username: "user".into(),
+ password: "pass".into(),
+ ..Default::default()
+ },
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ assert_eq!(
+ None,
+ db.find_login_to_update(make_entry("user", "pass"), &*TEST_ENCDEC)
+ .unwrap(),
+ );
+ }
+
+ #[test]
+ fn test_match_blank_password() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ let login = make_saved_login(&db, "", "pass");
+ assert_eq!(
+ Some(login),
+ db.find_login_to_update(make_entry("user", "pass"), &*TEST_ENCDEC)
+ .unwrap(),
+ );
+ }
+
+ #[test]
+ fn test_username_match_takes_precedence_over_blank_username() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ make_saved_login(&db, "", "pass");
+ let username_match = make_saved_login(&db, "user", "pass");
+ assert_eq!(
+ Some(username_match),
+ db.find_login_to_update(make_entry("user", "pass"), &*TEST_ENCDEC)
+ .unwrap(),
+ );
+ }
+
+ #[test]
+ fn test_invalid_login() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ assert!(db
+ .find_login_to_update(
+ LoginEntry {
+ http_realm: None,
+ form_action_origin: None,
+ ..LoginEntry::default()
+ },
+ &*TEST_ENCDEC
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_update_with_duplicate_login() {
+ ensure_initialized();
+ // If we have duplicate logins in the database, it should be possible to update them
+ // without triggering a DuplicateLogin error
+ let db = LoginDb::open_in_memory();
+ let login = make_saved_login(&db, "user", "pass");
+ let mut dupe = login.clone().encrypt(&*TEST_ENCDEC).unwrap();
+ dupe.meta.id = "different-guid".to_string();
+ db.insert_new_login(&dupe).unwrap();
+
+ let mut entry = login.entry();
+ entry.password = "pass2".to_string();
+ db.update(&login.id, entry, &*TEST_ENCDEC).unwrap();
+
+ let mut entry = login.entry();
+ entry.password = "pass3".to_string();
+ db.add_or_update(entry, &*TEST_ENCDEC).unwrap();
+ }
+ }
+}
diff --git a/third_party/rust/logins/src/encryption.rs b/third_party/rust/logins/src/encryption.rs
@@ -0,0 +1,504 @@
+/* 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/.
+ */
+
+// This is the *local* encryption support - it has nothing to do with the
+// encryption used by sync.
+
+// For context, what "local encryption" means in this context is:
+// * We use regular sqlite, but ensure that sensitive data is encrypted in the DB in the
+// `secure_fields` column. The encryption key is managed by the app.
+// * The `decrypt_struct` and `encrypt_struct` functions are used to convert between an encrypted
+// `secure_fields` string and a decrypted `SecureFields` struct
+// * Most API functions return `EncryptedLogin` which has its data encrypted.
+//
+// This makes life tricky for Sync - sync has its own encryption and its own
+// management of sync keys. The entire records are encrypted on the server -
+// so the record on the server has the plain-text data (which is then
+// encrypted as part of the entire record), so:
+// * When transforming a record from the DB into a Sync record, we need to
+// *decrypt* the data.
+// * When transforming a record from Sync into a DB record, we need to *encrypt*
+// the data.
+//
+// So Sync needs to know the key etc, and that needs to get passed down
+// multiple layers, from the app saying "sync now" all the way down to the
+// low level sync code.
+// To make life a little easier, we do that via a struct.
+//
+// Consumers of the Login component have 3 options for setting up encryption:
+// 1. Implement EncryptorDecryptor directly
+// eg `LoginStore::new(MyEncryptorDecryptor)`
+// 2. Implement KeyManager and use ManagedEncryptorDecryptor
+// eg `LoginStore::new(ManagedEncryptorDecryptor::new(MyKeyManager))`
+// 3. Generate a single key and create a StaticKeyManager and use it together with
+// ManagedEncryptorDecryptor
+// eg `LoginStore::new(ManagedEncryptorDecryptor::new(StaticKeyManager { key: myKey }))`
+//
+// You can implement EncryptorDecryptor directly to keep full control over the encryption
+// algorithm. For example, on the desktop, this could make use of NSS's SecretDecoderRing to
+// achieve transparent key management.
+//
+// If the application wants to keep the current encryption, like Android and iOS, for example, but
+// control the key management itself, the KeyManager can be implemented and the encryption can be
+// done on the Rust side with the ManagedEncryptorDecryptor.
+//
+// In tests or some command line tools, it can be practical to use a static key that does not
+// change at runtime and is already present when the LoginsStore is initialized. In this case, it
+// makes sense to use the provided StaticKeyManager.
+
+use crate::error::*;
+use std::sync::Arc;
+
+#[cfg(feature = "keydb")]
+use futures::executor::block_on;
+
+#[cfg(feature = "keydb")]
+use async_trait::async_trait;
+
+#[cfg(feature = "keydb")]
+use nss::assert_initialized as assert_nss_initialized;
+#[cfg(feature = "keydb")]
+use nss::pk11::sym_key::{
+ authenticate_with_primary_password, authentication_with_primary_password_is_needed,
+ get_or_create_aes256_key,
+};
+
+/// This is the generic EncryptorDecryptor trait, as handed over to the Store during initialization.
+/// Consumers can implement either this generic trait and bring in their own crypto, or leverage the
+/// ManagedEncryptorDecryptor below, which provides encryption algorithms out of the box.
+///
+/// Note that EncryptorDecryptor must not call any LoginStore methods. The login store can call out
+/// to the EncryptorDecryptor when it's internal mutex is held so calling back in to the LoginStore
+/// may deadlock.
+pub trait EncryptorDecryptor: Send + Sync {
+ fn encrypt(&self, cleartext: Vec<u8>) -> ApiResult<Vec<u8>>;
+ fn decrypt(&self, ciphertext: Vec<u8>) -> ApiResult<Vec<u8>>;
+}
+
+impl<T: EncryptorDecryptor> EncryptorDecryptor for Arc<T> {
+ fn encrypt(&self, clearbytes: Vec<u8>) -> ApiResult<Vec<u8>> {
+ (**self).encrypt(clearbytes)
+ }
+
+ fn decrypt(&self, cipherbytes: Vec<u8>) -> ApiResult<Vec<u8>> {
+ (**self).decrypt(cipherbytes)
+ }
+}
+
+/// The ManagedEncryptorDecryptor makes use of the NSS provided cryptographic algorithms. The
+/// ManagedEncryptorDecryptor uses a KeyManager for encryption key retrieval.
+pub struct ManagedEncryptorDecryptor {
+ key_manager: Arc<dyn KeyManager>,
+}
+
+impl ManagedEncryptorDecryptor {
+ #[uniffi::constructor()]
+ pub fn new(key_manager: Arc<dyn KeyManager>) -> Self {
+ Self { key_manager }
+ }
+}
+
+impl EncryptorDecryptor for ManagedEncryptorDecryptor {
+ fn encrypt(&self, clearbytes: Vec<u8>) -> ApiResult<Vec<u8>> {
+ let keybytes = self
+ .key_manager
+ .get_key()
+ .map_err(|_| LoginsApiError::MissingKey)?;
+ let key = std::str::from_utf8(&keybytes).map_err(|_| LoginsApiError::InvalidKey)?;
+
+ let encdec = jwcrypto::EncryptorDecryptor::new(key)
+ .map_err(|_: jwcrypto::JwCryptoError| LoginsApiError::InvalidKey)?;
+
+ let cleartext =
+ std::str::from_utf8(&clearbytes).map_err(|e| LoginsApiError::EncryptionFailed {
+ reason: e.to_string(),
+ })?;
+ encdec
+ .encrypt(cleartext)
+ .map_err(
+ |e: jwcrypto::JwCryptoError| LoginsApiError::EncryptionFailed {
+ reason: e.to_string(),
+ },
+ )
+ .map(|text| text.into())
+ }
+
+ fn decrypt(&self, cipherbytes: Vec<u8>) -> ApiResult<Vec<u8>> {
+ let keybytes = self
+ .key_manager
+ .get_key()
+ .map_err(|_| LoginsApiError::MissingKey)?;
+ let key = std::str::from_utf8(&keybytes).map_err(|_| LoginsApiError::InvalidKey)?;
+
+ let encdec = jwcrypto::EncryptorDecryptor::new(key)
+ .map_err(|_: jwcrypto::JwCryptoError| LoginsApiError::InvalidKey)?;
+
+ let ciphertext =
+ std::str::from_utf8(&cipherbytes).map_err(|e| LoginsApiError::DecryptionFailed {
+ reason: e.to_string(),
+ })?;
+ encdec
+ .decrypt(ciphertext)
+ .map_err(
+ |e: jwcrypto::JwCryptoError| LoginsApiError::DecryptionFailed {
+ reason: e.to_string(),
+ },
+ )
+ .map(|text| text.into())
+ }
+}
+
+/// Consumers can implement the KeyManager in combination with the ManagedEncryptorDecryptor to hand
+/// over the encryption key whenever encryption or decryption happens.
+pub trait KeyManager: Send + Sync {
+ fn get_key(&self) -> ApiResult<Vec<u8>>;
+}
+
+/// Last but not least we provide a StaticKeyManager, which can be
+/// used in cases where there is a single key during runtime, for example in tests.
+pub struct StaticKeyManager {
+ key: String,
+}
+
+impl StaticKeyManager {
+ pub fn new(key: String) -> Self {
+ Self { key }
+ }
+}
+
+impl KeyManager for StaticKeyManager {
+ #[handle_error(Error)]
+ fn get_key(&self) -> ApiResult<Vec<u8>> {
+ Ok(self.key.as_bytes().into())
+ }
+}
+
+/// `PrimaryPasswordAuthenticator` is used in conjunction with `NSSKeyManager` to provide the
+/// primary password and the success or failure actions of the authentication process.
+#[cfg(feature = "keydb")]
+#[uniffi::export(with_foreign)]
+#[async_trait]
+pub trait PrimaryPasswordAuthenticator: Send + Sync {
+ /// Get a primary password for authentication, otherwise return the
+ /// AuthenticationCancelled error to cancel the authentication process.
+ async fn get_primary_password(&self) -> ApiResult<String>;
+ async fn on_authentication_success(&self) -> ApiResult<()>;
+ async fn on_authentication_failure(&self) -> ApiResult<()>;
+}
+
+/// Use the `NSSKeyManager` to use NSS for key management.
+///
+/// NSS stores keys in `key4.db` within the profile and wraps the key with a key derived from the
+/// primary password, if set. It defers to the provided `PrimaryPasswordAuthenticator`
+/// implementation to handle user authentication. Note that if no primary password is set, the
+/// wrapping key is deterministically derived from an empty string.
+///
+/// Make sure to initialize NSS using `ensure_initialized_with_profile_dir` before creating a
+/// NSSKeyManager.
+///
+/// # Examples
+/// ```no_run
+/// use async_trait::async_trait;
+/// use logins::encryption::KeyManager;
+/// use logins::{PrimaryPasswordAuthenticator, LoginsApiError, NSSKeyManager};
+/// use std::sync::Arc;
+///
+/// struct MyPrimaryPasswordAuthenticator {}
+///
+/// #[async_trait]
+/// impl PrimaryPasswordAuthenticator for MyPrimaryPasswordAuthenticator {
+/// async fn get_primary_password(&self) -> Result<String, LoginsApiError> {
+/// // Most likely, you would want to prompt for a password.
+/// // let password = prompt_string("primary password").unwrap_or_default();
+/// Ok("secret".to_string())
+/// }
+///
+/// async fn on_authentication_success(&self) -> Result<(), LoginsApiError> {
+/// println!("success");
+/// Ok(())
+/// }
+///
+/// async fn on_authentication_failure(&self) -> Result<(), LoginsApiError> {
+/// println!("this did not work, please try again:");
+/// Ok(())
+/// }
+/// }
+/// let key_manager = NSSKeyManager::new(Arc::new(MyPrimaryPasswordAuthenticator {}));
+/// assert_eq!(key_manager.get_key().unwrap().len(), 63);
+/// ```
+#[cfg(feature = "keydb")]
+#[derive(uniffi::Object)]
+pub struct NSSKeyManager {
+ primary_password_authenticator: Arc<dyn PrimaryPasswordAuthenticator>,
+}
+
+#[cfg(feature = "keydb")]
+#[uniffi::export]
+impl NSSKeyManager {
+ /// Initialize new `NSSKeyManager` with a given `PrimaryPasswordAuthenticator`.
+ /// There must be a previous initializiation of NSS before initializing
+ /// `NSSKeyManager`, otherwise this panics.
+ #[uniffi::constructor()]
+ pub fn new(primary_password_authenticator: Arc<dyn PrimaryPasswordAuthenticator>) -> Self {
+ assert_nss_initialized();
+ Self {
+ primary_password_authenticator,
+ }
+ }
+
+ pub fn into_dyn_key_manager(self: Arc<Self>) -> Arc<dyn KeyManager> {
+ self
+ }
+}
+
+/// Identifier for the logins key, under which the key is stored in NSS.
+#[cfg(feature = "keydb")]
+static KEY_NAME: &str = "as-logins-key";
+
+// wrapp `authentication_with_primary_password_is_needed` into an ApiResult
+#[cfg(feature = "keydb")]
+fn api_authentication_with_primary_password_is_needed() -> ApiResult<bool> {
+ authentication_with_primary_password_is_needed().map_err(|e: nss::Error| {
+ LoginsApiError::NSSAuthenticationError {
+ reason: e.to_string(),
+ }
+ })
+}
+
+// wrapp `authenticate_with_primary_password` into an ApiResult
+#[cfg(feature = "keydb")]
+fn api_authenticate_with_primary_password(primary_password: &str) -> ApiResult<bool> {
+ authenticate_with_primary_password(primary_password).map_err(|e: nss::Error| {
+ LoginsApiError::NSSAuthenticationError {
+ reason: e.to_string(),
+ }
+ })
+}
+
+#[cfg(feature = "keydb")]
+impl KeyManager for NSSKeyManager {
+ fn get_key(&self) -> ApiResult<Vec<u8>> {
+ if api_authentication_with_primary_password_is_needed()? {
+ let primary_password =
+ block_on(self.primary_password_authenticator.get_primary_password())?;
+ let mut result = api_authenticate_with_primary_password(&primary_password)?;
+
+ if result {
+ block_on(
+ self.primary_password_authenticator
+ .on_authentication_success(),
+ )?;
+ } else {
+ while !result {
+ block_on(
+ self.primary_password_authenticator
+ .on_authentication_failure(),
+ )?;
+
+ let primary_password =
+ block_on(self.primary_password_authenticator.get_primary_password())?;
+ result = api_authenticate_with_primary_password(&primary_password)?;
+ }
+ block_on(
+ self.primary_password_authenticator
+ .on_authentication_success(),
+ )?;
+ }
+ }
+
+ let key = get_or_create_aes256_key(KEY_NAME).expect("Could not get or create key via NSS");
+ let mut bytes: Vec<u8> = Vec::new();
+ serde_json::to_writer(
+ &mut bytes,
+ &jwcrypto::Jwk::new_direct_from_bytes(None, &key),
+ )
+ .unwrap();
+ Ok(bytes)
+ }
+}
+
+#[handle_error(Error)]
+pub fn create_canary(text: &str, key: &str) -> ApiResult<String> {
+ Ok(jwcrypto::EncryptorDecryptor::new(key)?.create_canary(text)?)
+}
+
+pub fn check_canary(canary: &str, text: &str, key: &str) -> ApiResult<bool> {
+ let encdec = jwcrypto::EncryptorDecryptor::new(key)
+ .map_err(|_: jwcrypto::JwCryptoError| LoginsApiError::InvalidKey)?;
+ Ok(encdec.check_canary(canary, text).unwrap_or(false))
+}
+
+#[handle_error(Error)]
+pub fn create_key() -> ApiResult<String> {
+ Ok(jwcrypto::EncryptorDecryptor::create_key()?)
+}
+
+#[cfg(test)]
+pub mod test_utils {
+ use super::*;
+ use serde::{de::DeserializeOwned, Serialize};
+
+ lazy_static::lazy_static! {
+ pub static ref TEST_ENCRYPTION_KEY: String = serde_json::to_string(&jwcrypto::Jwk::new_direct_key(Some("test-key".to_string())).unwrap()).unwrap();
+ pub static ref TEST_ENCDEC: Arc<ManagedEncryptorDecryptor> = Arc::new(ManagedEncryptorDecryptor::new(Arc::new(StaticKeyManager { key: TEST_ENCRYPTION_KEY.clone() })));
+ }
+
+ pub fn encrypt_struct<T: Serialize>(fields: &T) -> String {
+ let string = serde_json::to_string(fields).unwrap();
+ let cipherbytes = TEST_ENCDEC.encrypt(string.as_bytes().into()).unwrap();
+ std::str::from_utf8(&cipherbytes).unwrap().to_owned()
+ }
+ pub fn decrypt_struct<T: DeserializeOwned>(ciphertext: String) -> T {
+ let jsonbytes = TEST_ENCDEC.decrypt(ciphertext.as_bytes().into()).unwrap();
+ serde_json::from_str(std::str::from_utf8(&jsonbytes).unwrap()).unwrap()
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod test {
+ use super::*;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn test_static_key_manager() {
+ ensure_initialized();
+ let key = create_key().unwrap();
+ let key_manager = StaticKeyManager { key: key.clone() };
+ assert_eq!(key.as_bytes(), key_manager.get_key().unwrap());
+ }
+
+ #[test]
+ fn test_managed_encdec_with_invalid_key() {
+ ensure_initialized();
+ let key_manager = Arc::new(StaticKeyManager {
+ key: "bad_key".to_owned(),
+ });
+ let encdec = ManagedEncryptorDecryptor { key_manager };
+ assert!(matches!(
+ encdec.encrypt("secret".as_bytes().into()).err().unwrap(),
+ LoginsApiError::InvalidKey
+ ));
+ }
+
+ #[test]
+ fn test_managed_encdec_with_missing_key() {
+ ensure_initialized();
+ struct MyKeyManager {}
+ impl KeyManager for MyKeyManager {
+ fn get_key(&self) -> ApiResult<Vec<u8>> {
+ Err(LoginsApiError::MissingKey)
+ }
+ }
+ let key_manager = Arc::new(MyKeyManager {});
+ let encdec = ManagedEncryptorDecryptor { key_manager };
+ assert!(matches!(
+ encdec.encrypt("secret".as_bytes().into()).err().unwrap(),
+ LoginsApiError::MissingKey
+ ));
+ }
+
+ #[test]
+ fn test_managed_encdec() {
+ ensure_initialized();
+ let key = create_key().unwrap();
+ let key_manager = Arc::new(StaticKeyManager { key });
+ let encdec = ManagedEncryptorDecryptor { key_manager };
+ let cleartext = "secret";
+ let ciphertext = encdec.encrypt(cleartext.as_bytes().into()).unwrap();
+ assert_eq!(
+ encdec.decrypt(ciphertext.clone()).unwrap(),
+ cleartext.as_bytes()
+ );
+ let other_encdec = ManagedEncryptorDecryptor {
+ key_manager: Arc::new(StaticKeyManager {
+ key: create_key().unwrap(),
+ }),
+ };
+
+ assert_eq!(
+ other_encdec.decrypt(ciphertext).err().unwrap().to_string(),
+ "decryption failed: Crypto error: NSS error: NSS error: -8190 "
+ );
+ }
+
+ #[test]
+ fn test_key_error() {
+ let storage_err = jwcrypto::EncryptorDecryptor::new("bad-key").err().unwrap();
+ println!("{storage_err:?}");
+ assert!(matches!(storage_err, jwcrypto::JwCryptoError::InvalidKey));
+ }
+
+ #[test]
+ fn test_canary_functionality() {
+ ensure_initialized();
+ const CANARY_TEXT: &str = "Arbitrary sequence of text";
+ let key = create_key().unwrap();
+ let canary = create_canary(CANARY_TEXT, &key).unwrap();
+ assert!(check_canary(&canary, CANARY_TEXT, &key).unwrap());
+
+ let different_key = create_key().unwrap();
+ assert!(!check_canary(&canary, CANARY_TEXT, &different_key).unwrap());
+
+ let bad_key = "bad_key".to_owned();
+ assert!(matches!(
+ check_canary(&canary, CANARY_TEXT, &bad_key).err().unwrap(),
+ LoginsApiError::InvalidKey
+ ));
+ }
+}
+
+#[cfg(feature = "keydb")]
+#[cfg(test)]
+mod keydb_test {
+ use super::*;
+ use nss::ensure_initialized_with_profile_dir;
+ use std::path::PathBuf;
+
+ struct MockPrimaryPasswordAuthenticator {
+ password: String,
+ }
+
+ #[async_trait]
+ impl PrimaryPasswordAuthenticator for MockPrimaryPasswordAuthenticator {
+ async fn get_primary_password(&self) -> ApiResult<String> {
+ Ok(self.password.clone())
+ }
+ async fn on_authentication_success(&self) -> ApiResult<()> {
+ Ok(())
+ }
+ async fn on_authentication_failure(&self) -> ApiResult<()> {
+ Ok(())
+ }
+ }
+
+ fn profile_path() -> PathBuf {
+ std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("fixtures/profile")
+ }
+
+ #[test]
+ fn test_ensure_initialized_with_profile_dir() {
+ ensure_initialized_with_profile_dir(profile_path());
+ }
+
+ #[test]
+ fn test_create_key() {
+ ensure_initialized_with_profile_dir(profile_path());
+ let key = create_key().unwrap();
+ assert_eq!(key.len(), 63)
+ }
+
+ #[test]
+ fn test_nss_key_manager() {
+ ensure_initialized_with_profile_dir(profile_path());
+ let mock_primary_password_authenticator = MockPrimaryPasswordAuthenticator {
+ password: "password".to_string(),
+ };
+ let nss_key_manager = NSSKeyManager {
+ primary_password_authenticator: Arc::new(mock_primary_password_authenticator),
+ };
+ assert_eq!(nss_key_manager.get_key().unwrap().len(), 63)
+ }
+}
diff --git a/third_party/rust/logins/src/error.rs b/third_party/rust/logins/src/error.rs
@@ -0,0 +1,226 @@
+/* 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::ffi::OsString;
+pub type Result<T> = std::result::Result<T, Error>;
+// Functions which are part of the public API should use this Result.
+pub type ApiResult<T> = std::result::Result<T, LoginsApiError>;
+
+pub use error_support::{breadcrumb, handle_error, report_error};
+pub use error_support::{debug, error, info, trace, warn};
+
+use error_support::{ErrorHandling, GetErrorHandling};
+use jwcrypto::JwCryptoError;
+use sync15::Error as Sync15Error;
+
+// Errors we return via the public interface.
+#[derive(Debug, thiserror::Error)]
+pub enum LoginsApiError {
+ #[error("NSS not initialized")]
+ NSSUninitialized,
+
+ #[error("NSS error during authentication: {reason}")]
+ NSSAuthenticationError { reason: String },
+
+ #[error("error during authentication: {reason}")]
+ AuthenticationError { reason: String },
+
+ #[error("authentication cancelled")]
+ AuthenticationCanceled,
+
+ #[error("Invalid login: {reason}")]
+ InvalidRecord { reason: String },
+
+ #[error("No record with guid exists (when one was required): {reason:?}")]
+ NoSuchRecord { reason: String },
+
+ #[error("Encryption key is missing.")]
+ MissingKey,
+
+ #[error("Encryption key is not valid.")]
+ InvalidKey,
+
+ #[error("encryption failed: {reason}")]
+ EncryptionFailed { reason: String },
+
+ #[error("decryption failed: {reason}")]
+ DecryptionFailed { reason: String },
+
+ #[error("{reason}")]
+ Interrupted { reason: String },
+
+ #[error("SyncAuthInvalid error {reason}")]
+ SyncAuthInvalid { reason: String },
+
+ #[error("Unexpected Error: {reason}")]
+ UnexpectedLoginsApiError { reason: String },
+}
+
+/// Logins error type
+/// These are "internal" errors used by the implementation. This error type
+/// is never returned to the consumer.
+#[derive(Debug, thiserror::Error)]
+pub enum Error {
+ #[error("Database is closed")]
+ DatabaseClosed,
+
+ #[error("Malformed incoming record")]
+ MalformedIncomingRecord,
+
+ #[error("Invalid login: {0}")]
+ InvalidLogin(#[from] InvalidLogin),
+
+ #[error("The `sync_status` column in DB has an illegal value: {0}")]
+ BadSyncStatus(u8),
+
+ #[error("No record with guid exists (when one was required): {0:?}")]
+ NoSuchRecord(String),
+
+ // Fennec import only works on empty logins tables.
+ #[error("The logins tables are not empty")]
+ NonEmptyTable,
+
+ #[error("encryption failed: {0:?}")]
+ EncryptionFailed(String),
+
+ #[error("decryption failed: {0:?}")]
+ DecryptionFailed(String),
+
+ #[error("Error synchronizing: {0}")]
+ SyncAdapterError(#[from] sync15::Error),
+
+ #[error("Error parsing JSON data: {0}")]
+ JsonError(#[from] serde_json::Error),
+
+ #[error("Error executing SQL: {0}")]
+ SqlError(#[from] rusqlite::Error),
+
+ #[error("Error parsing URL: {0}")]
+ UrlParseError(#[from] url::ParseError),
+
+ #[error("Invalid path: {0:?}")]
+ InvalidPath(OsString),
+
+ #[error("CryptoError({0})")]
+ CryptoError(#[from] JwCryptoError),
+
+ #[error("{0}")]
+ Interrupted(#[from] interrupt_support::Interrupted),
+
+ #[error("IOError: {0}")]
+ IOError(#[from] std::io::Error),
+
+ #[error("Migration Error: {0}")]
+ MigrationError(String),
+}
+
+/// Error::InvalidLogin subtypes
+#[derive(Debug, thiserror::Error)]
+pub enum InvalidLogin {
+ // EmptyOrigin error occurs when the login's origin field is empty.
+ #[error("Origin is empty")]
+ EmptyOrigin,
+ #[error("Password is empty")]
+ EmptyPassword,
+ #[error("Login already exists")]
+ DuplicateLogin,
+ #[error("Both `formActionOrigin` and `httpRealm` are present")]
+ BothTargets,
+ #[error("Neither `formActionOrigin` or `httpRealm` are present")]
+ NoTarget,
+ // Login has an illegal origin field, split off from IllegalFieldValue since this is a known
+ // issue with the Desktop logins and we don't want to report it to Sentry (see #5233).
+ #[error("Login has illegal origin")]
+ IllegalOrigin,
+ #[error("Login has illegal field: {field_info}")]
+ IllegalFieldValue { field_info: String },
+}
+
+// Define how our internal errors are handled and converted to external errors
+// See `support/error/README.md` for how this works, especially the warning about PII.
+impl GetErrorHandling for Error {
+ type ExternalError = LoginsApiError;
+
+ fn get_error_handling(&self) -> ErrorHandling<Self::ExternalError> {
+ match self {
+ Self::InvalidLogin(why) => ErrorHandling::convert(LoginsApiError::InvalidRecord {
+ reason: why.to_string(),
+ }),
+ Self::MalformedIncomingRecord => {
+ ErrorHandling::convert(LoginsApiError::InvalidRecord {
+ reason: "invalid incoming record".to_string(),
+ })
+ }
+ // Our internal "no such record" error is converted to our public "no such record" error, with no logging and no error reporting.
+ Self::NoSuchRecord(guid) => ErrorHandling::convert(LoginsApiError::NoSuchRecord {
+ reason: guid.to_string(),
+ }),
+ // NonEmptyTable error is just a sanity check to ensure we aren't asked to migrate into an
+ // existing DB - consumers should never actually do this, and will never expect to handle this as a specific
+ // error - so it gets reported to the error reporter and converted to an "internal" error.
+ Self::NonEmptyTable => {
+ ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: "must be an empty DB to migrate".to_string(),
+ })
+ .report_error("logins-migration")
+ }
+ Self::Interrupted(_) => ErrorHandling::convert(LoginsApiError::Interrupted {
+ reason: self.to_string(),
+ }),
+ Self::SyncAdapterError(e) => match e {
+ Sync15Error::TokenserverHttpError(401) | Sync15Error::BadKeyLength(..) => {
+ ErrorHandling::convert(LoginsApiError::SyncAuthInvalid {
+ reason: e.to_string(),
+ })
+ .log_warning()
+ }
+ Sync15Error::RequestError(_) => {
+ ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: e.to_string(),
+ })
+ .log_warning()
+ }
+ _ => ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: self.to_string(),
+ })
+ .report_error("logins-sync"),
+ },
+ Error::SqlError(rusqlite::Error::SqliteFailure(err, _)) => match err.code {
+ rusqlite::ErrorCode::DatabaseCorrupt => {
+ ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: self.to_string(),
+ })
+ .report_error("logins-db-corrupt")
+ }
+ rusqlite::ErrorCode::DiskFull => {
+ ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: self.to_string(),
+ })
+ .report_error("logins-db-disk-full")
+ }
+ _ => ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: self.to_string(),
+ })
+ .report_error("logins-unexpected"),
+ },
+ // Unexpected errors that we report to Sentry. We should watch the reports for these
+ // and do one or more of these things if we see them:
+ // - Fix the underlying issue
+ // - Add breadcrumbs or other context to help uncover the issue
+ // - Decide that these are expected errors and move them to the above case
+ _ => ErrorHandling::convert(LoginsApiError::UnexpectedLoginsApiError {
+ reason: self.to_string(),
+ })
+ .report_error("logins-unexpected"),
+ }
+ }
+}
+
+impl From<uniffi::UnexpectedUniFFICallbackError> for LoginsApiError {
+ fn from(error: uniffi::UnexpectedUniFFICallbackError) -> Self {
+ LoginsApiError::UnexpectedLoginsApiError {
+ reason: error.to_string(),
+ }
+ }
+}
diff --git a/third_party/rust/logins/src/lib.rs b/third_party/rust/logins/src/lib.rs
@@ -0,0 +1,73 @@
+/* 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/. */
+
+#![allow(unknown_lints)]
+#![warn(rust_2018_idioms)]
+
+#[macro_use]
+mod error;
+mod login;
+
+mod db;
+pub mod encryption;
+mod schema;
+mod store;
+mod sync;
+mod util;
+
+use crate::encryption::{
+ EncryptorDecryptor, KeyManager, ManagedEncryptorDecryptor, StaticKeyManager,
+};
+uniffi::include_scaffolding!("logins");
+
+#[cfg(feature = "keydb")]
+pub use crate::encryption::{NSSKeyManager, PrimaryPasswordAuthenticator};
+
+pub use crate::db::{LoginDb, LoginsDeletionMetrics};
+use crate::encryption::{check_canary, create_canary, create_key};
+pub use crate::error::*;
+pub use crate::login::*;
+pub use crate::store::*;
+pub use crate::sync::LoginsSyncEngine;
+use std::sync::Arc;
+
+// Utility function to create a StaticKeyManager to be used for the time being until support lands
+// for [trait implementation of an UniFFI
+// interface](https://mozilla.github.io/uniffi-rs/next/proc_macro/index.html#structs-implementing-traits)
+// in UniFFI.
+pub fn create_static_key_manager(key: String) -> Arc<StaticKeyManager> {
+ Arc::new(StaticKeyManager::new(key))
+}
+
+// Similar to create_static_key_manager above, create a
+// ManagedEncryptorDecryptor by passing in a KeyManager
+pub fn create_managed_encdec(key_manager: Arc<dyn KeyManager>) -> Arc<ManagedEncryptorDecryptor> {
+ Arc::new(ManagedEncryptorDecryptor::new(key_manager))
+}
+
+// Create a LoginStore by passing in a db path and a static key
+//
+// Note this is only temporarily needed until a bug with UniFFI and JavaScript is fixed, which
+// prevents passing around traits in JS
+pub fn create_login_store_with_static_key_manager(path: String, key: String) -> Arc<LoginStore> {
+ let encdec: ManagedEncryptorDecryptor =
+ ManagedEncryptorDecryptor::new(Arc::new(StaticKeyManager::new(key)));
+ Arc::new(LoginStore::new(path, Arc::new(encdec)).unwrap())
+}
+
+// Create a LoginStore with NSSKeyManager by passing in a db path and a PrimaryPasswordAuthenticator.
+//
+// Note this is only temporarily needed until a bug with UniFFI and JavaScript is fixed, which
+// prevents passing around traits in JS
+#[cfg(feature = "keydb")]
+#[uniffi::export]
+pub fn create_login_store_with_nss_keymanager(
+ path: String,
+ primary_password_authenticator: Arc<dyn PrimaryPasswordAuthenticator>,
+) -> Arc<LoginStore> {
+ let encdec: ManagedEncryptorDecryptor = ManagedEncryptorDecryptor::new(Arc::new(
+ NSSKeyManager::new(primary_password_authenticator),
+ ));
+ Arc::new(LoginStore::new(path, Arc::new(encdec)).unwrap())
+}
diff --git a/third_party/rust/logins/src/login.rs b/third_party/rust/logins/src/login.rs
@@ -0,0 +1,1299 @@
+/* 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/. */
+
+// N.B. if you're making a documentation change here, you might also want to make it in:
+//
+// * The API docs in ../ios/Logins/LoginRecord.swift
+// * The API docs in ../android/src/main/java/mozilla/appservices/logins/ServerPassword.kt
+// * The android-components docs at
+// https://github.com/mozilla-mobile/android-components/tree/master/components/service/sync-logins
+//
+// We'll figure out a more scalable approach to maintaining all those docs at some point...
+
+//! # Login Structs
+//!
+//! This module defines a number of core structs for Logins. They are:
+//! * [`LoginEntry`] A login entry by the user. This includes the username/password, the site it
+//! was submitted to, etc. [`LoginEntry`] does not store data specific to a DB record.
+//! * [`Login`] - A [`LoginEntry`] plus DB record information. This includes the GUID and metadata
+//! like time_last_used.
+//! * [`EncryptedLogin`] -- A Login above with the username/password data encrypted.
+//! * [`LoginFields`], [`SecureLoginFields`], [`LoginMeta`] -- These group the common fields in the
+//! structs above.
+//!
+//! Why so many structs for similar data? Consider some common use cases in a hypothetical browser
+//! (currently no browsers act exactly like this, although Fenix/android-components comes close):
+//!
+//! - User visits a page with a login form.
+//! - We inform the user if there are saved logins that can be autofilled. We use the
+//! `LoginDb.get_by_base_domain()` which returns a `Vec<EncryptedLogin>`. We don't decrypt the
+//! logins because we want to avoid requiring the encryption key at this point, which would
+//! force the user to authenticate. Note: this is aspirational at this point, no actual
+//! implementations follow this flow. Still, we want application-services to support it.
+//! - If the user chooses to autofill, we decrypt the logins into a `Vec<Login>`. We need to
+//! decrypt at this point to display the username and autofill the password if they select one.
+//! - When the user selects a login, we can use the already decrypted data from `Login` to fill
+//! in the form.
+//! - User chooses to save a login for autofilling later.
+//! - We present the user with a dialog that:
+//! - Displays a header that differentiates between different types of save: adding a new
+//! login, updating an existing login, filling in a blank username, etc.
+//! - Allows the user to tweak the username, in case we failed to detect the form field
+//! correctly. This may affect which header should be shown.
+//! - Here we use `find_login_to_update()` which returns an `Option<Login>`. Returning a login
+//! that has decrypted data avoids forcing the consumer code to decrypt the username again.
+//!
+//! # Login
+//! This has the complete set of data about a login. Very closely related is the
+//! "sync payload", defined in sync/payload.rs, which handles all aspects of the JSON serialization.
+//! It contains the following fields:
+//! - `meta`: A [`LoginMeta`] struct.
+//! - fields: A [`LoginFields`] struct.
+//! - sec_fields: A [`SecureLoginFields`] struct.
+//!
+//! # LoginEntry
+//! The struct used to add or update logins. This has the plain-text version of the fields that are
+//! stored encrypted, so almost all uses of an LoginEntry struct will also require the
+//! encryption key to be known and passed in. [LoginDB] methods that save data typically input
+//! [LoginEntry] instances. This allows the DB code to handle dupe-checking issues like
+//! determining which login record should be updated for a newly submitted [LoginEntry].
+//! It contains the following fields:
+//! - fields: A [`LoginFields`] struct.
+//! - sec_fields: A [`SecureLoginFields`] struct.
+//!
+//! # EncryptedLogin
+//! Encrypted version of [`Login`]. [LoginDB] methods that return data typically return [EncryptedLogin]
+//! this allows deferring decryption, and therefore user authentication, until the secure data is needed.
+//! It contains the following fields
+//! - `meta`: A [`LoginMeta`] struct.
+//! - `fields`: A [`LoginFields`] struct.
+//! - `sec_fields`: The secure fields as an encrypted string
+//!
+//! # SecureLoginFields
+//! The struct used to hold the fields which are stored encrypted. It contains:
+//! - username: A string.
+//! - password: A string.
+//!
+//! # LoginFields
+//!
+//! The core set of fields, use by both [`Login`] and [`LoginEntry`]
+//! It contains the following fields:
+//!
+//! - `origin`: The origin at which this login can be used, as a string.
+//!
+//! The login should only be used on sites that match this origin (for whatever definition
+//! of "matches" makes sense at the application level, e.g. eTLD+1 matching).
+//! This field is required, must be a valid origin in punycode format, and must not be
+//! set to the empty string.
+//!
+//! Examples of valid `origin` values include:
+//! - "https://site.com"
+//! - "http://site.com:1234"
+//! - "ftp://ftp.site.com"
+//! - "moz-proxy://127.0.0.1:8888"
+//! - "chrome://MyLegacyExtension"
+//! - "file://"
+//! - "https://\[::1\]"
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - truncating full URLs to just their origin component, if it is not an opaque origin
+//! - converting values with non-ascii characters into punycode
+//!
+//! **XXX TODO:**
+//! - Add a field with the original unicode versions of the URLs instead of punycode?
+//!
+//! - `sec_fields`: The `username` and `password` for the site, stored as a encrypted JSON
+//! representation of an `SecureLoginFields`.
+//!
+//! This field is required and usually encrypted. There are two different value types:
+//! - Plaintext empty string: Used for deleted records
+//! - Encrypted value: The credentials associated with the login.
+//!
+//! - `http_realm`: The challenge string for HTTP Basic authentication, if any.
+//!
+//! If present, the login should only be used in response to a HTTP Basic Auth
+//! challenge that specifies a matching realm. For legacy reasons this string may not
+//! contain null bytes, carriage returns or newlines.
+//!
+//! If this field is set to the empty string, this indicates a wildcard match on realm.
+//!
+//! This field must not be present if `form_action_origin` is set, since they indicate different types
+//! of login (HTTP-Auth based versus form-based). Exactly one of `http_realm` and `form_action_origin`
+//! must be present.
+//!
+//! - `form_action_origin`: The target origin of forms in which this login can be used, if any, as a string.
+//!
+//! If present, the login should only be used in forms whose target submission URL matches this origin.
+//! This field must be a valid origin or one of the following special cases:
+//! - An empty string, which is a wildcard match for any origin.
+//! - The single character ".", which is equivalent to the empty string
+//! - The string "javascript:", which matches any form with javascript target URL.
+//!
+//! This field must not be present if `http_realm` is set, since they indicate different types of login
+//! (HTTP-Auth based versus form-based). Exactly one of `http_realm` and `form_action_origin` must be present.
+//!
+//! If invalid data is received in this field (either from the application, or via sync) then the
+//! logins store will attempt to coerce it into valid data by:
+//! - truncating full URLs to just their origin component
+//! - converting origins with non-ascii characters into punycode
+//! - replacing invalid values with null if a valid 'http_realm' field is present
+//!
+//! - `username_field`: The name of the form field into which the 'username' should be filled, if any.
+//!
+//! This value is stored if provided by the application, but does not imply any restrictions on
+//! how the login may be used in practice. For legacy reasons this string may not contain null
+//! bytes, carriage returns or newlines. This field must be empty unless `form_action_origin` is set.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - setting to the empty string if 'form_action_origin' is not present
+//!
+//! - `password_field`: The name of the form field into which the 'password' should be filled, if any.
+//!
+//! This value is stored if provided by the application, but does not imply any restrictions on
+//! how the login may be used in practice. For legacy reasons this string may not contain null
+//! bytes, carriage returns or newlines. This field must be empty unless `form_action_origin` is set.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - setting to the empty string if 'form_action_origin' is not present
+//!
+//! # LoginMeta
+//!
+//! This contains data relating to the login database record -- both on the local instance and
+//! synced to other browsers.
+//! It contains the following fields:
+//! - `id`: A unique string identifier for this record.
+//!
+//! Consumers may assume that `id` contains only "safe" ASCII characters but should otherwise
+//! treat this it as an opaque identifier. These are generated as needed.
+//!
+//! - `timesUsed`: A lower bound on the number of times the password from this record has been used, as an integer.
+//!
+//! Applications should use the `touch()` method of the logins store to indicate when a password
+//! has been used, and should ensure that they only count uses of the actual `password` field
+//! (so for example, copying the `password` field to the clipboard should count as a "use", but
+//! copying just the `username` field should not).
+//!
+//! This number may not record uses that occurred on other devices, since some legacy
+//! sync clients do not record this information. It may be zero for records obtained
+//! via sync that have never been used locally.
+//!
+//! When merging duplicate records, the two usage counts are summed.
+//!
+//! This field is managed internally by the logins store by default and does not need to
+//! be set explicitly, although any application-provided value will be preserved when creating
+//! a new record.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - replacing missing or negative values with 0
+//!
+//! **XXX TODO:**
+//! - test that we prevent this counter from moving backwards.
+//! - test fixups of missing or negative values
+//! - test that we correctly merge dupes
+//!
+//! - `time_created`: An upper bound on the time of creation of this login, in integer milliseconds from the unix epoch.
+//!
+//! This is an upper bound because some legacy sync clients do not record this information.
+//!
+//! Note that this field is typically a timestamp taken from the local machine clock, so it
+//! may be wildly inaccurate if the client does not have an accurate clock.
+//!
+//! This field is managed internally by the logins store by default and does not need to
+//! be set explicitly, although any application-provided value will be preserved when creating
+//! a new record.
+//!
+//! When merging duplicate records, the smallest non-zero value is taken.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - replacing missing or negative values with the current time
+//!
+//! **XXX TODO:**
+//! - test that we prevent this timestamp from moving backwards.
+//! - test fixups of missing or negative values
+//! - test that we correctly merge dupes
+//!
+//! - `time_last_used`: A lower bound on the time of last use of this login, in integer milliseconds from the unix epoch.
+//!
+//! This is a lower bound because some legacy sync clients do not record this information;
+//! in that case newer clients set `timeLastUsed` when they use the record for the first time.
+//!
+//! Note that this field is typically a timestamp taken from the local machine clock, so it
+//! may be wildly inaccurate if the client does not have an accurate clock.
+//!
+//! This field is managed internally by the logins store by default and does not need to
+//! be set explicitly, although any application-provided value will be preserved when creating
+//! a new record.
+//!
+//! When merging duplicate records, the largest non-zero value is taken.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - removing negative values
+//!
+//! **XXX TODO:**
+//! - test that we prevent this timestamp from moving backwards.
+//! - test fixups of missing or negative values
+//! - test that we correctly merge dupes
+//!
+//! - `time_password_changed`: A lower bound on the time that the `password` field was last changed, in integer
+//! milliseconds from the unix epoch.
+//!
+//! Changes to other fields (such as `username`) are not reflected in this timestamp.
+//! This is a lower bound because some legacy sync clients do not record this information;
+//! in that case newer clients set `time_password_changed` when they change the `password` field.
+//!
+//! Note that this field is typically a timestamp taken from the local machine clock, so it
+//! may be wildly inaccurate if the client does not have an accurate clock.
+//!
+//! This field is managed internally by the logins store by default and does not need to
+//! be set explicitly, although any application-provided value will be preserved when creating
+//! a new record.
+//!
+//! When merging duplicate records, the largest non-zero value is taken.
+//!
+//! If invalid data is received in this field (either from the application, or via sync)
+//! then the logins store will attempt to coerce it into valid data by:
+//! - removing negative values
+//!
+//! **XXX TODO:**
+//! - test that we prevent this timestamp from moving backwards.
+//! - test that we don't set this for changes to other fields.
+//! - test that we correctly merge dupes
+//!
+//!
+//! In order to deal with data from legacy clients in a robust way, it is necessary to be able to build
+//! and manipulate all these `Login` structs that contain invalid data. The non-encrypted structs
+//! implement the `ValidateAndFixup` trait, providing the following methods which can be used by
+//! callers to ensure that they're only working with valid records:
+//!
+//! - `Login::check_valid()`: Checks validity of a login record, returning `()` if it is valid
+//! or an error if it is not.
+//!
+//! - `Login::fixup()`: Returns either the existing login if it is valid, a clone with invalid fields
+//! fixed up if it was safe to do so, or an error if the login is irreparably invalid.
+
+use crate::{encryption::EncryptorDecryptor, error::*};
+use rusqlite::Row;
+use serde_derive::*;
+use sync_guid::Guid;
+use url::Url;
+
+// LoginEntry fields that are stored in cleartext
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
+pub struct LoginFields {
+ pub origin: String,
+ pub form_action_origin: Option<String>,
+ pub http_realm: Option<String>,
+ pub username_field: String,
+ pub password_field: String,
+}
+
+/// LoginEntry fields that are stored encrypted
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Default)]
+pub struct SecureLoginFields {
+ // - Username cannot be null, use the empty string instead
+ // - Password can't be empty or null (enforced in the ValidateAndFixup code)
+ //
+ // This matches the desktop behavior:
+ // https://searchfox.org/mozilla-central/rev/d3683dbb252506400c71256ef3994cdbdfb71ada/toolkit/components/passwordmgr/LoginManager.jsm#260-267
+
+ // Because we store the json version of this in the DB, and that's the only place the json
+ // is used, we rename the fields to short names, just to reduce the overhead in the DB.
+ #[serde(rename = "u")]
+ pub username: String,
+ #[serde(rename = "p")]
+ pub password: String,
+}
+
+impl SecureLoginFields {
+ pub fn encrypt(&self, encdec: &dyn EncryptorDecryptor, login_id: &str) -> Result<String> {
+ let string = serde_json::to_string(&self)?;
+ let cipherbytes = encdec
+ .encrypt(string.as_bytes().into())
+ .map_err(|e| Error::EncryptionFailed(format!("{e} (encrypting {login_id})")))?;
+ let ciphertext = std::str::from_utf8(&cipherbytes).map_err(|e| {
+ Error::EncryptionFailed(format!("{e} (encrypting {login_id}: data not utf8)"))
+ })?;
+ Ok(ciphertext.to_owned())
+ }
+
+ pub fn decrypt(
+ ciphertext: &str,
+ encdec: &dyn EncryptorDecryptor,
+ login_id: &str,
+ ) -> Result<Self> {
+ let jsonbytes = encdec
+ .decrypt(ciphertext.as_bytes().into())
+ .map_err(|e| Error::DecryptionFailed(format!("{e} (decrypting {login_id})")))?;
+ let json =
+ std::str::from_utf8(&jsonbytes).map_err(|e| Error::DecryptionFailed(e.to_string()))?;
+ Ok(serde_json::from_str(json)?)
+ }
+}
+
+/// Login data specific to database records
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
+pub struct LoginMeta {
+ pub id: String,
+ pub time_created: i64,
+ pub time_password_changed: i64,
+ pub time_last_used: i64,
+ pub times_used: i64,
+}
+
+/// A login together with meta fields, handed over to the store API; ie a login persisted
+/// elsewhere, useful for migrations
+pub struct LoginEntryWithMeta {
+ pub entry: LoginEntry,
+ pub meta: LoginMeta,
+}
+
+/// A bulk insert result entry, returned by `add_many` and `add_many_with_records`
+pub enum BulkResultEntry {
+ Success { login: Login },
+ Error { message: String },
+}
+
+/// A login handed over to the store API; ie a login not yet persisted
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
+pub struct LoginEntry {
+ // login fields
+ pub origin: String,
+ pub form_action_origin: Option<String>,
+ pub http_realm: Option<String>,
+ pub username_field: String,
+ pub password_field: String,
+
+ // secure fields
+ pub username: String,
+ pub password: String,
+}
+
+impl LoginEntry {
+ pub fn new(fields: LoginFields, sec_fields: SecureLoginFields) -> Self {
+ Self {
+ origin: fields.origin,
+ form_action_origin: fields.form_action_origin,
+ http_realm: fields.http_realm,
+ username_field: fields.username_field,
+ password_field: fields.password_field,
+
+ username: sec_fields.username,
+ password: sec_fields.password,
+ }
+ }
+ /// Internal helper for validation and fixups of an "origin" stored as
+ /// a string.
+ fn validate_and_fixup_origin(origin: &str) -> Result<Option<String>> {
+ // Check we can parse the origin, then use the normalized version of it.
+ match Url::parse(origin) {
+ Ok(mut u) => {
+ // Presumably this is a faster path than always setting?
+ if u.path() != "/"
+ || u.fragment().is_some()
+ || u.query().is_some()
+ || u.username() != "/"
+ || u.password().is_some()
+ {
+ // Not identical - we only want the origin part, so kill
+ // any other parts which may exist.
+ // But first special case `file://` URLs which always
+ // resolve to `file://`
+ if u.scheme() == "file" {
+ return Ok(if origin == "file://" {
+ None
+ } else {
+ Some("file://".into())
+ });
+ }
+ u.set_path("");
+ u.set_fragment(None);
+ u.set_query(None);
+ let _ = u.set_username("");
+ let _ = u.set_password(None);
+ let mut href = String::from(u);
+ // We always store without the trailing "/" which Urls have.
+ if href.ends_with('/') {
+ href.pop().expect("url must have a length");
+ }
+ if origin != href {
+ // Needs to be fixed up.
+ return Ok(Some(href));
+ }
+ }
+ Ok(None)
+ }
+ Err(e) => {
+ breadcrumb!(
+ "Error parsing login origin: {e:?} ({})",
+ error_support::redact_url(origin)
+ );
+ // We can't fixup completely invalid records, so always throw.
+ Err(InvalidLogin::IllegalOrigin.into())
+ }
+ }
+ }
+}
+
+/// A login handed over from the store API, which has been persisted and contains persistence
+/// information such as id and time stamps
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
+pub struct Login {
+ // meta fields
+ pub id: String,
+ pub time_created: i64,
+ pub time_password_changed: i64,
+ pub time_last_used: i64,
+ pub times_used: i64,
+
+ // login fields
+ pub origin: String,
+ pub form_action_origin: Option<String>,
+ pub http_realm: Option<String>,
+ pub username_field: String,
+ pub password_field: String,
+
+ // secure fields
+ pub username: String,
+ pub password: String,
+}
+
+impl Login {
+ pub fn new(meta: LoginMeta, fields: LoginFields, sec_fields: SecureLoginFields) -> Self {
+ Self {
+ id: meta.id,
+ time_created: meta.time_created,
+ time_password_changed: meta.time_password_changed,
+ time_last_used: meta.time_last_used,
+ times_used: meta.times_used,
+
+ origin: fields.origin,
+ form_action_origin: fields.form_action_origin,
+ http_realm: fields.http_realm,
+ username_field: fields.username_field,
+ password_field: fields.password_field,
+
+ username: sec_fields.username,
+ password: sec_fields.password,
+ }
+ }
+
+ #[inline]
+ pub fn guid(&self) -> Guid {
+ Guid::from_string(self.id.clone())
+ }
+
+ pub fn entry(&self) -> LoginEntry {
+ LoginEntry {
+ origin: self.origin.clone(),
+ form_action_origin: self.form_action_origin.clone(),
+ http_realm: self.http_realm.clone(),
+ username_field: self.username_field.clone(),
+ password_field: self.password_field.clone(),
+
+ username: self.username.clone(),
+ password: self.password.clone(),
+ }
+ }
+
+ pub fn encrypt(self, encdec: &dyn EncryptorDecryptor) -> Result<EncryptedLogin> {
+ let sec_fields = SecureLoginFields {
+ username: self.username,
+ password: self.password,
+ }
+ .encrypt(encdec, &self.id)?;
+ Ok(EncryptedLogin {
+ meta: LoginMeta {
+ id: self.id,
+ time_created: self.time_created,
+ time_password_changed: self.time_password_changed,
+ time_last_used: self.time_last_used,
+ times_used: self.times_used,
+ },
+ fields: LoginFields {
+ origin: self.origin,
+ form_action_origin: self.form_action_origin,
+ http_realm: self.http_realm,
+ username_field: self.username_field,
+ password_field: self.password_field,
+ },
+ sec_fields,
+ })
+ }
+}
+
+/// A login stored in the database
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
+pub struct EncryptedLogin {
+ pub meta: LoginMeta,
+ pub fields: LoginFields,
+ pub sec_fields: String,
+}
+
+impl EncryptedLogin {
+ #[inline]
+ pub fn guid(&self) -> Guid {
+ Guid::from_string(self.meta.id.clone())
+ }
+
+ // TODO: Remove this: https://github.com/mozilla/application-services/issues/4185
+ #[inline]
+ pub fn guid_str(&self) -> &str {
+ &self.meta.id
+ }
+
+ pub fn decrypt(self, encdec: &dyn EncryptorDecryptor) -> Result<Login> {
+ let sec_fields = self.decrypt_fields(encdec)?;
+ Ok(Login::new(self.meta, self.fields, sec_fields))
+ }
+
+ pub fn decrypt_fields(&self, encdec: &dyn EncryptorDecryptor) -> Result<SecureLoginFields> {
+ SecureLoginFields::decrypt(&self.sec_fields, encdec, &self.meta.id)
+ }
+
+ pub(crate) fn from_row(row: &Row<'_>) -> Result<EncryptedLogin> {
+ let login = EncryptedLogin {
+ meta: LoginMeta {
+ id: row.get("guid")?,
+ time_created: row.get("timeCreated")?,
+ // Might be null
+ time_last_used: row
+ .get::<_, Option<i64>>("timeLastUsed")?
+ .unwrap_or_default(),
+
+ time_password_changed: row.get("timePasswordChanged")?,
+ times_used: row.get("timesUsed")?,
+ },
+ fields: LoginFields {
+ origin: row.get("origin")?,
+ http_realm: row.get("httpRealm")?,
+
+ form_action_origin: row.get("formActionOrigin")?,
+
+ username_field: string_or_default(row, "usernameField")?,
+ password_field: string_or_default(row, "passwordField")?,
+ },
+ sec_fields: row.get("secFields")?,
+ };
+ // XXX - we used to perform a fixup here, but that seems heavy-handed
+ // and difficult - we now only do that on add/insert when we have the
+ // encryption key.
+ Ok(login)
+ }
+}
+
+fn string_or_default(row: &Row<'_>, col: &str) -> Result<String> {
+ Ok(row.get::<_, Option<String>>(col)?.unwrap_or_default())
+}
+
+pub trait ValidateAndFixup {
+ // Our validate and fixup functions.
+ fn check_valid(&self) -> Result<()>
+ where
+ Self: Sized,
+ {
+ self.validate_and_fixup(false)?;
+ Ok(())
+ }
+
+ fn fixup(self) -> Result<Self>
+ where
+ Self: Sized,
+ {
+ match self.maybe_fixup()? {
+ None => Ok(self),
+ Some(login) => Ok(login),
+ }
+ }
+
+ fn maybe_fixup(&self) -> Result<Option<Self>>
+ where
+ Self: Sized,
+ {
+ self.validate_and_fixup(true)
+ }
+
+ // validates, and optionally fixes, a struct. If fixup is false and there is a validation
+ // issue, an `Err` is returned. If fixup is true and a problem was fixed, and `Ok(Some<Self>)`
+ // is returned with the fixed version. If there was no validation problem, `Ok(None)` is
+ // returned.
+ fn validate_and_fixup(&self, fixup: bool) -> Result<Option<Self>>
+ where
+ Self: Sized;
+}
+
+impl ValidateAndFixup for LoginEntry {
+ fn validate_and_fixup(&self, fixup: bool) -> Result<Option<Self>> {
+ // XXX TODO: we've definitely got more validation and fixups to add here!
+
+ let mut maybe_fixed = None;
+
+ /// A little helper to magic a Some(self.clone()) into existence when needed.
+ macro_rules! get_fixed_or_throw {
+ ($err:expr) => {
+ // This is a block expression returning a local variable,
+ // entirely so we can give it an explicit type declaration.
+ {
+ if !fixup {
+ return Err($err.into());
+ }
+ warn!("Fixing login record {:?}", $err);
+ let fixed: Result<&mut Self> =
+ Ok(maybe_fixed.get_or_insert_with(|| self.clone()));
+ fixed
+ }
+ };
+ }
+
+ if self.origin.is_empty() {
+ return Err(InvalidLogin::EmptyOrigin.into());
+ }
+
+ if self.form_action_origin.is_some() && self.http_realm.is_some() {
+ get_fixed_or_throw!(InvalidLogin::BothTargets)?.http_realm = None;
+ }
+
+ if self.form_action_origin.is_none() && self.http_realm.is_none() {
+ return Err(InvalidLogin::NoTarget.into());
+ }
+
+ let form_action_origin = self.form_action_origin.clone().unwrap_or_default();
+ let http_realm = maybe_fixed
+ .as_ref()
+ .unwrap_or(self)
+ .http_realm
+ .clone()
+ .unwrap_or_default();
+
+ let field_data = [
+ ("form_action_origin", &form_action_origin),
+ ("http_realm", &http_realm),
+ ("origin", &self.origin),
+ ("username_field", &self.username_field),
+ ("password_field", &self.password_field),
+ ];
+
+ for (field_name, field_value) in &field_data {
+ // Nuls are invalid.
+ if field_value.contains('\0') {
+ return Err(InvalidLogin::IllegalFieldValue {
+ field_info: format!("`{}` contains Nul", field_name),
+ }
+ .into());
+ }
+
+ // Newlines are invalid in Desktop for all the fields here.
+ if field_value.contains('\n') || field_value.contains('\r') {
+ return Err(InvalidLogin::IllegalFieldValue {
+ field_info: format!("`{}` contains newline", field_name),
+ }
+ .into());
+ }
+ }
+
+ // Desktop doesn't like fields with the below patterns
+ if self.username_field == "." {
+ return Err(InvalidLogin::IllegalFieldValue {
+ field_info: "`username_field` is a period".into(),
+ }
+ .into());
+ }
+
+ // Check we can parse the origin, then use the normalized version of it.
+ if let Some(fixed) = Self::validate_and_fixup_origin(&self.origin)? {
+ get_fixed_or_throw!(InvalidLogin::IllegalFieldValue {
+ field_info: "Origin is not normalized".into()
+ })?
+ .origin = fixed;
+ }
+
+ match &maybe_fixed.as_ref().unwrap_or(self).form_action_origin {
+ None => {
+ if !self.username_field.is_empty() {
+ get_fixed_or_throw!(InvalidLogin::IllegalFieldValue {
+ field_info: "username_field must be empty when form_action_origin is null"
+ .into()
+ })?
+ .username_field
+ .clear();
+ }
+ if !self.password_field.is_empty() {
+ get_fixed_or_throw!(InvalidLogin::IllegalFieldValue {
+ field_info: "password_field must be empty when form_action_origin is null"
+ .into()
+ })?
+ .password_field
+ .clear();
+ }
+ }
+ Some(href) => {
+ // "", ".", and "javascript:" are special cases documented at the top of this file.
+ if href == "." {
+ // A bit of a special case - if we are being asked to fixup, we replace
+ // "." with an empty string - but if not fixing up we don't complain.
+ if fixup {
+ maybe_fixed
+ .get_or_insert_with(|| self.clone())
+ .form_action_origin = Some("".into());
+ }
+ } else if !href.is_empty() && href != "javascript:" {
+ if let Some(fixed) = Self::validate_and_fixup_origin(href)? {
+ get_fixed_or_throw!(InvalidLogin::IllegalFieldValue {
+ field_info: "form_action_origin is not normalized".into()
+ })?
+ .form_action_origin = Some(fixed);
+ }
+ }
+ }
+ }
+
+ // secure fields
+ //
+ // \r\n chars are valid in desktop for some reason, so we allow them here too.
+ if self.username.contains('\0') {
+ return Err(InvalidLogin::IllegalFieldValue {
+ field_info: "`username` contains Nul".into(),
+ }
+ .into());
+ }
+ if self.password.is_empty() {
+ return Err(InvalidLogin::EmptyPassword.into());
+ }
+ if self.password.contains('\0') {
+ return Err(InvalidLogin::IllegalFieldValue {
+ field_info: "`password` contains Nul".into(),
+ }
+ .into());
+ }
+
+ Ok(maybe_fixed)
+ }
+}
+
+#[cfg(test)]
+pub mod test_utils {
+ use super::*;
+ use crate::encryption::test_utils::encrypt_struct;
+
+ // Factory function to make a new login
+ //
+ // It uses the guid to create a unique origin/form_action_origin
+ pub fn enc_login(id: &str, password: &str) -> EncryptedLogin {
+ let sec_fields = SecureLoginFields {
+ username: "user".to_string(),
+ password: password.to_string(),
+ };
+ EncryptedLogin {
+ meta: LoginMeta {
+ id: id.to_string(),
+ ..Default::default()
+ },
+ fields: LoginFields {
+ form_action_origin: Some(format!("https://{}.example.com", id)),
+ origin: format!("https://{}.example.com", id),
+ ..Default::default()
+ },
+ // TODO: fixme
+ sec_fields: encrypt_struct(&sec_fields),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_url_fixups() -> Result<()> {
+ // Start with URLs which are all valid and already normalized.
+ for input in &[
+ // The list of valid origins documented at the top of this file.
+ "https://site.com",
+ "http://site.com:1234",
+ "ftp://ftp.site.com",
+ "moz-proxy://127.0.0.1:8888",
+ "chrome://MyLegacyExtension",
+ "file://",
+ "https://[::1]",
+ ] {
+ assert_eq!(LoginEntry::validate_and_fixup_origin(input)?, None);
+ }
+
+ // And URLs which get normalized.
+ for (input, output) in &[
+ ("https://site.com/", "https://site.com"),
+ ("http://site.com:1234/", "http://site.com:1234"),
+ ("http://example.com/foo?query=wtf#bar", "http://example.com"),
+ ("http://example.com/foo#bar", "http://example.com"),
+ (
+ "http://username:password@example.com/",
+ "http://example.com",
+ ),
+ ("http://😍.com/", "http://xn--r28h.com"),
+ ("https://[0:0:0:0:0:0:0:1]", "https://[::1]"),
+ // All `file://` URLs normalize to exactly `file://`. See #2384 for
+ // why we might consider changing that later.
+ ("file:///", "file://"),
+ ("file://foo/bar", "file://"),
+ ("file://foo/bar/", "file://"),
+ ("moz-proxy://127.0.0.1:8888/", "moz-proxy://127.0.0.1:8888"),
+ (
+ "moz-proxy://127.0.0.1:8888/foo",
+ "moz-proxy://127.0.0.1:8888",
+ ),
+ ("chrome://MyLegacyExtension/", "chrome://MyLegacyExtension"),
+ (
+ "chrome://MyLegacyExtension/foo",
+ "chrome://MyLegacyExtension",
+ ),
+ ] {
+ assert_eq!(
+ LoginEntry::validate_and_fixup_origin(input)?,
+ Some((*output).into())
+ );
+ }
+ Ok(())
+ }
+
+ #[test]
+ fn test_check_valid() {
+ #[derive(Debug, Clone)]
+ struct TestCase {
+ login: LoginEntry,
+ should_err: bool,
+ expected_err: &'static str,
+ }
+
+ let valid_login = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_empty_origin = LoginEntry {
+ origin: "".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_empty_password = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "".into(),
+ ..Default::default()
+ };
+
+ let login_with_form_submit_and_http_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ form_action_origin: Some("https://www.example.com".into()),
+ username: "".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_without_form_submit_or_http_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ username: "".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_legacy_form_submit_and_http_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ form_action_origin: Some("".into()),
+ username: "".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_null_http_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.\0com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_null_username = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "\0".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_null_password = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "username".into(),
+ password: "test\0".into(),
+ ..Default::default()
+ };
+
+ let login_with_newline_origin = LoginEntry {
+ origin: "\rhttps://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_newline_username_field = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username_field: "\n".into(),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_newline_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("foo\nbar".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_newline_password = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test\n".into(),
+ ..Default::default()
+ };
+
+ let login_with_period_username_field = LoginEntry {
+ origin: "https://www.example.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username_field: ".".into(),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_period_form_action_origin = LoginEntry {
+ form_action_origin: Some(".".into()),
+ origin: "https://www.example.com".into(),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_javascript_form_action_origin = LoginEntry {
+ form_action_origin: Some("javascript:".into()),
+ origin: "https://www.example.com".into(),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_malformed_origin_parens = LoginEntry {
+ origin: " (".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_host_unicode = LoginEntry {
+ origin: "http://💖.com".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_origin_trailing_slash = LoginEntry {
+ origin: "https://www.example.com/".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_origin_expanded_ipv6 = LoginEntry {
+ origin: "https://[0:0:0:0:0:0:1:1]".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_unknown_protocol = LoginEntry {
+ origin: "moz-proxy://127.0.0.1:8888".into(),
+ http_realm: Some("https://www.example.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let test_cases = [
+ TestCase {
+ login: valid_login,
+ should_err: false,
+ expected_err: "",
+ },
+ TestCase {
+ login: login_with_empty_origin,
+ should_err: true,
+ expected_err: "Invalid login: Origin is empty",
+ },
+ TestCase {
+ login: login_with_empty_password,
+ should_err: true,
+ expected_err: "Invalid login: Password is empty",
+ },
+ TestCase {
+ login: login_with_form_submit_and_http_realm,
+ should_err: true,
+ expected_err: "Invalid login: Both `formActionOrigin` and `httpRealm` are present",
+ },
+ TestCase {
+ login: login_without_form_submit_or_http_realm,
+ should_err: true,
+ expected_err:
+ "Invalid login: Neither `formActionOrigin` or `httpRealm` are present",
+ },
+ TestCase {
+ login: login_with_null_http_realm,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: `http_realm` contains Nul",
+ },
+ TestCase {
+ login: login_with_null_username,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: `username` contains Nul",
+ },
+ TestCase {
+ login: login_with_null_password,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: `password` contains Nul",
+ },
+ TestCase {
+ login: login_with_newline_origin,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: `origin` contains newline",
+ },
+ TestCase {
+ login: login_with_newline_realm,
+ should_err: true,
+ expected_err:
+ "Invalid login: Login has illegal field: `http_realm` contains newline",
+ },
+ TestCase {
+ login: login_with_newline_username_field,
+ should_err: true,
+ expected_err:
+ "Invalid login: Login has illegal field: `username_field` contains newline",
+ },
+ TestCase {
+ login: login_with_newline_password,
+ should_err: false,
+ expected_err: "",
+ },
+ TestCase {
+ login: login_with_period_username_field,
+ should_err: true,
+ expected_err:
+ "Invalid login: Login has illegal field: `username_field` is a period",
+ },
+ TestCase {
+ login: login_with_period_form_action_origin,
+ should_err: false,
+ expected_err: "",
+ },
+ TestCase {
+ login: login_with_javascript_form_action_origin,
+ should_err: false,
+ expected_err: "",
+ },
+ TestCase {
+ login: login_with_malformed_origin_parens,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal origin",
+ },
+ TestCase {
+ login: login_with_host_unicode,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: Origin is not normalized",
+ },
+ TestCase {
+ login: login_with_origin_trailing_slash,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: Origin is not normalized",
+ },
+ TestCase {
+ login: login_with_origin_expanded_ipv6,
+ should_err: true,
+ expected_err: "Invalid login: Login has illegal field: Origin is not normalized",
+ },
+ TestCase {
+ login: login_with_unknown_protocol,
+ should_err: false,
+ expected_err: "",
+ },
+ TestCase {
+ login: login_with_legacy_form_submit_and_http_realm,
+ should_err: false,
+ expected_err: "",
+ },
+ ];
+
+ for tc in &test_cases {
+ let actual = tc.login.check_valid();
+
+ if tc.should_err {
+ assert!(actual.is_err(), "{:#?}", tc);
+ assert_eq!(
+ tc.expected_err,
+ actual.unwrap_err().to_string(),
+ "{:#?}",
+ tc,
+ );
+ } else {
+ assert!(actual.is_ok(), "{:#?}", tc);
+ assert!(
+ tc.login.clone().fixup().is_ok(),
+ "Fixup failed after check_valid passed: {:#?}",
+ &tc,
+ );
+ }
+ }
+ }
+
+ #[test]
+ fn test_fixup() {
+ #[derive(Debug, Default)]
+ struct TestCase {
+ login: LoginEntry,
+ fixedup_host: Option<&'static str>,
+ fixedup_form_action_origin: Option<String>,
+ }
+
+ // Note that most URL fixups are tested above, but we have one or 2 here.
+ let login_with_full_url = LoginEntry {
+ origin: "http://example.com/foo?query=wtf#bar".into(),
+ form_action_origin: Some("http://example.com/foo?query=wtf#bar".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_host_unicode = LoginEntry {
+ origin: "http://😍.com".into(),
+ form_action_origin: Some("http://😍.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_period_fsu = LoginEntry {
+ origin: "https://example.com".into(),
+ form_action_origin: Some(".".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+ let login_with_empty_fsu = LoginEntry {
+ origin: "https://example.com".into(),
+ form_action_origin: Some("".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let login_with_form_submit_and_http_realm = LoginEntry {
+ origin: "https://www.example.com".into(),
+ form_action_origin: Some("https://www.example.com".into()),
+ // If both http_realm and form_action_origin are specified, we drop
+ // the former when fixing up. So for this test we must have an
+ // invalid value in http_realm to ensure we don't validate a value
+ // we end up dropping.
+ http_realm: Some("\n".into()),
+ username: "".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+
+ let test_cases = [
+ TestCase {
+ login: login_with_full_url,
+ fixedup_host: "http://example.com".into(),
+ fixedup_form_action_origin: Some("http://example.com".into()),
+ },
+ TestCase {
+ login: login_with_host_unicode,
+ fixedup_host: "http://xn--r28h.com".into(),
+ fixedup_form_action_origin: Some("http://xn--r28h.com".into()),
+ },
+ TestCase {
+ login: login_with_period_fsu,
+ fixedup_form_action_origin: Some("".into()),
+ ..TestCase::default()
+ },
+ TestCase {
+ login: login_with_form_submit_and_http_realm,
+ fixedup_form_action_origin: Some("https://www.example.com".into()),
+ ..TestCase::default()
+ },
+ TestCase {
+ login: login_with_empty_fsu,
+ // Should still be empty.
+ fixedup_form_action_origin: Some("".into()),
+ ..TestCase::default()
+ },
+ ];
+
+ for tc in &test_cases {
+ let login = tc.login.clone().fixup().expect("should work");
+ if let Some(expected) = tc.fixedup_host {
+ assert_eq!(login.origin, expected, "origin not fixed in {:#?}", tc);
+ }
+ assert_eq!(
+ login.form_action_origin, tc.fixedup_form_action_origin,
+ "form_action_origin not fixed in {:#?}",
+ tc,
+ );
+ login.check_valid().unwrap_or_else(|e| {
+ panic!("Fixup produces invalid record: {:#?}", (e, &tc, &login));
+ });
+ assert_eq!(
+ login.clone().fixup().unwrap(),
+ login,
+ "fixup did not reach fixed point for testcase: {:#?}",
+ tc,
+ );
+ }
+ }
+
+ #[test]
+ fn test_secure_fields_serde() {
+ let sf = SecureLoginFields {
+ username: "foo".into(),
+ password: "pwd".into(),
+ };
+ assert_eq!(
+ serde_json::to_string(&sf).unwrap(),
+ r#"{"u":"foo","p":"pwd"}"#
+ );
+ let got: SecureLoginFields = serde_json::from_str(r#"{"u": "user", "p": "p"}"#).unwrap();
+ let expected = SecureLoginFields {
+ username: "user".into(),
+ password: "p".into(),
+ };
+ assert_eq!(got, expected);
+ }
+}
diff --git a/third_party/rust/logins/src/logins.udl b/third_party/rust/logins/src/logins.udl
@@ -0,0 +1,276 @@
+/* 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/. */
+
+namespace logins {
+ /// We expose the crypto primitives on the namespace
+
+ /// Create a new, random, encryption key.
+ [Throws=LoginsApiError]
+ string create_key();
+
+ /// Create a "canary" string, which can be used to test if the encryption
+ //key is still valid for the logins data
+ [Throws=LoginsApiError]
+ string create_canary([ByRef]string text, [ByRef]string encryption_key);
+
+ /// Check that key is still valid using the output of `create_canary`.
+ //`text` much match the text you initially passed to `create_canary()`
+ [Throws=LoginsApiError]
+ boolean check_canary([ByRef]string canary, [ByRef]string text, [ByRef]string encryption_key);
+
+ /// Utility function to create a StaticKeyManager to be used for the time
+ /// being until support lands for [trait implementation of an UniFFI
+ /// interface](https://mozilla.github.io/uniffi-rs/next/proc_macro/index.html#structs-implementing-traits)
+ /// in UniFFI.
+ KeyManager create_static_key_manager(string key);
+
+ /// Similar to create_static_key_manager above, create a
+ /// ManagedEncryptorDecryptor by passing in a KeyManager
+ EncryptorDecryptor create_managed_encdec(KeyManager key_manager);
+
+ /// Create a LoginStore with StaticKeyManager by passing in a db path and a
+ /// static key
+ LoginStore create_login_store_with_static_key_manager(string path, string key);
+};
+
+/// A login entry from the user, not linked to any database record.
+/// The add/update APIs input these.
+dictionary LoginEntry {
+ // login fields
+ string origin;
+ string? http_realm;
+ string? form_action_origin;
+ string username_field;
+ string password_field;
+
+ // secure login fields
+ string password;
+ string username;
+};
+
+/// Login data specific to database records.
+/// The add_with_record API inputs this.
+dictionary LoginMeta {
+ string id;
+ i64 times_used;
+ i64 time_created;
+ i64 time_last_used;
+ i64 time_password_changed;
+};
+
+/// A login together with record fields, handed over to the store API; ie a login persisted
+/// elsewhere, useful for migrations
+dictionary LoginEntryWithMeta {
+ LoginEntry entry;
+ LoginMeta meta;
+};
+
+/// A bulk insert result entry, returned by `add_many` and `add_many_with_meta`
+[Enum]
+interface BulkResultEntry {
+ Success(Login login);
+ Error(string message);
+};
+
+/// A login stored in the database
+dictionary Login {
+ // meta fields
+ string id;
+ i64 times_used;
+ i64 time_created;
+ i64 time_last_used;
+ i64 time_password_changed;
+
+ // login fields
+ string origin;
+ string? http_realm;
+ string? form_action_origin;
+ string username_field;
+ string password_field;
+
+ // secure login fields
+ string password;
+ string username;
+};
+
+/// Metrics tracking deletion of logins that cannot be decrypted, see `delete_undecryptable_records_for_remote_replacement`
+/// for more details
+dictionary LoginsDeletionMetrics {
+ u64 local_deleted;
+ u64 mirror_deleted;
+};
+
+/// These are the errors returned by our public API.
+[Error]
+interface LoginsApiError {
+ /// NSS not initialized.
+ NSSUninitialized();
+
+ /// NSS error during authentication
+ NSSAuthenticationError(string reason);
+
+ /// error during authentication (in PrimaryPasswordAuthenticator)
+ AuthenticationError(string reason);
+
+ /// authentication has been cancelled.
+ AuthenticationCanceled();
+
+ /// The login data supplied is invalid. The reason will indicate what's wrong with it.
+ InvalidRecord(string reason);
+
+ /// Asking to do something with a guid which doesn't exist.
+ NoSuchRecord(string reason);
+
+ /// Encryption key is missing.
+ MissingKey();
+
+ /// Encryption key is not valid.
+ InvalidKey();
+
+ /// encryption failed
+ EncryptionFailed(string reason);
+
+ /// decryption failed
+ DecryptionFailed(string reason);
+
+ /// An operation was interrupted at the request of the consuming app.
+ Interrupted(string reason);
+
+ /// Sync reported that authentication failed and the user should re-enter their FxA password.
+ // TODO: remove this at the same time as remove the sync() method in favour of the SyncManager.
+ SyncAuthInvalid(string reason);
+
+ /// something internal went wrong which doesn't have a public error value
+ /// because the consuming app can not reasonably take any action to resolve it.
+ /// The underlying error will have been logged and reported.
+ /// (ideally would just be `Unexpected`, but that would be a breaking change)
+ UnexpectedLoginsApiError(string reason);
+};
+
+[Trait, WithForeign]
+interface EncryptorDecryptor {
+ [Throws=LoginsApiError]
+ bytes encrypt(bytes cleartext);
+
+ [Throws=LoginsApiError]
+ bytes decrypt(bytes ciphertext);
+};
+
+[Trait, WithForeign]
+interface KeyManager {
+ [Throws=LoginsApiError]
+ bytes get_key();
+};
+
+interface StaticKeyManager {
+ constructor(string key);
+};
+
+interface ManagedEncryptorDecryptor {
+ constructor(KeyManager key_manager);
+};
+
+interface LoginStore {
+ [Throws=LoginsApiError]
+ constructor(string path, EncryptorDecryptor encdec);
+
+ [Throws=LoginsApiError]
+ Login add(LoginEntry login);
+
+ [Throws=LoginsApiError]
+ sequence<BulkResultEntry> add_many(sequence<LoginEntry> logins);
+
+ [Throws=LoginsApiError]
+ Login add_with_meta(LoginEntryWithMeta entry_with_meta);
+
+ [Throws=LoginsApiError]
+ sequence<BulkResultEntry> add_many_with_meta(sequence<LoginEntryWithMeta> entries_with_meta);
+
+ [Throws=LoginsApiError]
+ Login update([ByRef] string id, LoginEntry login);
+
+ [Throws=LoginsApiError]
+ Login add_or_update(LoginEntry login);
+
+ [Throws=LoginsApiError]
+ boolean delete([ByRef] string id);
+
+ [Throws=LoginsApiError, Self=ByArc]
+ sequence<boolean> delete_many(sequence<string> ids);
+
+ /// Clear out locally stored logins data
+ ///
+ /// If sync is enabled, then we will try to recover the data on the next sync.
+ ///
+ /// The main reason to call this is when regenerating a new encryption key.
+ /// In that case, there's no reason to keep around the local data since it can't be decrypted.
+ /// Calling `wipe_local` is better than keeping around these un-decryptable logins, since we
+ /// might be able to recover the data via sync.
+ ///
+ /// This is a no-op for freshly created databases, so it's safe to call this whenever a key is
+ /// generated.
+ [Throws=LoginsApiError]
+ void wipe_local();
+
+ [Throws=LoginsApiError, Self=ByArc]
+ void reset();
+
+ /// The `delete_undecryptable_records_for_remote_replacement` function locally deletes stored logins
+ /// that cannot be decrypted and sets the last sync time to 0 so any existing server records can be downloaded
+ /// and overwrite the locally deleted records.
+ ///
+ /// NB: This function was created to unblock iOS logins users who are unable to sync logins and should not be used
+ /// outside of this use case.
+ [Throws=LoginsApiError, Self=ByArc]
+ LoginsDeletionMetrics delete_undecryptable_records_for_remote_replacement();
+
+ [Throws=LoginsApiError]
+ void touch([ByRef] string id);
+
+ [Throws=LoginsApiError]
+ boolean is_empty();
+
+ [Throws=LoginsApiError]
+ i64 count();
+
+ [Throws=LoginsApiError]
+ i64 count_by_origin([ByRef] string origin);
+
+ [Throws=LoginsApiError]
+ i64 count_by_form_action_origin([ByRef] string form_action_origin);
+
+ [Throws=LoginsApiError]
+ sequence<Login> list();
+
+ [Throws=LoginsApiError]
+ sequence<Login> get_by_base_domain([ByRef] string base_domain);
+
+ [Throws=LoginsApiError]
+ boolean has_logins_by_base_domain([ByRef] string base_domain);
+
+ [Throws=LoginsApiError]
+ Login? find_login_to_update(LoginEntry look);
+
+ [Throws=LoginsApiError]
+ Login? get([ByRef] string id);
+
+ [Throws=LoginsApiError]
+ void set_checkpoint([ByRef] string checkpoint);
+
+ [Throws=LoginsApiError]
+ string? get_checkpoint();
+
+ /// Run maintenance on the DB
+ ///
+ /// This is intended to be run during idle time and will take steps / to clean up / shrink the
+ /// database.
+ [Throws=LoginsApiError]
+ void run_maintenance();
+
+ [Self=ByArc]
+ void register_with_sync_manager();
+
+ [Self=ByArc]
+ void shutdown();
+};
diff --git a/third_party/rust/logins/src/schema.rs b/third_party/rust/logins/src/schema.rs
@@ -0,0 +1,320 @@
+/* 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/. */
+
+//! Logins Schema v4
+//! ================
+//!
+//! The schema we use is a evolution of the firefox-ios logins database format.
+//! There are three tables:
+//!
+//! - `loginsL`: The local table.
+//! - `loginsM`: The mirror table.
+//! - `loginsSyncMeta`: The table used to to store various sync metadata.
+//!
+//! ## `loginsL`
+//!
+//! This stores local login information, also known as the "overlay".
+//!
+//! `loginsL` is essentially unchanged from firefox-ios, however note the
+//! semantic change v4 makes to timestamp fields (which is explained in more
+//! detail in the [COMMON_COLS] documentation).
+//!
+//! It is important to note that `loginsL` is not guaranteed to be present for
+//! all records. Synced records may only exist in `loginsM` (although this is
+//! not guaranteed). In either case, queries should read from both `loginsL` and
+//! `loginsM`.
+//!
+//! ### `loginsL` Columns
+//!
+//! Contains all fields in [COMMON_COLS], as well as the following additional
+//! columns:
+//!
+//! - `local_modified`: A millisecond local timestamp indicating when the record
+//! was changed locally, or NULL if the record has never been changed locally.
+//!
+//! - `is_deleted`: A boolean indicating whether or not this record is a
+//! tombstone.
+//!
+//! - `sync_status`: A `SyncStatus` enum value, one of
+//!
+//! - `0` (`SyncStatus::Synced`): Indicating that the record has been synced
+//!
+//! - `1` (`SyncStatus::Changed`): Indicating that the record should be
+//! has changed locally and is known to exist on the server.
+//!
+//! - `2` (`SyncStatus::New`): Indicating that the record has never been
+//! synced, or we have been reset since the last time it synced.
+//!
+//! ## `loginsM`
+//!
+//! This stores server-side login information, also known as the "mirror".
+//!
+//! Like `loginsL`, `loginM` has not changed from firefox-ios, beyond the
+//! change to store timestamps as milliseconds explained in [COMMON_COLS].
+//!
+//! Also like `loginsL`, `loginsM` is not guaranteed to have rows for all
+//! records. It should not have rows for records which were not synced!
+//!
+//! It is important to note that `loginsL` is not guaranteed to be present for
+//! all records. Synced records may only exist in `loginsM`! Queries should
+//! test against both!
+//!
+//! ### `loginsM` Columns
+//!
+//! Contains all fields in [COMMON_COLS], as well as the following additional
+//! columns:
+//!
+//! - `server_modified`: the most recent server-modification timestamp
+//! ([sync15::ServerTimestamp]) we've seen for this record. Stored as
+//! a millisecond value.
+//!
+//! - `is_overridden`: A boolean indicating whether or not the mirror contents
+//! are invalid, and that we should defer to the data stored in `loginsL`.
+//!
+//! ## `loginsSyncMeta`
+//!
+//! This is a simple key-value table based on the `moz_meta` table in places.
+//! This table was added (by this rust crate) in version 4, and so is not
+//! present in firefox-ios.
+//!
+//! Currently it is used to store two items:
+//!
+//! 1. The last sync timestamp is stored under [LAST_SYNC_META_KEY], a
+//! `sync15::ServerTimestamp` stored in integer milliseconds.
+//!
+//! 2. The persisted sync state machine information is stored under
+//! [GLOBAL_STATE_META_KEY]. This is a `sync15::GlobalState` stored as
+//! JSON.
+//!
+
+use crate::error::*;
+use lazy_static::lazy_static;
+use rusqlite::Connection;
+use sql_support::ConnExt;
+
+/// Version 1: SQLCipher -> plaintext migration.
+/// Version 2: addition of `loginsM.enc_unknown_fields`.
+pub(super) const VERSION: i64 = 2;
+
+/// Every column shared by both tables except for `id`
+///
+/// Note: `timeCreated`, `timeLastUsed`, and `timePasswordChanged` are in
+/// milliseconds. This is in line with how the server and Desktop handle it, but
+/// counter to how firefox-ios handles it (hence needing to fix them up
+/// firefox-ios on schema upgrade from 3, the last firefox-ios password schema
+/// version).
+///
+/// The reason for breaking from how firefox-ios does things is just because it
+/// complicates the code to have multiple kinds of timestamps, for very little
+/// benefit. It also makes it unclear what's stored on the server, leading to
+/// further confusion.
+///
+/// However, note that the `local_modified` (of `loginsL`) and `server_modified`
+/// (of `loginsM`) are stored as milliseconds as well both on firefox-ios and
+/// here (and so they do not need to be updated with the `timeLastUsed`/
+/// `timePasswordChanged`/`timeCreated` timestamps.
+pub const COMMON_COLS: &str = "
+ guid,
+ secFields,
+ origin,
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ timeCreated,
+ timeLastUsed,
+ timePasswordChanged,
+ timesUsed
+";
+
+const COMMON_SQL: &str = "
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ origin TEXT NOT NULL,
+ -- Exactly one of httpRealm or formActionOrigin should be set
+ httpRealm TEXT,
+ formActionOrigin TEXT,
+ usernameField TEXT,
+ passwordField TEXT,
+ timesUsed INTEGER NOT NULL DEFAULT 0,
+ timeCreated INTEGER NOT NULL,
+ timeLastUsed INTEGER,
+ timePasswordChanged INTEGER NOT NULL,
+ secFields TEXT,
+ guid TEXT NOT NULL UNIQUE
+";
+
+lazy_static! {
+ static ref CREATE_LOCAL_TABLE_SQL: String = format!(
+ "CREATE TABLE IF NOT EXISTS loginsL (
+ {common_sql},
+ -- Milliseconds, or NULL if never modified locally.
+ local_modified INTEGER,
+
+ is_deleted TINYINT NOT NULL DEFAULT 0,
+ sync_status TINYINT NOT NULL DEFAULT 0
+ )",
+ common_sql = COMMON_SQL
+ );
+ static ref CREATE_MIRROR_TABLE_SQL: String = format!(
+ "CREATE TABLE IF NOT EXISTS loginsM (
+ {common_sql},
+ -- Milliseconds (a sync15::ServerTimestamp multiplied by
+ -- 1000 and truncated)
+ server_modified INTEGER NOT NULL,
+ is_overridden TINYINT NOT NULL DEFAULT 0,
+ -- fields on incoming records we don't know about and roundtrip.
+ -- a serde_json::Value::Object as an encrypted string.
+ enc_unknown_fields TEXT
+ )",
+ common_sql = COMMON_SQL
+ );
+ static ref SET_VERSION_SQL: String =
+ format!("PRAGMA user_version = {version}", version = VERSION);
+}
+
+const CREATE_META_TABLE_SQL: &str = "
+ CREATE TABLE IF NOT EXISTS loginsSyncMeta (
+ key TEXT PRIMARY KEY,
+ value NOT NULL
+ )
+";
+
+const CREATE_OVERRIDE_ORIGIN_INDEX_SQL: &str = "
+ CREATE INDEX IF NOT EXISTS idx_loginsM_is_overridden_origin
+ ON loginsM (is_overridden, origin)
+";
+
+const CREATE_DELETED_ORIGIN_INDEX_SQL: &str = "
+ CREATE INDEX IF NOT EXISTS idx_loginsL_is_deleted_origin
+ ON loginsL (is_deleted, origin)
+";
+
+pub(crate) static LAST_SYNC_META_KEY: &str = "last_sync_time";
+pub(crate) static GLOBAL_STATE_META_KEY: &str = "global_state_v2";
+pub(crate) static GLOBAL_SYNCID_META_KEY: &str = "global_sync_id";
+pub(crate) static COLLECTION_SYNCID_META_KEY: &str = "passwords_sync_id";
+pub(crate) static CHECKPOINT_KEY: &str = "checkpoint";
+
+pub(crate) fn init(db: &Connection) -> Result<()> {
+ let user_version = db.conn_ext_query_one::<i64>("PRAGMA user_version")?;
+ warn!("user_version: {}", user_version);
+ if user_version == 0 {
+ return create(db);
+ }
+ if user_version != VERSION {
+ if user_version < VERSION {
+ upgrade(db, user_version)?;
+ } else {
+ warn!(
+ "Loaded future schema version {} (we only understand version {}). \
+ Optimistically ",
+ user_version, VERSION
+ )
+ }
+ }
+ Ok(())
+}
+
+// Allow the redundant Ok() here. It will make more sense once we have an actual upgrade function.
+#[allow(clippy::unnecessary_wraps)]
+fn upgrade(db: &Connection, from: i64) -> Result<()> {
+ debug!("Upgrading schema from {} to {}", from, VERSION);
+ if from == VERSION {
+ return Ok(());
+ }
+ assert_ne!(
+ from, 0,
+ "Upgrading from user_version = 0 should already be handled (in `init`)"
+ );
+
+ // Schema upgrades.
+ if from == 1 {
+ // Just one new nullable column makes this fairly easy
+ db.execute_batch("ALTER TABLE loginsM ADD enc_unknown_fields TEXT;")?;
+ }
+ // XXX - next migration, be sure to:
+ // from = 2;
+ // if from == 2 ...
+ db.execute_batch(&SET_VERSION_SQL)?;
+ Ok(())
+}
+
+pub(crate) fn create(db: &Connection) -> Result<()> {
+ debug!("Creating schema");
+ db.execute_all(&[
+ &*CREATE_LOCAL_TABLE_SQL,
+ &*CREATE_MIRROR_TABLE_SQL,
+ CREATE_OVERRIDE_ORIGIN_INDEX_SQL,
+ CREATE_DELETED_ORIGIN_INDEX_SQL,
+ CREATE_META_TABLE_SQL,
+ &*SET_VERSION_SQL,
+ ])?;
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use crate::LoginDb;
+ use nss::ensure_initialized;
+ use rusqlite::Connection;
+
+ #[test]
+ fn test_create_schema() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ // should be VERSION.
+ let version = db.conn_ext_query_one::<i64>("PRAGMA user_version").unwrap();
+ assert_eq!(version, VERSION);
+ }
+
+ #[test]
+ fn test_upgrade_v1() {
+ ensure_initialized();
+ // manually setup a V1 schema.
+ let connection = Connection::open_in_memory().unwrap();
+ connection
+ .execute_batch(
+ "
+ CREATE TABLE IF NOT EXISTS loginsM (
+ -- this was common_sql as at v1
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ origin TEXT NOT NULL,
+ httpRealm TEXT,
+ formActionOrigin TEXT,
+ usernameField TEXT,
+ passwordField TEXT,
+ timesUsed INTEGER NOT NULL DEFAULT 0,
+ timeCreated INTEGER NOT NULL,
+ timeLastUsed INTEGER,
+ timePasswordChanged INTEGER NOT NULL,
+ secFields TEXT,
+ guid TEXT NOT NULL UNIQUE,
+ server_modified INTEGER NOT NULL,
+ is_overridden TINYINT NOT NULL DEFAULT 0
+ -- note enc_unknown_fields missing
+ );
+ ",
+ )
+ .unwrap();
+ // Call `create` to create the rest of the schema - the "if not exists" means loginsM
+ // will remain as v1.
+ create(&connection).unwrap();
+ // but that set the version to VERSION - set it back to 1 so our upgrade code runs.
+ connection
+ .execute_batch("PRAGMA user_version = 1;")
+ .unwrap();
+
+ // Now open the DB - it will create loginsL for us and migrate loginsM.
+ let db = LoginDb::with_connection(connection, TEST_ENCDEC.clone()).unwrap();
+ // all migrations should have succeeded.
+ let version = db.conn_ext_query_one::<i64>("PRAGMA user_version").unwrap();
+ assert_eq!(version, VERSION);
+
+ // and ensure sql selecting the new column works.
+ db.execute_batch("SELECT enc_unknown_fields FROM loginsM")
+ .unwrap();
+ }
+}
diff --git a/third_party/rust/logins/src/store.rs b/third_party/rust/logins/src/store.rs
@@ -0,0 +1,548 @@
+/* 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 crate::db::{LoginDb, LoginsDeletionMetrics};
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::login::{BulkResultEntry, EncryptedLogin, Login, LoginEntry, LoginEntryWithMeta};
+use crate::schema;
+use crate::LoginsSyncEngine;
+use parking_lot::Mutex;
+use sql_support::run_maintenance;
+use std::path::Path;
+use std::sync::{Arc, Weak};
+use sync15::{
+ engine::{EngineSyncAssociation, SyncEngine, SyncEngineId},
+ ServerTimestamp,
+};
+
+#[derive(uniffi::Enum)]
+pub enum LoginOrErrorMessage {
+ Login,
+ String,
+}
+
+// Our "sync manager" will use whatever is stashed here.
+lazy_static::lazy_static! {
+ // Mutex: just taken long enough to update the inner stuff - needed
+ // to wrap the RefCell as they aren't `Sync`
+ static ref STORE_FOR_MANAGER: Mutex<Weak<LoginStore>> = Mutex::new(Weak::new());
+}
+
+/// Called by the sync manager to get a sync engine via the store previously
+/// registered with the sync manager.
+pub fn get_registered_sync_engine(engine_id: &SyncEngineId) -> Option<Box<dyn SyncEngine>> {
+ let weak = STORE_FOR_MANAGER.lock();
+ match weak.upgrade() {
+ None => None,
+ Some(store) => match create_sync_engine(store, engine_id) {
+ Ok(engine) => Some(engine),
+ Err(e) => {
+ report_error!("logins-sync-engine-create-error", "{e}");
+ None
+ }
+ },
+ }
+}
+
+fn create_sync_engine(
+ store: Arc<LoginStore>,
+ engine_id: &SyncEngineId,
+) -> Result<Box<dyn SyncEngine>> {
+ match engine_id {
+ SyncEngineId::Passwords => Ok(Box::new(LoginsSyncEngine::new(Arc::clone(&store))?)),
+ // panicking here seems reasonable - it's a static error if this
+ // it hit, not something that runtime conditions can influence.
+ _ => unreachable!("can't provide unknown engine: {}", engine_id),
+ }
+}
+
+fn map_bulk_result_entry(
+ enc_login: Result<EncryptedLogin>,
+ encdec: &dyn EncryptorDecryptor,
+) -> BulkResultEntry {
+ match enc_login {
+ Ok(enc_login) => match enc_login.decrypt(encdec) {
+ Ok(login) => BulkResultEntry::Success { login },
+ Err(error) => {
+ warn!("Login could not be decrypted. This indicates a fundamental problem with the encryption key.");
+ BulkResultEntry::Error {
+ message: error.to_string(),
+ }
+ }
+ },
+ Err(error) => BulkResultEntry::Error {
+ message: error.to_string(),
+ },
+ }
+}
+
+pub struct LoginStore {
+ pub db: Mutex<Option<LoginDb>>,
+}
+
+impl LoginStore {
+ #[handle_error(Error)]
+ pub fn new(path: impl AsRef<Path>, encdec: Arc<dyn EncryptorDecryptor>) -> ApiResult<Self> {
+ let db = Mutex::new(Some(LoginDb::open(path, encdec)?));
+ Ok(Self { db })
+ }
+
+ pub fn new_from_db(db: LoginDb) -> Self {
+ let db = Mutex::new(Some(db));
+ Self { db }
+ }
+
+ // Only used for tests, but it's `pub` the `sync-test` crate uses it.
+ #[cfg(test)]
+ pub fn new_in_memory() -> Self {
+ let db = Mutex::new(Some(LoginDb::open_in_memory()));
+ Self { db }
+ }
+
+ pub fn lock_db(&self) -> Result<parking_lot::MappedMutexGuard<'_, LoginDb>> {
+ parking_lot::MutexGuard::try_map(self.db.lock(), |db| db.as_mut())
+ .map_err(|_| Error::DatabaseClosed)
+ }
+
+ #[handle_error(Error)]
+ pub fn is_empty(&self) -> ApiResult<bool> {
+ Ok(self.lock_db()?.count_all()? == 0)
+ }
+
+ #[handle_error(Error)]
+ pub fn list(&self) -> ApiResult<Vec<Login>> {
+ let db = self.lock_db()?;
+ db.get_all().and_then(|logins| {
+ logins
+ .into_iter()
+ .map(|login| login.decrypt(db.encdec.as_ref()))
+ .collect()
+ })
+ }
+
+ #[handle_error(Error)]
+ pub fn count(&self) -> ApiResult<i64> {
+ self.lock_db()?.count_all()
+ }
+
+ #[handle_error(Error)]
+ pub fn count_by_origin(&self, origin: &str) -> ApiResult<i64> {
+ self.lock_db()?.count_by_origin(origin)
+ }
+
+ #[handle_error(Error)]
+ pub fn count_by_form_action_origin(&self, form_action_origin: &str) -> ApiResult<i64> {
+ self.lock_db()?
+ .count_by_form_action_origin(form_action_origin)
+ }
+
+ #[handle_error(Error)]
+ pub fn get(&self, id: &str) -> ApiResult<Option<Login>> {
+ let db = self.lock_db()?;
+ match db.get_by_id(id) {
+ Ok(result) => match result {
+ Some(enc_login) => enc_login.decrypt(db.encdec.as_ref()).map(Some),
+ None => Ok(None),
+ },
+ Err(err) => Err(err),
+ }
+ }
+
+ #[handle_error(Error)]
+ pub fn get_by_base_domain(&self, base_domain: &str) -> ApiResult<Vec<Login>> {
+ let db = self.lock_db()?;
+ db.get_by_base_domain(base_domain).and_then(|logins| {
+ logins
+ .into_iter()
+ .map(|login| login.decrypt(db.encdec.as_ref()))
+ .collect()
+ })
+ }
+
+ #[handle_error(Error)]
+ pub fn has_logins_by_base_domain(&self, base_domain: &str) -> ApiResult<bool> {
+ self.lock_db()?
+ .get_by_base_domain(base_domain)
+ .map(|logins| !logins.is_empty())
+ }
+
+ #[handle_error(Error)]
+ pub fn find_login_to_update(&self, entry: LoginEntry) -> ApiResult<Option<Login>> {
+ let db = self.lock_db()?;
+ db.find_login_to_update(entry, db.encdec.as_ref())
+ }
+
+ #[handle_error(Error)]
+ pub fn touch(&self, id: &str) -> ApiResult<()> {
+ self.lock_db()?.touch(id)
+ }
+
+ #[handle_error(Error)]
+ pub fn delete(&self, id: &str) -> ApiResult<bool> {
+ self.lock_db()?.delete(id)
+ }
+
+ #[handle_error(Error)]
+ pub fn delete_many(&self, ids: Vec<String>) -> ApiResult<Vec<bool>> {
+ // Note we need to receive a vector of String here because `Vec<&str>` is not supported
+ // with UDL.
+ let ids: Vec<&str> = ids.iter().map(|id| &**id).collect();
+ self.lock_db()?.delete_many(ids)
+ }
+
+ #[handle_error(Error)]
+ pub fn delete_undecryptable_records_for_remote_replacement(
+ self: Arc<Self>,
+ ) -> ApiResult<LoginsDeletionMetrics> {
+ // This function was created for the iOS logins verification logic that will
+ // remove records that prevent logins syncing. Once the verification logic is
+ // removed from iOS, this function can be removed from the store.
+
+ // Creating an engine requires locking the DB, so make sure to do this first
+ let engine = LoginsSyncEngine::new(Arc::clone(&self))?;
+
+ let db = self.lock_db()?;
+ let deletion_stats =
+ db.delete_undecryptable_records_for_remote_replacement(db.encdec.as_ref())?;
+ engine.set_last_sync(&db, ServerTimestamp(0))?;
+ Ok(deletion_stats)
+ }
+
+ #[handle_error(Error)]
+ pub fn wipe_local(&self) -> ApiResult<()> {
+ self.lock_db()?.wipe_local()?;
+ Ok(())
+ }
+
+ #[handle_error(Error)]
+ pub fn reset(self: Arc<Self>) -> ApiResult<()> {
+ // Reset should not exist here - all resets should be done via the
+ // sync manager. It seems that actual consumers don't use this, but
+ // some tests do, so it remains for now.
+ let engine = LoginsSyncEngine::new(Arc::clone(&self))?;
+ engine.do_reset(&EngineSyncAssociation::Disconnected)?;
+ Ok(())
+ }
+
+ #[handle_error(Error)]
+ pub fn update(&self, id: &str, entry: LoginEntry) -> ApiResult<Login> {
+ let db = self.lock_db()?;
+ db.update(id, entry, db.encdec.as_ref())
+ .and_then(|enc_login| enc_login.decrypt(db.encdec.as_ref()))
+ }
+
+ #[handle_error(Error)]
+ pub fn add(&self, entry: LoginEntry) -> ApiResult<Login> {
+ let db = self.lock_db()?;
+ db.add(entry, db.encdec.as_ref())
+ .and_then(|enc_login| enc_login.decrypt(db.encdec.as_ref()))
+ }
+
+ #[handle_error(Error)]
+ pub fn add_many(&self, entries: Vec<LoginEntry>) -> ApiResult<Vec<BulkResultEntry>> {
+ let db = self.lock_db()?;
+ db.add_many(entries, db.encdec.as_ref()).map(|enc_logins| {
+ enc_logins
+ .into_iter()
+ .map(|enc_login| map_bulk_result_entry(enc_login, db.encdec.as_ref()))
+ .collect()
+ })
+ }
+
+ /// This method is intended to preserve metadata (LoginMeta) during a migration.
+ /// In normal operation, this method should not be used; instead,
+ /// use `add(entry)`, which manages the corresponding fields itself.
+ #[handle_error(Error)]
+ pub fn add_with_meta(&self, entry_with_meta: LoginEntryWithMeta) -> ApiResult<Login> {
+ let db = self.lock_db()?;
+ db.add_with_meta(entry_with_meta, db.encdec.as_ref())
+ .and_then(|enc_login| enc_login.decrypt(db.encdec.as_ref()))
+ }
+
+ #[handle_error(Error)]
+ pub fn add_many_with_meta(
+ &self,
+ entries_with_meta: Vec<LoginEntryWithMeta>,
+ ) -> ApiResult<Vec<BulkResultEntry>> {
+ let db = self.lock_db()?;
+ db.add_many_with_meta(entries_with_meta, db.encdec.as_ref())
+ .map(|enc_logins| {
+ enc_logins
+ .into_iter()
+ .map(|enc_login| map_bulk_result_entry(enc_login, db.encdec.as_ref()))
+ .collect()
+ })
+ }
+
+ #[handle_error(Error)]
+ pub fn add_or_update(&self, entry: LoginEntry) -> ApiResult<Login> {
+ let db = self.lock_db()?;
+ db.add_or_update(entry, db.encdec.as_ref())
+ .and_then(|enc_login| enc_login.decrypt(db.encdec.as_ref()))
+ }
+
+ #[handle_error(Error)]
+ pub fn set_checkpoint(&self, checkpoint: &str) -> ApiResult<()> {
+ self.lock_db()?
+ .put_meta(schema::CHECKPOINT_KEY, &checkpoint)
+ }
+
+ #[handle_error(Error)]
+ pub fn get_checkpoint(&self) -> ApiResult<Option<String>> {
+ self.lock_db()?.get_meta(schema::CHECKPOINT_KEY)
+ }
+
+ #[handle_error(Error)]
+ pub fn run_maintenance(&self) -> ApiResult<()> {
+ let conn = self.lock_db()?;
+ run_maintenance(&conn)?;
+ Ok(())
+ }
+
+ pub fn shutdown(&self) {
+ if let Some(db) = self.db.lock().take() {
+ let _ = db.shutdown();
+ }
+ }
+
+ // This allows the embedding app to say "make this instance available to
+ // the sync manager". The implementation is more like "offer to sync mgr"
+ // (thereby avoiding us needing to link with the sync manager) but
+ // `register_with_sync_manager()` is logically what's happening so that's
+ // the name it gets.
+ pub fn register_with_sync_manager(self: Arc<Self>) {
+ let mut state = STORE_FOR_MANAGER.lock();
+ *state = Arc::downgrade(&self);
+ }
+
+ // this isn't exposed by uniffi - currently the
+ // only consumer of this is our "example" (and hence why they
+ // are `pub` and not `pub(crate)`).
+ // We could probably make the example work with the sync manager - but then
+ // our example would link with places and logins etc, and it's not a big
+ // deal really.
+ #[handle_error(Error)]
+ pub fn create_logins_sync_engine(self: Arc<Self>) -> ApiResult<Box<dyn SyncEngine>> {
+ Ok(Box::new(LoginsSyncEngine::new(self)?) as Box<dyn SyncEngine>)
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod test {
+ use super::*;
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use crate::util;
+ use nss::ensure_initialized;
+ use std::cmp::Reverse;
+ use std::time::SystemTime;
+
+ fn assert_logins_equiv(a: &LoginEntry, b: &Login) {
+ assert_eq!(a.origin, b.origin);
+ assert_eq!(a.form_action_origin, b.form_action_origin);
+ assert_eq!(a.http_realm, b.http_realm);
+ assert_eq!(a.username_field, b.username_field);
+ assert_eq!(a.password_field, b.password_field);
+ assert_eq!(b.username, a.username);
+ assert_eq!(b.password, a.password);
+ }
+
+ #[test]
+ fn test_general() {
+ ensure_initialized();
+
+ let store = LoginStore::new_in_memory();
+ let list = store.list().expect("Grabbing Empty list to work");
+ assert_eq!(list.len(), 0);
+ let start_us = util::system_time_ms_i64(SystemTime::now());
+
+ let a = LoginEntry {
+ origin: "https://www.example.com".into(),
+ form_action_origin: Some("https://www.example.com".into()),
+ username_field: "user_input".into(),
+ password_field: "pass_input".into(),
+ username: "coolperson21".into(),
+ password: "p4ssw0rd".into(),
+ ..Default::default()
+ };
+
+ let b = LoginEntry {
+ origin: "https://www.example2.com".into(),
+ http_realm: Some("Some String Here".into()),
+ username: "asdf".into(),
+ password: "fdsa".into(),
+ ..Default::default()
+ };
+ let a_id = store.add(a.clone()).expect("added a").id;
+ let b_id = store.add(b.clone()).expect("added b").id;
+
+ let a_from_db = store
+ .get(&a_id)
+ .expect("Not to error getting a")
+ .expect("a to exist");
+
+ assert_logins_equiv(&a, &a_from_db);
+ assert!(a_from_db.time_created >= start_us);
+ assert!(a_from_db.time_password_changed >= start_us);
+ assert!(a_from_db.time_last_used >= start_us);
+ assert_eq!(a_from_db.times_used, 1);
+
+ let b_from_db = store
+ .get(&b_id)
+ .expect("Not to error getting b")
+ .expect("b to exist");
+
+ assert_logins_equiv(&LoginEntry { ..b.clone() }, &b_from_db);
+ assert!(b_from_db.time_created >= start_us);
+ assert!(b_from_db.time_password_changed >= start_us);
+ assert!(b_from_db.time_last_used >= start_us);
+ assert_eq!(b_from_db.times_used, 1);
+
+ let mut list = store.list().expect("Grabbing list to work");
+ assert_eq!(list.len(), 2);
+
+ let mut expect = vec![a_from_db, b_from_db.clone()];
+
+ list.sort_by_key(|b| Reverse(b.guid()));
+ expect.sort_by_key(|b| Reverse(b.guid()));
+ assert_eq!(list, expect);
+
+ store.delete(&a_id).expect("Successful delete");
+ assert!(store
+ .get(&a_id)
+ .expect("get after delete should still work")
+ .is_none());
+
+ let list = store.list().expect("Grabbing list to work");
+ assert_eq!(list.len(), 1);
+ assert_eq!(list[0], b_from_db);
+
+ let has_logins = store
+ .has_logins_by_base_domain("example2.com")
+ .expect("Expect a result for this origin");
+ assert!(has_logins);
+
+ let list = store
+ .get_by_base_domain("example2.com")
+ .expect("Expect a list for this origin");
+ assert_eq!(list.len(), 1);
+ assert_eq!(list[0], b_from_db);
+
+ let has_logins = store
+ .has_logins_by_base_domain("www.example.com")
+ .expect("Expect a result for this origin");
+ assert!(!has_logins);
+
+ let list = store
+ .get_by_base_domain("www.example.com")
+ .expect("Expect an empty list");
+ assert_eq!(list.len(), 0);
+
+ let now_us = util::system_time_ms_i64(SystemTime::now());
+ let b2 = LoginEntry {
+ username: b.username.to_owned(),
+ password: "newpass".into(),
+ ..b
+ };
+
+ store
+ .update(&b_id, b2.clone())
+ .expect("update b should work");
+
+ let b_after_update = store
+ .get(&b_id)
+ .expect("Not to error getting b")
+ .expect("b to exist");
+
+ assert_logins_equiv(&b2, &b_after_update);
+ assert!(b_after_update.time_created >= start_us);
+ assert!(b_after_update.time_created <= now_us);
+ assert!(b_after_update.time_password_changed >= now_us);
+ assert!(b_after_update.time_last_used >= now_us);
+ // Should be two even though we updated twice
+ assert_eq!(b_after_update.times_used, 2);
+ }
+
+ #[test]
+ fn test_checkpoint() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ let checkpoint = "a-checkpoint";
+ store.set_checkpoint(checkpoint).ok();
+ assert_eq!(store.get_checkpoint().unwrap().unwrap(), checkpoint);
+ }
+
+ #[test]
+ fn test_sync_manager_registration() {
+ ensure_initialized();
+ let store = Arc::new(LoginStore::new_in_memory());
+ assert_eq!(Arc::strong_count(&store), 1);
+ assert_eq!(Arc::weak_count(&store), 0);
+ Arc::clone(&store).register_with_sync_manager();
+ assert_eq!(Arc::strong_count(&store), 1);
+ assert_eq!(Arc::weak_count(&store), 1);
+ let registered = STORE_FOR_MANAGER.lock().upgrade().expect("should upgrade");
+ assert!(Arc::ptr_eq(&store, ®istered));
+ drop(registered);
+ // should be no new references
+ assert_eq!(Arc::strong_count(&store), 1);
+ assert_eq!(Arc::weak_count(&store), 1);
+ // dropping the registered object should drop the registration.
+ drop(store);
+ assert!(STORE_FOR_MANAGER.lock().upgrade().is_none());
+ }
+
+ #[test]
+ fn test_wipe_local_on_a_fresh_database_is_a_noop() {
+ ensure_initialized();
+ // If the database has data, then wipe_local() returns > 0 rows deleted
+ let db = LoginDb::open_in_memory();
+ db.add_or_update(
+ LoginEntry {
+ origin: "https://www.example.com".into(),
+ form_action_origin: Some("https://www.example.com".into()),
+ username_field: "user_input".into(),
+ password_field: "pass_input".into(),
+ username: "coolperson21".into(),
+ password: "p4ssw0rd".into(),
+ ..Default::default()
+ },
+ &TEST_ENCDEC.clone(),
+ )
+ .unwrap();
+ assert!(db.wipe_local().unwrap() > 0);
+
+ // If the database is empty, then wipe_local() returns 0 rows deleted
+ let db = LoginDb::open_in_memory();
+ assert_eq!(db.wipe_local().unwrap(), 0);
+ }
+
+ #[test]
+ fn test_shutdown() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ store.shutdown();
+ assert!(matches!(
+ store.list(),
+ Err(LoginsApiError::UnexpectedLoginsApiError { reason: _ })
+ ));
+ assert!(store.db.lock().is_none());
+ }
+
+ #[test]
+ fn test_delete_undecryptable_records_for_remote_replacement() {
+ ensure_initialized();
+ let store = Arc::new(LoginStore::new_in_memory());
+ // Not much of a test, but let's make sure this doesn't deadlock at least.
+ store
+ .delete_undecryptable_records_for_remote_replacement()
+ .unwrap();
+ }
+}
+
+#[test]
+fn test_send() {
+ fn ensure_send<T: Send>() {}
+ ensure_send::<LoginStore>();
+}
diff --git a/third_party/rust/logins/src/sync/engine.rs b/third_party/rust/logins/src/sync/engine.rs
@@ -0,0 +1,1188 @@
+/* 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 super::merge::{LocalLogin, MirrorLogin, SyncLoginData};
+use super::update_plan::UpdatePlan;
+use super::SyncStatus;
+use crate::db::CLONE_ENTIRE_MIRROR_SQL;
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::login::EncryptedLogin;
+use crate::schema;
+use crate::util;
+use crate::LoginDb;
+use crate::LoginStore;
+use interrupt_support::SqlInterruptScope;
+use rusqlite::named_params;
+use sql_support::ConnExt;
+use std::cell::RefCell;
+use std::collections::HashSet;
+use std::sync::Arc;
+use std::time::{Duration, UNIX_EPOCH};
+use sync15::bso::{IncomingBso, OutgoingBso, OutgoingEnvelope};
+use sync15::engine::{CollSyncIds, CollectionRequest, EngineSyncAssociation, SyncEngine};
+use sync15::{telemetry, ServerTimestamp};
+use sync_guid::Guid;
+
+// The sync engine.
+pub struct LoginsSyncEngine {
+ pub store: Arc<LoginStore>,
+ pub scope: SqlInterruptScope,
+ pub encdec: Arc<dyn EncryptorDecryptor>,
+ pub staged: RefCell<Vec<IncomingBso>>,
+}
+
+impl LoginsSyncEngine {
+ pub fn new(store: Arc<LoginStore>) -> Result<Self> {
+ let db = store.lock_db()?;
+ let scope = db.begin_interrupt_scope()?;
+ let encdec = db.encdec.clone();
+ drop(db);
+ Ok(Self {
+ store,
+ encdec,
+ scope,
+ staged: RefCell::new(vec![]),
+ })
+ }
+
+ fn reconcile(
+ &self,
+ records: Vec<SyncLoginData>,
+ server_now: ServerTimestamp,
+ telem: &mut telemetry::EngineIncoming,
+ ) -> Result<UpdatePlan> {
+ let mut plan = UpdatePlan::default();
+
+ for mut record in records {
+ self.scope.err_if_interrupted()?;
+ debug!("Processing remote change {}", record.guid());
+ let upstream = if let Some(inbound) = record.inbound.take() {
+ inbound
+ } else {
+ debug!("Processing inbound deletion (always prefer)");
+ plan.plan_delete(record.guid.clone());
+ continue;
+ };
+ let upstream_time = record.inbound_ts;
+ match (record.mirror.take(), record.local.take()) {
+ (Some(mirror), Some(local)) => {
+ debug!(" Conflict between remote and local, Resolving with 3WM");
+ plan.plan_three_way_merge(
+ local,
+ mirror,
+ upstream,
+ upstream_time,
+ server_now,
+ self.encdec.as_ref(),
+ )?;
+ telem.reconciled(1);
+ }
+ (Some(_mirror), None) => {
+ debug!(" Forwarding mirror to remote");
+ plan.plan_mirror_update(upstream, upstream_time);
+ telem.applied(1);
+ }
+ (None, Some(local)) => {
+ debug!(" Conflicting record without shared parent, Resolving with 2WM");
+ plan.plan_two_way_merge(local, (upstream, upstream_time));
+ telem.reconciled(1);
+ }
+ (None, None) => {
+ if let Some(dupe) = self.find_dupe_login(&upstream.login)? {
+ debug!(
+ " Incoming record {} was is a dupe of local record {}",
+ upstream.guid(),
+ dupe.guid()
+ );
+ let local_modified = UNIX_EPOCH
+ + Duration::from_millis(dupe.meta.time_password_changed as u64);
+ let local = LocalLogin::Alive {
+ login: dupe,
+ local_modified,
+ };
+ plan.plan_two_way_merge(local, (upstream, upstream_time));
+ } else {
+ debug!(" No dupe found, inserting into mirror");
+ plan.plan_mirror_insert(upstream, upstream_time, false);
+ }
+ telem.applied(1);
+ }
+ }
+ }
+ Ok(plan)
+ }
+
+ fn execute_plan(&self, plan: UpdatePlan) -> Result<()> {
+ // Because rusqlite want a mutable reference to create a transaction
+ // (as a way to save us from ourselves), we side-step that by creating
+ // it manually.
+ let db = self.store.lock_db()?;
+ let tx = db.unchecked_transaction()?;
+ plan.execute(&tx, &self.scope)?;
+ tx.commit()?;
+ Ok(())
+ }
+
+ // Fetch all the data for the provided IDs.
+ // TODO: Might be better taking a fn instead of returning all of it... But that func will likely
+ // want to insert stuff while we're doing this so ugh.
+ fn fetch_login_data(
+ &self,
+ records: Vec<IncomingBso>,
+ telem: &mut telemetry::EngineIncoming,
+ ) -> Result<Vec<SyncLoginData>> {
+ let mut sync_data = Vec::with_capacity(records.len());
+ {
+ let mut seen_ids: HashSet<Guid> = HashSet::with_capacity(records.len());
+ for incoming in records.into_iter() {
+ let id = incoming.envelope.id.clone();
+ match SyncLoginData::from_bso(incoming, self.encdec.as_ref()) {
+ Ok(v) => sync_data.push(v),
+ Err(e) => {
+ match e {
+ // This is a known error with Desktop logins (see #5233), just log it
+ // rather than reporting to sentry
+ Error::InvalidLogin(InvalidLogin::IllegalOrigin) => {
+ warn!("logins-deserialize-error: {e}");
+ }
+ // For all other errors, report them to Sentry
+ _ => {
+ report_error!(
+ "logins-deserialize-error",
+ "Failed to deserialize record {:?}: {e}",
+ id
+ );
+ }
+ };
+ // Ideally we'd track new_failed, but it's unclear how
+ // much value it has.
+ telem.failed(1);
+ }
+ }
+ seen_ids.insert(id);
+ }
+ }
+ self.scope.err_if_interrupted()?;
+
+ sql_support::each_chunk(
+ &sync_data
+ .iter()
+ .map(|s| s.guid.as_str().to_string())
+ .collect::<Vec<String>>(),
+ |chunk, offset| -> Result<()> {
+ // pairs the bound parameter for the guid with an integer index.
+ let values_with_idx = sql_support::repeat_display(chunk.len(), ",", |i, f| {
+ write!(f, "({},?)", i + offset)
+ });
+ let query = format!(
+ "WITH to_fetch(guid_idx, fetch_guid) AS (VALUES {vals})
+ SELECT
+ {common_cols},
+ is_overridden,
+ server_modified,
+ NULL as local_modified,
+ NULL as is_deleted,
+ NULL as sync_status,
+ 1 as is_mirror,
+ to_fetch.guid_idx as guid_idx
+ FROM loginsM
+ JOIN to_fetch
+ ON loginsM.guid = to_fetch.fetch_guid
+
+ UNION ALL
+
+ SELECT
+ {common_cols},
+ NULL as is_overridden,
+ NULL as server_modified,
+ local_modified,
+ is_deleted,
+ sync_status,
+ 0 as is_mirror,
+ to_fetch.guid_idx as guid_idx
+ FROM loginsL
+ JOIN to_fetch
+ ON loginsL.guid = to_fetch.fetch_guid",
+ // give each VALUES item 2 entries, an index and the parameter.
+ vals = values_with_idx,
+ common_cols = schema::COMMON_COLS,
+ );
+
+ let db = &self.store.lock_db()?;
+ let mut stmt = db.prepare(&query)?;
+
+ let rows = stmt.query_and_then(rusqlite::params_from_iter(chunk), |row| {
+ let guid_idx_i = row.get::<_, i64>("guid_idx")?;
+ // Hitting this means our math is wrong...
+ assert!(guid_idx_i >= 0);
+
+ let guid_idx = guid_idx_i as usize;
+ let is_mirror: bool = row.get("is_mirror")?;
+ if is_mirror {
+ sync_data[guid_idx].set_mirror(MirrorLogin::from_row(row)?)?;
+ } else {
+ sync_data[guid_idx].set_local(LocalLogin::from_row(row)?)?;
+ }
+ self.scope.err_if_interrupted()?;
+ Ok(())
+ })?;
+ // `rows` is an Iterator<Item = Result<()>>, so we need to collect to handle the errors.
+ rows.collect::<Result<()>>()?;
+ Ok(())
+ },
+ )?;
+ Ok(sync_data)
+ }
+
+ fn fetch_outgoing(&self) -> Result<Vec<OutgoingBso>> {
+ // Taken from iOS. Arbitrarily large, so that clients that want to
+ // process deletions first can; for us it doesn't matter.
+ const TOMBSTONE_SORTINDEX: i32 = 5_000_000;
+ const DEFAULT_SORTINDEX: i32 = 1;
+ let db = self.store.lock_db()?;
+ let mut stmt = db.prepare_cached(&format!(
+ "SELECT L.*, M.enc_unknown_fields
+ FROM loginsL L LEFT JOIN loginsM M ON L.guid = M.guid
+ WHERE sync_status IS NOT {synced}",
+ synced = SyncStatus::Synced as u8
+ ))?;
+ let bsos = stmt.query_and_then([], |row| {
+ self.scope.err_if_interrupted()?;
+ Ok(if row.get::<_, bool>("is_deleted")? {
+ let envelope = OutgoingEnvelope {
+ id: row.get::<_, String>("guid")?.into(),
+ sortindex: Some(TOMBSTONE_SORTINDEX),
+ ..Default::default()
+ };
+ OutgoingBso::new_tombstone(envelope)
+ } else {
+ let unknown = row.get::<_, Option<String>>("enc_unknown_fields")?;
+ let mut bso =
+ EncryptedLogin::from_row(row)?.into_bso(self.encdec.as_ref(), unknown)?;
+ bso.envelope.sortindex = Some(DEFAULT_SORTINDEX);
+ bso
+ })
+ })?;
+ bsos.collect::<Result<_>>()
+ }
+
+ fn do_apply_incoming(
+ &self,
+ inbound: Vec<IncomingBso>,
+ timestamp: ServerTimestamp,
+ telem: &mut telemetry::Engine,
+ ) -> Result<Vec<OutgoingBso>> {
+ let mut incoming_telemetry = telemetry::EngineIncoming::new();
+ let data = self.fetch_login_data(inbound, &mut incoming_telemetry)?;
+ let plan = {
+ let result = self.reconcile(data, timestamp, &mut incoming_telemetry);
+ telem.incoming(incoming_telemetry);
+ result
+ }?;
+ self.execute_plan(plan)?;
+ self.fetch_outgoing()
+ }
+
+ // Note this receives the db to prevent a deadlock
+ pub fn set_last_sync(&self, db: &LoginDb, last_sync: ServerTimestamp) -> Result<()> {
+ debug!("Updating last sync to {}", last_sync);
+ let last_sync_millis = last_sync.as_millis();
+ db.put_meta(schema::LAST_SYNC_META_KEY, &last_sync_millis)
+ }
+
+ fn get_last_sync(&self, db: &LoginDb) -> Result<Option<ServerTimestamp>> {
+ let millis = db.get_meta::<i64>(schema::LAST_SYNC_META_KEY)?.unwrap();
+ Ok(Some(ServerTimestamp(millis)))
+ }
+
+ pub fn set_global_state(&self, state: &Option<String>) -> Result<()> {
+ let to_write = match state {
+ Some(ref s) => s,
+ None => "",
+ };
+ let db = self.store.lock_db()?;
+ db.put_meta(schema::GLOBAL_STATE_META_KEY, &to_write)
+ }
+
+ pub fn get_global_state(&self) -> Result<Option<String>> {
+ let db = self.store.lock_db()?;
+ db.get_meta::<String>(schema::GLOBAL_STATE_META_KEY)
+ }
+
+ fn mark_as_synchronized(&self, guids: &[&str], ts: ServerTimestamp) -> Result<()> {
+ let db = self.store.lock_db()?;
+ let tx = db.unchecked_transaction()?;
+ sql_support::each_chunk(guids, |chunk, _| -> Result<()> {
+ db.execute(
+ &format!(
+ "DELETE FROM loginsM WHERE guid IN ({vars})",
+ vars = sql_support::repeat_sql_vars(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ self.scope.err_if_interrupted()?;
+
+ db.execute(
+ &format!(
+ "INSERT OR IGNORE INTO loginsM (
+ {common_cols}, is_overridden, server_modified
+ )
+ SELECT {common_cols}, 0, {modified_ms_i64}
+ FROM loginsL
+ WHERE is_deleted = 0 AND guid IN ({vars})",
+ common_cols = schema::COMMON_COLS,
+ modified_ms_i64 = ts.as_millis(),
+ vars = sql_support::repeat_sql_vars(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ self.scope.err_if_interrupted()?;
+
+ db.execute(
+ &format!(
+ "DELETE FROM loginsL WHERE guid IN ({vars})",
+ vars = sql_support::repeat_sql_vars(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ self.scope.err_if_interrupted()?;
+ Ok(())
+ })?;
+ self.set_last_sync(&db, ts)?;
+ tx.commit()?;
+ Ok(())
+ }
+
+ // This exists here as a public function so the store can call it. Ideally
+ // the store would not do that :) Then it can go back into the sync trait
+ // and return an anyhow::Result
+ pub fn do_reset(&self, assoc: &EngineSyncAssociation) -> Result<()> {
+ info!("Executing reset on password engine!");
+ let db = self.store.lock_db()?;
+ let tx = db.unchecked_transaction()?;
+ db.execute_all(&[
+ &CLONE_ENTIRE_MIRROR_SQL,
+ "DELETE FROM loginsM",
+ &format!("UPDATE loginsL SET sync_status = {}", SyncStatus::New as u8),
+ ])?;
+ self.set_last_sync(&db, ServerTimestamp(0))?;
+ match assoc {
+ EngineSyncAssociation::Disconnected => {
+ db.delete_meta(schema::GLOBAL_SYNCID_META_KEY)?;
+ db.delete_meta(schema::COLLECTION_SYNCID_META_KEY)?;
+ }
+ EngineSyncAssociation::Connected(ids) => {
+ db.put_meta(schema::GLOBAL_SYNCID_META_KEY, &ids.global)?;
+ db.put_meta(schema::COLLECTION_SYNCID_META_KEY, &ids.coll)?;
+ }
+ };
+ db.delete_meta(schema::GLOBAL_STATE_META_KEY)?;
+ tx.commit()?;
+ Ok(())
+ }
+
+ // It would be nice if this were a batch-ish api (e.g. takes a slice of records and finds dupes
+ // for each one if they exist)... I can't think of how to write that query, though.
+ // This is subtly different from dupe handling by the main API and maybe
+ // could be consolidated, but for now it remains sync specific.
+ pub(crate) fn find_dupe_login(&self, l: &EncryptedLogin) -> Result<Option<EncryptedLogin>> {
+ let form_submit_host_port = l
+ .fields
+ .form_action_origin
+ .as_ref()
+ .and_then(|s| util::url_host_port(s));
+ let enc_fields = l.decrypt_fields(self.encdec.as_ref())?;
+ let args = named_params! {
+ ":origin": l.fields.origin,
+ ":http_realm": l.fields.http_realm,
+ ":form_submit": form_submit_host_port,
+ };
+ let mut query = format!(
+ "SELECT {common}
+ FROM loginsL
+ WHERE origin IS :origin
+ AND httpRealm IS :http_realm",
+ common = schema::COMMON_COLS,
+ );
+ if form_submit_host_port.is_some() {
+ // Stolen from iOS
+ query += " AND (formActionOrigin = '' OR (instr(formActionOrigin, :form_submit) > 0))";
+ } else {
+ query += " AND formActionOrigin IS :form_submit"
+ }
+ let db = self.store.lock_db()?;
+ let mut stmt = db.prepare_cached(&query)?;
+ for login in stmt
+ .query_and_then(args, EncryptedLogin::from_row)?
+ .collect::<Result<Vec<EncryptedLogin>>>()?
+ {
+ let this_enc_fields = login.decrypt_fields(self.encdec.as_ref())?;
+ if enc_fields.username == this_enc_fields.username {
+ return Ok(Some(login));
+ }
+ }
+ Ok(None)
+ }
+}
+
+impl SyncEngine for LoginsSyncEngine {
+ fn collection_name(&self) -> std::borrow::Cow<'static, str> {
+ "passwords".into()
+ }
+
+ fn stage_incoming(
+ &self,
+ mut inbound: Vec<IncomingBso>,
+ _telem: &mut telemetry::Engine,
+ ) -> anyhow::Result<()> {
+ // We don't have cross-item dependencies like bookmarks does, so we can
+ // just apply now instead of "staging"
+ self.staged.borrow_mut().append(&mut inbound);
+ Ok(())
+ }
+
+ fn apply(
+ &self,
+ timestamp: ServerTimestamp,
+ telem: &mut telemetry::Engine,
+ ) -> anyhow::Result<Vec<OutgoingBso>> {
+ let inbound = (*self.staged.borrow_mut()).drain(..).collect();
+ Ok(self.do_apply_incoming(inbound, timestamp, telem)?)
+ }
+
+ fn set_uploaded(&self, new_timestamp: ServerTimestamp, ids: Vec<Guid>) -> anyhow::Result<()> {
+ Ok(self.mark_as_synchronized(
+ &ids.iter().map(Guid::as_str).collect::<Vec<_>>(),
+ new_timestamp,
+ )?)
+ }
+
+ fn get_collection_request(
+ &self,
+ server_timestamp: ServerTimestamp,
+ ) -> anyhow::Result<Option<CollectionRequest>> {
+ let db = self.store.lock_db()?;
+ let since = self.get_last_sync(&db)?.unwrap_or_default();
+ Ok(if since == server_timestamp {
+ None
+ } else {
+ Some(
+ CollectionRequest::new("passwords".into())
+ .full()
+ .newer_than(since),
+ )
+ })
+ }
+
+ fn get_sync_assoc(&self) -> anyhow::Result<EngineSyncAssociation> {
+ let db = self.store.lock_db()?;
+ let global = db.get_meta(schema::GLOBAL_SYNCID_META_KEY)?;
+ let coll = db.get_meta(schema::COLLECTION_SYNCID_META_KEY)?;
+ Ok(if let (Some(global), Some(coll)) = (global, coll) {
+ EngineSyncAssociation::Connected(CollSyncIds { global, coll })
+ } else {
+ EngineSyncAssociation::Disconnected
+ })
+ }
+
+ fn reset(&self, assoc: &EngineSyncAssociation) -> anyhow::Result<()> {
+ self.do_reset(assoc)?;
+ Ok(())
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::db::test_utils::insert_login;
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use crate::login::test_utils::enc_login;
+ use crate::{LoginEntry, LoginFields, LoginMeta, SecureLoginFields};
+ use nss::ensure_initialized;
+ use std::collections::HashMap;
+ use std::sync::Arc;
+
+ // Wrap sync functions for easier testing
+ fn run_fetch_login_data(
+ engine: &mut LoginsSyncEngine,
+ records: Vec<IncomingBso>,
+ ) -> (Vec<SyncLoginData>, telemetry::EngineIncoming) {
+ let mut telem = sync15::telemetry::EngineIncoming::new();
+ (engine.fetch_login_data(records, &mut telem).unwrap(), telem)
+ }
+
+ fn run_fetch_outgoing(store: LoginStore) -> Vec<OutgoingBso> {
+ let engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+ engine.fetch_outgoing().unwrap()
+ }
+
+ #[test]
+ fn test_fetch_login_data() {
+ ensure_initialized();
+ // Test some common cases with fetch_login data
+ let store = LoginStore::new_in_memory();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "updated_remotely",
+ None,
+ Some("password"),
+ );
+ insert_login(
+ &store.lock_db().unwrap(),
+ "deleted_remotely",
+ None,
+ Some("password"),
+ );
+ insert_login(
+ &store.lock_db().unwrap(),
+ "three_way_merge",
+ Some("new-local-password"),
+ Some("password"),
+ );
+
+ let mut engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+
+ let (res, _) = run_fetch_login_data(
+ &mut engine,
+ vec![
+ IncomingBso::new_test_tombstone(Guid::new("deleted_remotely")),
+ enc_login("added_remotely", "password")
+ .into_bso(&*TEST_ENCDEC, None)
+ .unwrap()
+ .to_test_incoming(),
+ enc_login("updated_remotely", "new-password")
+ .into_bso(&*TEST_ENCDEC, None)
+ .unwrap()
+ .to_test_incoming(),
+ enc_login("three_way_merge", "new-remote-password")
+ .into_bso(&*TEST_ENCDEC, None)
+ .unwrap()
+ .to_test_incoming(),
+ ],
+ );
+ // For simpler testing, extract/decrypt passwords and put them in a hash map
+ #[derive(Debug, PartialEq)]
+ struct SyncPasswords {
+ local: Option<String>,
+ mirror: Option<String>,
+ inbound: Option<String>,
+ }
+ let extracted_passwords: HashMap<String, SyncPasswords> = res
+ .into_iter()
+ .map(|sync_login_data| {
+ let mut guids_seen = HashSet::new();
+ let passwords = SyncPasswords {
+ local: sync_login_data.local.map(|local_login| {
+ guids_seen.insert(local_login.guid_str().to_string());
+ let LocalLogin::Alive { login, .. } = local_login else {
+ unreachable!("this test is not expecting a tombstone");
+ };
+ login.decrypt_fields(&*TEST_ENCDEC).unwrap().password
+ }),
+ mirror: sync_login_data.mirror.map(|mirror_login| {
+ guids_seen.insert(mirror_login.login.meta.id.clone());
+ mirror_login
+ .login
+ .decrypt_fields(&*TEST_ENCDEC)
+ .unwrap()
+ .password
+ }),
+ inbound: sync_login_data.inbound.map(|incoming| {
+ guids_seen.insert(incoming.login.meta.id.clone());
+ incoming
+ .login
+ .decrypt_fields(&*TEST_ENCDEC)
+ .unwrap()
+ .password
+ }),
+ };
+ (guids_seen.into_iter().next().unwrap(), passwords)
+ })
+ .collect();
+
+ assert_eq!(extracted_passwords.len(), 4);
+ assert_eq!(
+ extracted_passwords.get("added_remotely").unwrap(),
+ &SyncPasswords {
+ local: None,
+ mirror: None,
+ inbound: Some("password".into()),
+ }
+ );
+ assert_eq!(
+ extracted_passwords.get("updated_remotely").unwrap(),
+ &SyncPasswords {
+ local: None,
+ mirror: Some("password".into()),
+ inbound: Some("new-password".into()),
+ }
+ );
+ assert_eq!(
+ extracted_passwords.get("deleted_remotely").unwrap(),
+ &SyncPasswords {
+ local: None,
+ mirror: Some("password".into()),
+ inbound: None,
+ }
+ );
+ assert_eq!(
+ extracted_passwords.get("three_way_merge").unwrap(),
+ &SyncPasswords {
+ local: Some("new-local-password".into()),
+ mirror: Some("password".into()),
+ inbound: Some("new-remote-password".into()),
+ }
+ );
+ }
+
+ #[test]
+ fn test_sync_local_delete() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "local-deleted",
+ Some("password"),
+ None,
+ );
+ store.lock_db().unwrap().delete("local-deleted").unwrap();
+ let changeset = run_fetch_outgoing(store);
+ let changes: HashMap<String, serde_json::Value> = changeset
+ .into_iter()
+ .map(|b| {
+ (
+ b.envelope.id.to_string(),
+ serde_json::from_str(&b.payload).unwrap(),
+ )
+ })
+ .collect();
+ assert_eq!(changes.len(), 1);
+ assert!(changes["local-deleted"].get("deleted").is_some());
+
+ // hmmm. In theory, we do not need to sync a local-only deletion
+ }
+
+ #[test]
+ fn test_sync_local_readd() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "local-readded",
+ Some("password"),
+ None,
+ );
+ store.lock_db().unwrap().delete("local-readded").unwrap();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "local-readded",
+ Some("password"),
+ None,
+ );
+ let changeset = run_fetch_outgoing(store);
+ let changes: HashMap<String, serde_json::Value> = changeset
+ .into_iter()
+ .map(|b| {
+ (
+ b.envelope.id.to_string(),
+ serde_json::from_str(&b.payload).unwrap(),
+ )
+ })
+ .collect();
+ assert_eq!(changes.len(), 1);
+ assert_eq!(
+ changes["local-readded"].get("password").unwrap(),
+ "password"
+ );
+ }
+
+ #[test]
+ fn test_sync_local_readd_of_remote_deletion() {
+ ensure_initialized();
+ let other_store = LoginStore::new_in_memory();
+ let mut engine = LoginsSyncEngine::new(Arc::new(other_store)).unwrap();
+ let (_res, _telem) = run_fetch_login_data(
+ &mut engine,
+ vec![IncomingBso::new_test_tombstone(Guid::new("remote-readded"))],
+ );
+
+ let store = LoginStore::new_in_memory();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "remote-readded",
+ Some("password"),
+ None,
+ );
+ let changeset = run_fetch_outgoing(store);
+ let changes: HashMap<String, serde_json::Value> = changeset
+ .into_iter()
+ .map(|b| {
+ (
+ b.envelope.id.to_string(),
+ serde_json::from_str(&b.payload).unwrap(),
+ )
+ })
+ .collect();
+ assert_eq!(changes.len(), 1);
+ assert_eq!(
+ changes["remote-readded"].get("password").unwrap(),
+ "password"
+ );
+ }
+
+ #[test]
+ fn test_sync_local_readd_redelete_of_remote_login() {
+ ensure_initialized();
+ let other_store = LoginStore::new_in_memory();
+ let mut engine = LoginsSyncEngine::new(Arc::new(other_store)).unwrap();
+ let (_res, _telem) = run_fetch_login_data(
+ &mut engine,
+ vec![IncomingBso::from_test_content(serde_json::json!({
+ "id": "remote-readded-redeleted",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ }))],
+ );
+
+ let store = LoginStore::new_in_memory();
+ store
+ .lock_db()
+ .unwrap()
+ .delete("remote-readded-redeleted")
+ .unwrap();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "remote-readded-redeleted",
+ Some("password"),
+ None,
+ );
+ store
+ .lock_db()
+ .unwrap()
+ .delete("remote-readded-redeleted")
+ .unwrap();
+ let changeset = run_fetch_outgoing(store);
+ let changes: HashMap<String, serde_json::Value> = changeset
+ .into_iter()
+ .map(|b| {
+ (
+ b.envelope.id.to_string(),
+ serde_json::from_str(&b.payload).unwrap(),
+ )
+ })
+ .collect();
+ assert_eq!(changes.len(), 1);
+ assert!(changes["remote-readded-redeleted"].get("deleted").is_some());
+ }
+
+ #[test]
+ fn test_fetch_outgoing() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ insert_login(
+ &store.lock_db().unwrap(),
+ "changed",
+ Some("new-password"),
+ Some("password"),
+ );
+ insert_login(
+ &store.lock_db().unwrap(),
+ "unchanged",
+ None,
+ Some("password"),
+ );
+ insert_login(&store.lock_db().unwrap(), "added", Some("password"), None);
+ insert_login(&store.lock_db().unwrap(), "deleted", None, Some("password"));
+ store.lock_db().unwrap().delete("deleted").unwrap();
+
+ let changeset = run_fetch_outgoing(store);
+ let changes: HashMap<String, serde_json::Value> = changeset
+ .into_iter()
+ .map(|b| {
+ (
+ b.envelope.id.to_string(),
+ serde_json::from_str(&b.payload).unwrap(),
+ )
+ })
+ .collect();
+ assert_eq!(changes.len(), 3);
+ assert_eq!(changes["added"].get("password").unwrap(), "password");
+ assert_eq!(changes["changed"].get("password").unwrap(), "new-password");
+ assert!(changes["deleted"].get("deleted").is_some());
+ assert!(changes["added"].get("deleted").is_none());
+ assert!(changes["changed"].get("deleted").is_none());
+ }
+
+ #[test]
+ fn test_bad_record() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+ let test_ids = ["dummy_000001", "dummy_000002", "dummy_000003"];
+ for id in test_ids {
+ insert_login(
+ &store.lock_db().unwrap(),
+ id,
+ Some("password"),
+ Some("password"),
+ );
+ }
+ let mut engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+ engine
+ .mark_as_synchronized(&test_ids, ServerTimestamp::from_millis(100))
+ .unwrap();
+ let (res, telem) = run_fetch_login_data(
+ &mut engine,
+ vec![
+ IncomingBso::new_test_tombstone(Guid::new("dummy_000001")),
+ // invalid
+ IncomingBso::from_test_content(serde_json::json!({
+ "id": "dummy_000002",
+ "garbage": "data",
+ "etc": "not a login"
+ })),
+ // valid
+ IncomingBso::from_test_content(serde_json::json!({
+ "id": "dummy_000003",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ })),
+ ],
+ );
+ assert_eq!(telem.get_failed(), 1);
+ assert_eq!(res.len(), 2);
+ assert_eq!(res[0].guid, "dummy_000001");
+ assert_eq!(res[1].guid, "dummy_000003");
+ assert_eq!(engine.fetch_outgoing().unwrap().len(), 0);
+ }
+
+ fn make_enc_login(
+ username: &str,
+ password: &str,
+ fao: Option<String>,
+ realm: Option<String>,
+ ) -> EncryptedLogin {
+ ensure_initialized();
+ let id = Guid::random().to_string();
+ let sec_fields = SecureLoginFields {
+ username: username.into(),
+ password: password.into(),
+ }
+ .encrypt(&*TEST_ENCDEC, &id)
+ .unwrap();
+ EncryptedLogin {
+ meta: LoginMeta {
+ id,
+ ..Default::default()
+ },
+ fields: LoginFields {
+ form_action_origin: fao,
+ http_realm: realm,
+ origin: "http://not-relevant-here.com".into(),
+ ..Default::default()
+ },
+ sec_fields,
+ }
+ }
+
+ #[test]
+ fn find_dupe_login() {
+ ensure_initialized();
+ let store = LoginStore::new_in_memory();
+
+ let to_add = LoginEntry {
+ form_action_origin: Some("https://www.example.com".into()),
+ origin: "http://not-relevant-here.com".into(),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ };
+ let first_id = store.add(to_add).expect("should insert first").id;
+
+ let to_add = LoginEntry {
+ form_action_origin: Some("https://www.example1.com".into()),
+ origin: "http://not-relevant-here.com".into(),
+ username: "test1".into(),
+ password: "test1".into(),
+ ..Default::default()
+ };
+ let second_id = store.add(to_add).expect("should insert second").id;
+
+ let to_add = LoginEntry {
+ http_realm: Some("http://some-realm.com".into()),
+ origin: "http://not-relevant-here.com".into(),
+ username: "test1".into(),
+ password: "test1".into(),
+ ..Default::default()
+ };
+ let no_form_origin_id = store.add(to_add).expect("should insert second").id;
+
+ let engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+
+ let to_find = make_enc_login("test", "test", Some("https://www.example.com".into()), None);
+ assert_eq!(
+ engine
+ .find_dupe_login(&to_find)
+ .expect("should work")
+ .expect("should be Some()")
+ .meta
+ .id,
+ first_id
+ );
+
+ let to_find = make_enc_login(
+ "test",
+ "test",
+ Some("https://something-else.com".into()),
+ None,
+ );
+ assert!(engine
+ .find_dupe_login(&to_find)
+ .expect("should work")
+ .is_none());
+
+ let to_find = make_enc_login(
+ "test1",
+ "test1",
+ Some("https://www.example1.com".into()),
+ None,
+ );
+ assert_eq!(
+ engine
+ .find_dupe_login(&to_find)
+ .expect("should work")
+ .expect("should be Some()")
+ .meta
+ .id,
+ second_id
+ );
+
+ let to_find = make_enc_login(
+ "other",
+ "other",
+ Some("https://www.example1.com".into()),
+ None,
+ );
+ assert!(engine
+ .find_dupe_login(&to_find)
+ .expect("should work")
+ .is_none());
+
+ // no form origin.
+ let to_find = make_enc_login("test1", "test1", None, Some("http://some-realm.com".into()));
+ assert_eq!(
+ engine
+ .find_dupe_login(&to_find)
+ .expect("should work")
+ .expect("should be Some()")
+ .meta
+ .id,
+ no_form_origin_id
+ );
+ }
+
+ #[test]
+ fn test_roundtrip_unknown() {
+ ensure_initialized();
+ // A couple of helpers
+ fn apply_incoming_payload(engine: &LoginsSyncEngine, payload: serde_json::Value) {
+ let bso = IncomingBso::from_test_content(payload);
+ let mut telem = sync15::telemetry::Engine::new(engine.collection_name());
+ engine.stage_incoming(vec![bso], &mut telem).unwrap();
+ engine
+ .apply(ServerTimestamp::from_millis(0), &mut telem)
+ .unwrap();
+ }
+
+ fn get_outgoing_payload(engine: &LoginsSyncEngine) -> serde_json::Value {
+ // Edit it so it's considered outgoing.
+ engine
+ .store
+ .update(
+ "dummy_000001",
+ LoginEntry {
+ origin: "https://www.example2.com".into(),
+ http_realm: Some("https://www.example2.com".into()),
+ username: "test".into(),
+ password: "test".into(),
+ ..Default::default()
+ },
+ )
+ .unwrap();
+ let changeset = engine.fetch_outgoing().unwrap();
+ assert_eq!(changeset.len(), 1);
+ serde_json::from_str::<serde_json::Value>(&changeset[0].payload).unwrap()
+ }
+
+ // The test itself...
+ let store = LoginStore::new_in_memory();
+ let engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+
+ apply_incoming_payload(
+ &engine,
+ serde_json::json!({
+ "id": "dummy_000001",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "unknown1": "?",
+ "unknown2": {"sub": "object"},
+ }),
+ );
+
+ let payload = get_outgoing_payload(&engine);
+
+ // The outgoing payload for our item should have the unknown fields.
+ assert_eq!(payload.get("unknown1").unwrap().as_str().unwrap(), "?");
+ assert_eq!(
+ payload.get("unknown2").unwrap(),
+ &serde_json::json!({"sub": "object"})
+ );
+
+ // test mirror updates - record is already in our mirror, but now it's
+ // incoming with different unknown fields.
+ apply_incoming_payload(
+ &engine,
+ serde_json::json!({
+ "id": "dummy_000001",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "unknown2": 99,
+ "unknown3": {"something": "else"},
+ }),
+ );
+ let payload = get_outgoing_payload(&engine);
+ // old unknown values were replaced.
+ assert!(payload.get("unknown1").is_none());
+ assert_eq!(payload.get("unknown2").unwrap().as_u64().unwrap(), 99);
+ assert_eq!(
+ payload
+ .get("unknown3")
+ .unwrap()
+ .as_object()
+ .unwrap()
+ .get("something")
+ .unwrap()
+ .as_str()
+ .unwrap(),
+ "else"
+ );
+ }
+
+ fn count(engine: &LoginsSyncEngine, table_name: &str) -> u32 {
+ ensure_initialized();
+ let sql = format!("SELECT COUNT(*) FROM {table_name}");
+ engine
+ .store
+ .lock_db()
+ // TODO: get rid of this unwrap
+ .unwrap()
+ .try_query_one(&sql, [], false)
+ .unwrap()
+ .unwrap()
+ }
+
+ fn do_test_incoming_with_local_unmirrored_tombstone(local_newer: bool) {
+ ensure_initialized();
+ fn apply_incoming_payload(engine: &LoginsSyncEngine, payload: serde_json::Value) {
+ let bso = IncomingBso::from_test_content(payload);
+ let mut telem = sync15::telemetry::Engine::new(engine.collection_name());
+ engine.stage_incoming(vec![bso], &mut telem).unwrap();
+ engine
+ .apply(ServerTimestamp::from_millis(0), &mut telem)
+ .unwrap();
+ }
+
+ // The test itself...
+ let (local_timestamp, remote_timestamp) = if local_newer { (123, 0) } else { (0, 123) };
+
+ let store = LoginStore::new_in_memory();
+ let engine = LoginsSyncEngine::new(Arc::new(store)).unwrap();
+
+ // apply an incoming record - will be in the mirror.
+ apply_incoming_payload(
+ &engine,
+ serde_json::json!({
+ "id": "dummy_000001",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "timePasswordChanged": local_timestamp,
+ "unknown1": "?",
+ "unknown2": {"sub": "object"},
+ }),
+ );
+
+ // Reset the engine - this wipes the mirror.
+ engine.reset(&EngineSyncAssociation::Disconnected).unwrap();
+ // But the local record does still exist.
+ assert!(engine
+ .store
+ .get("dummy_000001")
+ .expect("should work")
+ .is_some());
+
+ // Delete the local record.
+ engine.store.delete("dummy_000001").unwrap();
+ assert!(engine
+ .store
+ .get("dummy_000001")
+ .expect("should work")
+ .is_none());
+
+ // double-check our test preconditions - should now have 1 in LoginsL and 0 in LoginsM
+ assert_eq!(count(&engine, "LoginsL"), 1);
+ assert_eq!(count(&engine, "LoginsM"), 0);
+
+ // Now we assume we've been reconnected to sync and have an incoming change for the record.
+ apply_incoming_payload(
+ &engine,
+ serde_json::json!({
+ "id": "dummy_000001",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test2",
+ "timePasswordChanged": remote_timestamp,
+ "unknown1": "?",
+ "unknown2": {"sub": "object"},
+ }),
+ );
+
+ // Desktop semantics here are that a local tombstone is treated as though it doesn't exist at all.
+ // ie, the remote record should be taken whether it is newer or older than the tombstone.
+ assert!(engine
+ .store
+ .get("dummy_000001")
+ .expect("should work")
+ .is_some());
+ // and there should never be an outgoing record.
+ // XXX - but there is! But this is exceedingly rare, we
+ // should fix it :)
+ // assert_eq!(engine.fetch_outgoing().unwrap().len(), 0);
+
+ // should now be no records in loginsL and 1 in loginsM
+ assert_eq!(count(&engine, "LoginsL"), 0);
+ assert_eq!(count(&engine, "LoginsM"), 1);
+ }
+
+ #[test]
+ fn test_incoming_non_mirror_tombstone_local_newer() {
+ do_test_incoming_with_local_unmirrored_tombstone(true);
+ }
+
+ #[test]
+ fn test_incoming_non_mirror_tombstone_local_older() {
+ do_test_incoming_with_local_unmirrored_tombstone(false);
+ }
+}
diff --git a/third_party/rust/logins/src/sync/merge.rs b/third_party/rust/logins/src/sync/merge.rs
@@ -0,0 +1,432 @@
+/* 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/. */
+
+// Merging for Sync.
+use super::{IncomingLogin, LoginPayload};
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::login::EncryptedLogin;
+use crate::util;
+use rusqlite::Row;
+use std::time::SystemTime;
+use sync15::bso::{IncomingBso, IncomingKind};
+use sync15::ServerTimestamp;
+use sync_guid::Guid;
+
+#[derive(Clone, Debug)]
+pub(crate) struct MirrorLogin {
+ pub login: EncryptedLogin,
+ pub server_modified: ServerTimestamp,
+}
+
+impl MirrorLogin {
+ #[inline]
+ pub fn guid_str(&self) -> &str {
+ &self.login.meta.id
+ }
+
+ pub(crate) fn from_row(row: &Row<'_>) -> Result<MirrorLogin> {
+ Ok(MirrorLogin {
+ login: EncryptedLogin::from_row(row)?,
+ server_modified: ServerTimestamp(row.get::<_, i64>("server_modified")?),
+ })
+ }
+}
+#[derive(Clone, Debug)]
+pub(crate) enum LocalLogin {
+ Tombstone {
+ id: String,
+ local_modified: SystemTime,
+ },
+ Alive {
+ login: EncryptedLogin,
+ local_modified: SystemTime,
+ },
+}
+
+impl LocalLogin {
+ #[inline]
+ pub fn guid_str(&self) -> &str {
+ match &self {
+ LocalLogin::Tombstone { id, .. } => id.as_str(),
+ LocalLogin::Alive { login, .. } => login.guid_str(),
+ }
+ }
+
+ pub fn local_modified(&self) -> SystemTime {
+ match &self {
+ LocalLogin::Tombstone { local_modified, .. }
+ | LocalLogin::Alive { local_modified, .. } => *local_modified,
+ }
+ }
+
+ pub(crate) fn from_row(row: &Row<'_>) -> Result<LocalLogin> {
+ let local_modified = util::system_time_millis_from_row(row, "local_modified")?;
+ Ok(if row.get("is_deleted")? {
+ let id = row.get("guid")?;
+ LocalLogin::Tombstone { id, local_modified }
+ } else {
+ let login = EncryptedLogin::from_row(row)?;
+ if login.sec_fields.is_empty() {
+ error_support::report_error!("logins-crypto", "empty ciphertext in the db",);
+ }
+ LocalLogin::Alive {
+ login,
+ local_modified,
+ }
+ })
+ }
+
+ // Only used by tests where we want to get the "raw" record - ie, a tombstone will still
+ // be returned here, just with many otherwise invalid empty fields
+ #[cfg(not(feature = "keydb"))]
+ #[cfg(test)]
+ pub(crate) fn test_raw_from_row(row: &Row<'_>) -> Result<EncryptedLogin> {
+ EncryptedLogin::from_row(row)
+ }
+}
+
+macro_rules! impl_login {
+ ($ty:ty { $($fields:tt)* }) => {
+ impl AsRef<EncryptedLogin> for $ty {
+ #[inline]
+ fn as_ref(&self) -> &EncryptedLogin {
+ &self.login
+ }
+ }
+
+ impl AsMut<EncryptedLogin> for $ty {
+ #[inline]
+ fn as_mut(&mut self) -> &mut EncryptedLogin {
+ &mut self.login
+ }
+ }
+
+ impl From<$ty> for EncryptedLogin {
+ #[inline]
+ fn from(l: $ty) -> Self {
+ l.login
+ }
+ }
+
+ impl From<EncryptedLogin> for $ty {
+ #[inline]
+ fn from(login: EncryptedLogin) -> Self {
+ Self { login, $($fields)* }
+ }
+ }
+ };
+}
+
+impl_login!(MirrorLogin {
+ server_modified: ServerTimestamp(0)
+});
+
+// Stores data needed to do a 3-way merge
+#[derive(Debug)]
+pub(super) struct SyncLoginData {
+ pub guid: Guid,
+ pub local: Option<LocalLogin>,
+ pub mirror: Option<MirrorLogin>,
+ // None means it's a deletion
+ pub inbound: Option<IncomingLogin>,
+ pub inbound_ts: ServerTimestamp,
+}
+
+impl SyncLoginData {
+ #[inline]
+ pub fn guid_str(&self) -> &str {
+ self.guid.as_str()
+ }
+
+ #[inline]
+ pub fn guid(&self) -> &Guid {
+ &self.guid
+ }
+
+ pub fn from_bso(bso: IncomingBso, encdec: &dyn EncryptorDecryptor) -> Result<Self> {
+ let guid = bso.envelope.id.clone();
+ let inbound_ts = bso.envelope.modified;
+ let inbound = match bso.into_content::<LoginPayload>().kind {
+ IncomingKind::Content(p) => Some(IncomingLogin::from_incoming_payload(p, encdec)?),
+ IncomingKind::Tombstone => None,
+ // Before the IncomingKind refactor we returned an error. We could probably just
+ // treat it as a tombstone but should check that's sane, so for now, we also err.
+ IncomingKind::Malformed => return Err(Error::MalformedIncomingRecord),
+ };
+ Ok(Self {
+ guid,
+ local: None,
+ mirror: None,
+ inbound,
+ inbound_ts,
+ })
+ }
+}
+
+macro_rules! impl_login_setter {
+ ($setter_name:ident, $field:ident, $Login:ty) => {
+ impl SyncLoginData {
+ pub(crate) fn $setter_name(&mut self, record: $Login) -> Result<()> {
+ // TODO: We probably shouldn't panic in this function!
+ if self.$field.is_some() {
+ // Shouldn't be possible (only could happen if UNIQUE fails in sqlite, or if we
+ // get duplicate guids somewhere,but we check).
+ panic!(
+ "SyncLoginData::{} called on object that already has {} data",
+ stringify!($setter_name),
+ stringify!($field)
+ );
+ }
+
+ if self.guid_str() != record.guid_str() {
+ // This is almost certainly a bug in our code.
+ panic!(
+ "Wrong guid on login in {}: {:?} != {:?}",
+ stringify!($setter_name),
+ self.guid_str(),
+ record.guid_str()
+ );
+ }
+
+ self.$field = Some(record);
+ Ok(())
+ }
+ }
+ };
+}
+
+impl_login_setter!(set_local, local, LocalLogin);
+impl_login_setter!(set_mirror, mirror, MirrorLogin);
+
+#[derive(Debug, Default, Clone)]
+pub(crate) struct LoginDelta {
+ // "non-commutative" fields
+ pub origin: Option<String>,
+ pub password: Option<String>,
+ pub username: Option<String>,
+ pub http_realm: Option<String>,
+ pub form_action_origin: Option<String>,
+
+ pub time_created: Option<i64>,
+ pub time_last_used: Option<i64>,
+ pub time_password_changed: Option<i64>,
+
+ // "non-conflicting" fields (which are the same)
+ pub password_field: Option<String>,
+ pub username_field: Option<String>,
+
+ // Commutative field
+ pub times_used: i64,
+}
+
+macro_rules! merge_field {
+ ($merged:ident, $b:ident, $prefer_b:expr, $field:ident) => {
+ if let Some($field) = $b.$field.take() {
+ if $merged.$field.is_some() {
+ warn!("Collision merging login field {}", stringify!($field));
+ if $prefer_b {
+ $merged.$field = Some($field);
+ }
+ } else {
+ $merged.$field = Some($field);
+ }
+ }
+ };
+}
+
+impl LoginDelta {
+ #[allow(clippy::cognitive_complexity)] // Looks like clippy considers this after macro-expansion...
+ pub fn merge(self, mut b: LoginDelta, b_is_newer: bool) -> LoginDelta {
+ let mut merged = self;
+ merge_field!(merged, b, b_is_newer, origin);
+ merge_field!(merged, b, b_is_newer, password);
+ merge_field!(merged, b, b_is_newer, username);
+ merge_field!(merged, b, b_is_newer, http_realm);
+ merge_field!(merged, b, b_is_newer, form_action_origin);
+
+ merge_field!(merged, b, b_is_newer, time_created);
+ merge_field!(merged, b, b_is_newer, time_last_used);
+ merge_field!(merged, b, b_is_newer, time_password_changed);
+
+ merge_field!(merged, b, b_is_newer, password_field);
+ merge_field!(merged, b, b_is_newer, username_field);
+
+ // commutative fields
+ merged.times_used += b.times_used;
+
+ merged
+ }
+}
+
+macro_rules! apply_field {
+ ($login:ident, $delta:ident, $field:ident) => {
+ if let Some($field) = $delta.$field.take() {
+ $login.fields.$field = $field.into();
+ }
+ };
+}
+
+macro_rules! apply_metadata_field {
+ ($login:ident, $delta:ident, $field:ident) => {
+ if let Some($field) = $delta.$field.take() {
+ $login.meta.$field = $field.into();
+ }
+ };
+}
+
+impl EncryptedLogin {
+ pub(crate) fn apply_delta(
+ &mut self,
+ mut delta: LoginDelta,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<()> {
+ apply_field!(self, delta, origin);
+
+ apply_metadata_field!(self, delta, time_created);
+ apply_metadata_field!(self, delta, time_last_used);
+ apply_metadata_field!(self, delta, time_password_changed);
+
+ apply_field!(self, delta, password_field);
+ apply_field!(self, delta, username_field);
+
+ let mut sec_fields = self.decrypt_fields(encdec)?;
+ if let Some(password) = delta.password.take() {
+ sec_fields.password = password;
+ }
+ if let Some(username) = delta.username.take() {
+ sec_fields.username = username;
+ }
+ self.sec_fields = sec_fields.encrypt(encdec, &self.meta.id)?;
+
+ // Use Some("") to indicate that it should be changed to be None (hacky...)
+ if let Some(realm) = delta.http_realm.take() {
+ self.fields.http_realm = if realm.is_empty() { None } else { Some(realm) };
+ }
+
+ if let Some(url) = delta.form_action_origin.take() {
+ self.fields.form_action_origin = if url.is_empty() { None } else { Some(url) };
+ }
+
+ self.meta.times_used += delta.times_used;
+ Ok(())
+ }
+
+ pub(crate) fn delta(
+ &self,
+ older: &EncryptedLogin,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<LoginDelta> {
+ let mut delta = LoginDelta::default();
+
+ if self.fields.form_action_origin != older.fields.form_action_origin {
+ delta.form_action_origin =
+ Some(self.fields.form_action_origin.clone().unwrap_or_default());
+ }
+
+ if self.fields.http_realm != older.fields.http_realm {
+ delta.http_realm = Some(self.fields.http_realm.clone().unwrap_or_default());
+ }
+
+ if self.fields.origin != older.fields.origin {
+ delta.origin = Some(self.fields.origin.clone());
+ }
+ let older_sec_fields = older.decrypt_fields(encdec)?;
+ let self_sec_fields = self.decrypt_fields(encdec)?;
+ if self_sec_fields.username != older_sec_fields.username {
+ delta.username = Some(self_sec_fields.username.clone());
+ }
+ if self_sec_fields.password != older_sec_fields.password {
+ delta.password = Some(self_sec_fields.password);
+ }
+ if self.fields.password_field != older.fields.password_field {
+ delta.password_field = Some(self.fields.password_field.clone());
+ }
+ if self.fields.username_field != older.fields.username_field {
+ delta.username_field = Some(self.fields.username_field.clone());
+ }
+
+ // We discard zero (and negative numbers) for timestamps so that a
+ // record that doesn't contain this information (these are
+ // `#[serde(default)]`) doesn't skew our records.
+ //
+ // Arguably, we should also also ignore values later than our
+ // `time_created`, or earlier than our `time_last_used` or
+ // `time_password_changed`. Doing this properly would probably require
+ // a scheme analogous to Desktop's weak-reupload system, so I'm punting
+ // on it for now.
+ if self.meta.time_created > 0 && self.meta.time_created != older.meta.time_created {
+ delta.time_created = Some(self.meta.time_created);
+ }
+ if self.meta.time_last_used > 0 && self.meta.time_last_used != older.meta.time_last_used {
+ delta.time_last_used = Some(self.meta.time_last_used);
+ }
+ if self.meta.time_password_changed > 0
+ && self.meta.time_password_changed != older.meta.time_password_changed
+ {
+ delta.time_password_changed = Some(self.meta.time_password_changed);
+ }
+
+ if self.meta.times_used > 0 && self.meta.times_used != older.meta.times_used {
+ delta.times_used = self.meta.times_used - older.meta.times_used;
+ }
+
+ Ok(delta)
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn test_invalid_payload_timestamps() {
+ ensure_initialized();
+ #[allow(clippy::unreadable_literal)]
+ let bad_timestamp = 18446732429235952000u64;
+ let bad_payload = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "timeCreated": bad_timestamp,
+ "timeLastUsed": "some other garbage",
+ "timePasswordChanged": -30, // valid i64 but negative
+ }));
+ let login = SyncLoginData::from_bso(bad_payload, &*TEST_ENCDEC)
+ .unwrap()
+ .inbound
+ .unwrap()
+ .login;
+ assert_eq!(login.meta.time_created, 0);
+ assert_eq!(login.meta.time_last_used, 0);
+ assert_eq!(login.meta.time_password_changed, 0);
+
+ let now64 = util::system_time_ms_i64(std::time::SystemTime::now());
+ let good_payload = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "formSubmitURL": "https://www.example.com/submit",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "timeCreated": now64 - 100,
+ "timeLastUsed": now64 - 50,
+ "timePasswordChanged": now64 - 25,
+ }));
+
+ let login = SyncLoginData::from_bso(good_payload, &*TEST_ENCDEC)
+ .unwrap()
+ .inbound
+ .unwrap()
+ .login;
+
+ assert_eq!(login.meta.time_created, now64 - 100);
+ assert_eq!(login.meta.time_last_used, now64 - 50);
+ assert_eq!(login.meta.time_password_changed, now64 - 25);
+ }
+}
diff --git a/third_party/rust/logins/src/sync/mod.rs b/third_party/rust/logins/src/sync/mod.rs
@@ -0,0 +1,19 @@
+/* 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/. */
+
+mod engine;
+pub(crate) mod merge;
+mod payload;
+mod update_plan;
+
+pub use engine::LoginsSyncEngine;
+use payload::{IncomingLogin, LoginPayload};
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[repr(u8)]
+pub(crate) enum SyncStatus {
+ Synced = 0,
+ Changed = 1,
+ New = 2,
+}
diff --git a/third_party/rust/logins/src/sync/payload.rs b/third_party/rust/logins/src/sync/payload.rs
@@ -0,0 +1,436 @@
+/* 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/. */
+
+// Login entry from a server payload
+//
+// This struct is used for fetching/sending login records to the server. There are a number
+// of differences between this and the top-level Login struct; some fields are renamed, some are
+// locally encrypted, etc.
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::login::ValidateAndFixup;
+use crate::SecureLoginFields;
+use crate::{EncryptedLogin, LoginEntry, LoginFields, LoginMeta};
+use serde_derive::*;
+use sync15::bso::OutgoingBso;
+use sync_guid::Guid;
+
+type UnknownFields = serde_json::Map<String, serde_json::Value>;
+
+trait UnknownFieldsExt {
+ fn encrypt(&self, encdec: &dyn EncryptorDecryptor) -> Result<String>;
+ fn decrypt(ciphertext: &str, encdec: &dyn EncryptorDecryptor) -> Result<Self>
+ where
+ Self: Sized;
+}
+
+impl UnknownFieldsExt for UnknownFields {
+ fn encrypt(&self, encdec: &dyn EncryptorDecryptor) -> Result<String> {
+ let string = serde_json::to_string(&self)?;
+ let cipherbytes = encdec
+ .encrypt(string.as_bytes().into())
+ .map_err(|e| Error::EncryptionFailed(e.to_string()))?;
+ let ciphertext = std::str::from_utf8(&cipherbytes)
+ .map_err(|e| Error::EncryptionFailed(e.to_string()))?;
+ Ok(ciphertext.to_owned())
+ }
+
+ fn decrypt(ciphertext: &str, encdec: &dyn EncryptorDecryptor) -> Result<Self> {
+ let jsonbytes = encdec
+ .decrypt(ciphertext.as_bytes().into())
+ .map_err(|e| Error::DecryptionFailed(e.to_string()))?;
+ let json =
+ std::str::from_utf8(&jsonbytes).map_err(|e| Error::DecryptionFailed(e.to_string()))?;
+ Ok(serde_json::from_str(json)?)
+ }
+}
+
+/// What we get from the server after parsing the payload. We need to round-trip "unknown"
+/// fields, but don't want to carry them around in `EncryptedLogin`.
+#[derive(Debug)]
+pub(super) struct IncomingLogin {
+ pub login: EncryptedLogin,
+ // An encrypted UnknownFields, or None if there are none.
+ pub unknown: Option<String>,
+}
+
+impl IncomingLogin {
+ pub fn guid(&self) -> Guid {
+ self.login.guid()
+ }
+
+ pub(super) fn from_incoming_payload(
+ p: LoginPayload,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<Self> {
+ let original_fields = LoginFields {
+ origin: p.hostname,
+ form_action_origin: p.form_submit_url,
+ http_realm: p.http_realm,
+ username_field: p.username_field,
+ password_field: p.password_field,
+ };
+ let original_sec_fields = SecureLoginFields {
+ username: p.username,
+ password: p.password,
+ };
+ // we do a bit of a dance here to maybe_fixup() the fields via LoginEntry
+ let original_login_entry = LoginEntry::new(original_fields, original_sec_fields);
+ let login_entry = original_login_entry
+ .maybe_fixup()?
+ .unwrap_or(original_login_entry);
+ let fields = LoginFields {
+ origin: login_entry.origin,
+ form_action_origin: login_entry.form_action_origin,
+ http_realm: login_entry.http_realm,
+ username_field: login_entry.username_field,
+ password_field: login_entry.password_field,
+ };
+ let id = String::from(p.guid);
+ let sec_fields = SecureLoginFields {
+ username: login_entry.username,
+ password: login_entry.password,
+ }
+ .encrypt(encdec, &id)?;
+
+ // We handle NULL in the DB for migrated databases and it's wasteful
+ // to encrypt the common case of an empty map, so...
+ let unknown = if p.unknown_fields.is_empty() {
+ None
+ } else {
+ Some(p.unknown_fields.encrypt(encdec)?)
+ };
+
+ // If we can't fix the parts we keep the invalid bits.
+ Ok(Self {
+ login: EncryptedLogin {
+ meta: LoginMeta {
+ id,
+ time_created: p.time_created,
+ time_password_changed: p.time_password_changed,
+ time_last_used: p.time_last_used,
+ times_used: p.times_used,
+ },
+ fields,
+ sec_fields,
+ },
+ unknown,
+ })
+ }
+}
+
+/// The JSON payload that lives on the storage servers.
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+#[serde(rename_all = "camelCase")]
+pub struct LoginPayload {
+ #[serde(rename = "id")]
+ pub guid: Guid,
+
+ // This is 'origin' in our Login struct.
+ pub hostname: String,
+
+ // This is 'form_action_origin' in our Login struct.
+ // rename_all = "camelCase" by default will do formSubmitUrl, but we can just
+ // override this one field.
+ #[serde(rename = "formSubmitURL")]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub form_submit_url: Option<String>,
+
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub http_realm: Option<String>,
+
+ #[serde(default)]
+ pub username: String,
+
+ pub password: String,
+
+ #[serde(default)]
+ pub username_field: String,
+
+ #[serde(default)]
+ pub password_field: String,
+
+ #[serde(default)]
+ #[serde(deserialize_with = "deserialize_timestamp")]
+ pub time_created: i64,
+
+ #[serde(default)]
+ #[serde(deserialize_with = "deserialize_timestamp")]
+ pub time_password_changed: i64,
+
+ #[serde(default)]
+ #[serde(deserialize_with = "deserialize_timestamp")]
+ pub time_last_used: i64,
+
+ #[serde(default)]
+ pub times_used: i64,
+
+ // Additional "unknown" round-tripped fields.
+ #[serde(flatten)]
+ unknown_fields: UnknownFields,
+}
+
+// These probably should be on the payload itself, but one refactor at a time!
+impl EncryptedLogin {
+ pub fn into_bso(
+ self,
+ encdec: &dyn EncryptorDecryptor,
+ enc_unknown_fields: Option<String>,
+ ) -> Result<OutgoingBso> {
+ let unknown_fields = match enc_unknown_fields {
+ Some(s) => UnknownFields::decrypt(&s, encdec)?,
+ None => Default::default(),
+ };
+ let sec_fields = SecureLoginFields::decrypt(&self.sec_fields, encdec, &self.meta.id)?;
+ Ok(OutgoingBso::from_content_with_id(
+ crate::sync::LoginPayload {
+ guid: self.guid(),
+ hostname: self.fields.origin,
+ form_submit_url: self.fields.form_action_origin,
+ http_realm: self.fields.http_realm,
+ username_field: self.fields.username_field,
+ password_field: self.fields.password_field,
+ username: sec_fields.username,
+ password: sec_fields.password,
+ time_created: self.meta.time_created,
+ time_password_changed: self.meta.time_password_changed,
+ time_last_used: self.meta.time_last_used,
+ times_used: self.meta.times_used,
+ unknown_fields,
+ },
+ )?)
+ }
+}
+
+// Quiet clippy, since this function is passed to deserialiaze_with...
+#[allow(clippy::unnecessary_wraps)]
+fn deserialize_timestamp<'de, D>(deserializer: D) -> std::result::Result<i64, D::Error>
+where
+ D: serde::de::Deserializer<'de>,
+{
+ use serde::de::Deserialize;
+ // Invalid and negative timestamps are all replaced with 0. Eventually we
+ // should investigate replacing values that are unreasonable but still fit
+ // in an i64 (a date 1000 years in the future, for example), but
+ // appropriately handling that is complex.
+ Ok(i64::deserialize(deserializer).unwrap_or_default().max(0))
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::encryption::test_utils::{encrypt_struct, TEST_ENCDEC};
+ use crate::sync::merge::SyncLoginData;
+ use crate::{EncryptedLogin, LoginFields, LoginMeta, SecureLoginFields};
+ use sync15::bso::IncomingBso;
+
+ #[test]
+ fn test_payload_to_login() {
+ let bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "httpRealm": "test",
+ "hostname": "https://www.example.com",
+ "username": "user",
+ "password": "password",
+ }));
+ let login = IncomingLogin::from_incoming_payload(
+ bso.into_content::<LoginPayload>().content().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap()
+ .login;
+ assert_eq!(login.meta.id, "123412341234");
+ assert_eq!(login.fields.http_realm, Some("test".to_string()));
+ assert_eq!(login.fields.origin, "https://www.example.com");
+ assert_eq!(login.fields.form_action_origin, None);
+ let sec_fields = login.decrypt_fields(&*TEST_ENCDEC).unwrap();
+ assert_eq!(sec_fields.username, "user");
+ assert_eq!(sec_fields.password, "password");
+ }
+
+ // formSubmitURL (now formActionOrigin) being an empty string is a valid
+ // legacy case that is supported on desktop, we should ensure we are as well
+ // https://searchfox.org/mozilla-central/rev/32c74afbb24dce4b5dd6b33be71197e615631d71/toolkit/components/passwordmgr/test/unit/test_logins_change.js#183-184
+ #[test]
+ fn test_payload_empty_form_action_to_login() {
+ let bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "formSubmitURL": "",
+ "hostname": "https://www.example.com",
+ "username": "user",
+ "password": "password",
+ }));
+ let login = IncomingLogin::from_incoming_payload(
+ bso.into_content::<LoginPayload>().content().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap()
+ .login;
+ assert_eq!(login.meta.id, "123412341234");
+ assert_eq!(login.fields.form_action_origin, Some("".to_string()));
+ assert_eq!(login.fields.http_realm, None);
+ assert_eq!(login.fields.origin, "https://www.example.com");
+ let sec_fields = login.decrypt_fields(&*TEST_ENCDEC).unwrap();
+ assert_eq!(sec_fields.username, "user");
+ assert_eq!(sec_fields.password, "password");
+
+ let bso = login.into_bso(&*TEST_ENCDEC, None).unwrap();
+ assert_eq!(bso.envelope.id, "123412341234");
+ let payload_data: serde_json::Value = serde_json::from_str(&bso.payload).unwrap();
+ assert_eq!(payload_data["httpRealm"], serde_json::Value::Null);
+ assert_eq!(payload_data["formSubmitURL"], "".to_string());
+ }
+
+ #[test]
+ fn test_payload_unknown_fields() {
+ // No "unknown" fields.
+ let bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "httpRealm": "test",
+ "hostname": "https://www.example.com",
+ "username": "user",
+ "password": "password",
+ }));
+ let payload = bso.into_content::<LoginPayload>().content().unwrap();
+ assert!(payload.unknown_fields.is_empty());
+
+ // An unknown "foo"
+ let bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "httpRealm": "test",
+ "hostname": "https://www.example.com",
+ "username": "user",
+ "password": "password",
+ "foo": "bar",
+ }));
+ let payload = bso.into_content::<LoginPayload>().content().unwrap();
+ assert_eq!(payload.unknown_fields.len(), 1);
+ assert_eq!(
+ payload.unknown_fields.get("foo").unwrap().as_str().unwrap(),
+ "bar"
+ );
+ // re-serialize it.
+ let unknown = Some(encrypt_struct::<UnknownFields>(&payload.unknown_fields));
+ let login = IncomingLogin::from_incoming_payload(payload, &*TEST_ENCDEC)
+ .unwrap()
+ .login;
+ // The raw outgoing payload should have it back.
+ let outgoing = login.into_bso(&*TEST_ENCDEC, unknown).unwrap();
+ let json =
+ serde_json::from_str::<serde_json::Map<String, serde_json::Value>>(&outgoing.payload)
+ .unwrap();
+ assert_eq!(json.get("foo").unwrap().as_str().unwrap(), "bar");
+ }
+
+ #[test]
+ fn test_form_submit_payload_to_login() {
+ let bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "hostname": "https://www.example.com",
+ "formSubmitURL": "https://www.example.com",
+ "usernameField": "username-field",
+ "username": "user",
+ "password": "password",
+ }));
+ let login = IncomingLogin::from_incoming_payload(
+ bso.into_content::<LoginPayload>().content().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap()
+ .login;
+ assert_eq!(login.meta.id, "123412341234");
+ assert_eq!(login.fields.http_realm, None);
+ assert_eq!(login.fields.origin, "https://www.example.com");
+ assert_eq!(
+ login.fields.form_action_origin,
+ Some("https://www.example.com".to_string())
+ );
+ assert_eq!(login.fields.username_field, "username-field");
+ let sec_fields = login.decrypt_fields(&*TEST_ENCDEC).unwrap();
+ assert_eq!(sec_fields.username, "user");
+ assert_eq!(sec_fields.password, "password");
+ }
+
+ #[test]
+ fn test_login_into_payload() {
+ let login = EncryptedLogin {
+ meta: LoginMeta {
+ id: "123412341234".into(),
+ ..Default::default()
+ },
+ fields: LoginFields {
+ http_realm: Some("test".into()),
+ origin: "https://www.example.com".into(),
+ ..Default::default()
+ },
+ sec_fields: encrypt_struct(&SecureLoginFields {
+ username: "user".into(),
+ password: "password".into(),
+ }),
+ };
+ let bso = login.into_bso(&*TEST_ENCDEC, None).unwrap();
+ assert_eq!(bso.envelope.id, "123412341234");
+ let payload_data: serde_json::Value = serde_json::from_str(&bso.payload).unwrap();
+ assert_eq!(payload_data["httpRealm"], "test".to_string());
+ assert_eq!(payload_data["hostname"], "https://www.example.com");
+ assert_eq!(payload_data["username"], "user");
+ assert_eq!(payload_data["password"], "password");
+ assert!(matches!(
+ payload_data["formActionOrigin"],
+ serde_json::Value::Null
+ ));
+ }
+
+ #[test]
+ fn test_username_field_requires_a_form_target() {
+ let bad_json = serde_json::json!({
+ "id": "123412341234",
+ "httpRealm": "test",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "usernameField": "invalid"
+ });
+ let bad_bso = IncomingBso::from_test_content(bad_json.clone());
+
+ // Incoming sync data gets fixed automatically.
+ let login = IncomingLogin::from_incoming_payload(
+ bad_bso.into_content::<LoginPayload>().content().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap()
+ .login;
+ assert_eq!(login.fields.username_field, "");
+
+ // SyncLoginData::from_payload also fixes up.
+ let bad_bso = IncomingBso::from_test_content(bad_json);
+ let login = SyncLoginData::from_bso(bad_bso, &*TEST_ENCDEC)
+ .unwrap()
+ .inbound
+ .unwrap()
+ .login;
+ assert_eq!(login.fields.username_field, "");
+ }
+
+ #[test]
+ fn test_password_field_requires_a_form_target() {
+ let bad_bso = IncomingBso::from_test_content(serde_json::json!({
+ "id": "123412341234",
+ "httpRealm": "test",
+ "hostname": "https://www.example.com",
+ "username": "test",
+ "password": "test",
+ "passwordField": "invalid"
+ }));
+
+ let login = IncomingLogin::from_incoming_payload(
+ bad_bso.into_content::<LoginPayload>().content().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap()
+ .login;
+ assert_eq!(login.fields.password_field, "");
+ }
+}
diff --git a/third_party/rust/logins/src/sync/update_plan.rs b/third_party/rust/logins/src/sync/update_plan.rs
@@ -0,0 +1,653 @@
+/* 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 super::merge::{LocalLogin, MirrorLogin};
+use super::{IncomingLogin, SyncStatus};
+use crate::encryption::EncryptorDecryptor;
+use crate::error::*;
+use crate::util;
+use interrupt_support::SqlInterruptScope;
+use rusqlite::{named_params, Connection};
+use std::time::SystemTime;
+use sync15::ServerTimestamp;
+use sync_guid::Guid;
+
+#[derive(Default, Debug)]
+pub(super) struct UpdatePlan {
+ pub delete_mirror: Vec<Guid>,
+ pub delete_local: Vec<Guid>,
+ pub local_updates: Vec<MirrorLogin>,
+ // the bool is the `is_overridden` flag, the i64 is ServerTimestamp in millis
+ pub mirror_inserts: Vec<(IncomingLogin, i64, bool)>,
+ pub mirror_updates: Vec<(IncomingLogin, i64)>,
+}
+
+impl UpdatePlan {
+ pub fn plan_two_way_merge(
+ &mut self,
+ local: LocalLogin,
+ upstream: (IncomingLogin, ServerTimestamp),
+ ) {
+ match &local {
+ LocalLogin::Tombstone { .. } => {
+ debug!(" ignoring local tombstone, inserting into mirror");
+ self.delete_local.push(upstream.0.guid());
+ self.plan_mirror_insert(upstream.0, upstream.1, false);
+ }
+ LocalLogin::Alive { login, .. } => {
+ debug!(" Conflicting record without shared parent, using newer");
+ let is_override =
+ login.meta.time_password_changed > upstream.0.login.meta.time_password_changed;
+ self.plan_mirror_insert(upstream.0, upstream.1, is_override);
+ if !is_override {
+ self.delete_local.push(login.guid());
+ }
+ }
+ }
+ }
+
+ pub fn plan_three_way_merge(
+ &mut self,
+ local: LocalLogin,
+ shared: MirrorLogin,
+ upstream: IncomingLogin,
+ upstream_time: ServerTimestamp,
+ server_now: ServerTimestamp,
+ encdec: &dyn EncryptorDecryptor,
+ ) -> Result<()> {
+ let local_age = SystemTime::now()
+ .duration_since(local.local_modified())
+ .unwrap_or_default();
+ let remote_age = server_now.duration_since(upstream_time).unwrap_or_default();
+
+ let delta = {
+ let upstream_delta = upstream.login.delta(&shared.login, encdec)?;
+ match local {
+ LocalLogin::Tombstone { .. } => {
+ // If the login was deleted locally, the merged delta is the
+ // upstream delta. We do this because a user simultaneously deleting their
+ // login and updating it has two possible outcomes:
+ // - A login that was intended to be deleted remains because another update was
+ // there
+ // - A login that was intended to be updated got deleted
+ //
+ // The second case is arguably worse, where a user could lose their login
+ // indefinitely
+ // So, just like desktop, this acts as though the local login doesn't exist at all.
+ upstream_delta
+ }
+ LocalLogin::Alive { login, .. } => {
+ let local_delta = login.delta(&shared.login, encdec)?;
+ local_delta.merge(upstream_delta, remote_age < local_age)
+ }
+ }
+ };
+
+ // Update mirror to upstream
+ self.mirror_updates
+ .push((upstream, upstream_time.as_millis()));
+ let mut new = shared;
+
+ new.login.apply_delta(delta, encdec)?;
+ new.server_modified = upstream_time;
+ self.local_updates.push(new);
+ Ok(())
+ }
+
+ pub fn plan_delete(&mut self, id: Guid) {
+ self.delete_local.push(id.clone());
+ self.delete_mirror.push(id);
+ }
+
+ pub fn plan_mirror_update(&mut self, upstream: IncomingLogin, time: ServerTimestamp) {
+ self.mirror_updates.push((upstream, time.as_millis()));
+ }
+
+ pub fn plan_mirror_insert(
+ &mut self,
+ upstream: IncomingLogin,
+ time: ServerTimestamp,
+ is_override: bool,
+ ) {
+ self.mirror_inserts
+ .push((upstream, time.as_millis(), is_override));
+ }
+
+ fn perform_deletes(&self, conn: &Connection, scope: &SqlInterruptScope) -> Result<()> {
+ sql_support::each_chunk(&self.delete_local, |chunk, _| -> Result<()> {
+ conn.execute(
+ &format!(
+ "DELETE FROM loginsL WHERE guid IN ({vars})",
+ vars = sql_support::repeat_sql_vars(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ scope.err_if_interrupted()?;
+ Ok(())
+ })?;
+
+ sql_support::each_chunk(&self.delete_mirror, |chunk, _| {
+ conn.execute(
+ &format!(
+ "DELETE FROM loginsM WHERE guid IN ({vars})",
+ vars = sql_support::repeat_sql_vars(chunk.len())
+ ),
+ rusqlite::params_from_iter(chunk),
+ )?;
+ Ok(())
+ })
+ }
+
+ // These aren't batched but probably should be.
+ fn perform_mirror_updates(&self, conn: &Connection, scope: &SqlInterruptScope) -> Result<()> {
+ let sql = "
+ UPDATE loginsM
+ SET server_modified = :server_modified,
+ enc_unknown_fields = :enc_unknown_fields,
+ httpRealm = :http_realm,
+ formActionOrigin = :form_action_origin,
+ usernameField = :username_field,
+ passwordField = :password_field,
+ origin = :origin,
+ secFields = :sec_fields,
+ -- Avoid zeroes if the remote has been overwritten by an older client.
+ timesUsed = coalesce(nullif(:times_used, 0), timesUsed),
+ timeLastUsed = coalesce(nullif(:time_last_used, 0), timeLastUsed),
+ timePasswordChanged = coalesce(nullif(:time_password_changed, 0), timePasswordChanged),
+ timeCreated = coalesce(nullif(:time_created, 0), timeCreated)
+ WHERE guid = :guid
+ ";
+ let mut stmt = conn.prepare_cached(sql)?;
+ for (upstream, timestamp) in &self.mirror_updates {
+ let login = &upstream.login;
+ trace!("Updating mirror {:?}", login.guid_str());
+ stmt.execute(named_params! {
+ ":server_modified": *timestamp,
+ ":enc_unknown_fields": upstream.unknown,
+ ":http_realm": login.fields.http_realm,
+ ":form_action_origin": login.fields.form_action_origin,
+ ":username_field": login.fields.username_field,
+ ":password_field": login.fields.password_field,
+ ":origin": login.fields.origin,
+ ":times_used": login.meta.times_used,
+ ":time_last_used": login.meta.time_last_used,
+ ":time_password_changed": login.meta.time_password_changed,
+ ":time_created": login.meta.time_created,
+ ":guid": login.guid_str(),
+ ":sec_fields": login.sec_fields,
+ })?;
+ scope.err_if_interrupted()?;
+ }
+ Ok(())
+ }
+
+ fn perform_mirror_inserts(&self, conn: &Connection, scope: &SqlInterruptScope) -> Result<()> {
+ let sql = "
+ INSERT OR IGNORE INTO loginsM (
+ is_overridden,
+ server_modified,
+ enc_unknown_fields,
+
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ origin,
+ secFields,
+
+ timesUsed,
+ timeLastUsed,
+ timePasswordChanged,
+ timeCreated,
+
+ guid
+ ) VALUES (
+ :is_overridden,
+ :server_modified,
+ :enc_unknown_fields,
+
+ :http_realm,
+ :form_action_origin,
+ :username_field,
+ :password_field,
+ :origin,
+ :sec_fields,
+
+ :times_used,
+ :time_last_used,
+ :time_password_changed,
+ :time_created,
+
+ :guid
+ )";
+ let mut stmt = conn.prepare_cached(sql)?;
+
+ for (upstream, timestamp, is_overridden) in &self.mirror_inserts {
+ let login = &upstream.login;
+ trace!("Inserting mirror {:?}", login.guid_str());
+ stmt.execute(named_params! {
+ ":is_overridden": *is_overridden,
+ ":server_modified": *timestamp,
+ ":enc_unknown_fields": upstream.unknown,
+ ":http_realm": login.fields.http_realm,
+ ":form_action_origin": login.fields.form_action_origin,
+ ":username_field": login.fields.username_field,
+ ":password_field": login.fields.password_field,
+ ":origin": login.fields.origin,
+ ":times_used": login.meta.times_used,
+ ":time_last_used": login.meta.time_last_used,
+ ":time_password_changed": login.meta.time_password_changed,
+ ":time_created": login.meta.time_created,
+ ":guid": login.guid_str(),
+ ":sec_fields": login.sec_fields,
+ })?;
+ scope.err_if_interrupted()?;
+ }
+ Ok(())
+ }
+
+ fn perform_local_updates(&self, conn: &Connection, scope: &SqlInterruptScope) -> Result<()> {
+ let sql = format!(
+ "UPDATE loginsL
+ SET local_modified = :local_modified,
+ httpRealm = :http_realm,
+ formActionOrigin = :form_action_origin,
+ usernameField = :username_field,
+ passwordField = :password_field,
+ timeLastUsed = :time_last_used,
+ timePasswordChanged = :time_password_changed,
+ timesUsed = :times_used,
+ origin = :origin,
+ secFields = :sec_fields,
+ sync_status = {changed},
+ is_deleted = 0
+ WHERE guid = :guid",
+ changed = SyncStatus::Changed as u8
+ );
+ let mut stmt = conn.prepare_cached(&sql)?;
+ // XXX OutgoingChangeset should no longer have timestamp.
+ let local_ms: i64 = util::system_time_ms_i64(SystemTime::now());
+ for l in &self.local_updates {
+ trace!("Updating local {:?}", l.guid_str());
+ stmt.execute(named_params! {
+ ":local_modified": local_ms,
+ ":http_realm": l.login.fields.http_realm,
+ ":form_action_origin": l.login.fields.form_action_origin,
+ ":username_field": l.login.fields.username_field,
+ ":password_field": l.login.fields.password_field,
+ ":origin": l.login.fields.origin,
+ ":time_last_used": l.login.meta.time_last_used,
+ ":time_password_changed": l.login.meta.time_password_changed,
+ ":times_used": l.login.meta.times_used,
+ ":guid": l.guid_str(),
+ ":sec_fields": l.login.sec_fields,
+ })?;
+ scope.err_if_interrupted()?;
+ }
+ Ok(())
+ }
+
+ pub fn execute(&self, conn: &Connection, scope: &SqlInterruptScope) -> Result<()> {
+ debug!(
+ "UpdatePlan: deleting {} records...",
+ self.delete_local.len()
+ );
+ self.perform_deletes(conn, scope)?;
+ debug!(
+ "UpdatePlan: Updating {} existing mirror records...",
+ self.mirror_updates.len()
+ );
+ self.perform_mirror_updates(conn, scope)?;
+ debug!(
+ "UpdatePlan: Inserting {} new mirror records...",
+ self.mirror_inserts.len()
+ );
+ self.perform_mirror_inserts(conn, scope)?;
+ debug!(
+ "UpdatePlan: Updating {} reconciled local records...",
+ self.local_updates.len()
+ );
+ self.perform_local_updates(conn, scope)?;
+ Ok(())
+ }
+}
+
+#[cfg(not(feature = "keydb"))]
+#[cfg(test)]
+mod tests {
+ use nss::ensure_initialized;
+ use std::time::Duration;
+
+ use super::*;
+ use crate::db::test_utils::{
+ check_local_login, check_mirror_login, get_local_guids, get_mirror_guids,
+ get_server_modified, insert_encrypted_login, insert_login,
+ };
+ use crate::db::LoginDb;
+ use crate::encryption::test_utils::TEST_ENCDEC;
+ use crate::login::test_utils::enc_login;
+
+ fn inc_login(id: &str, password: &str) -> crate::sync::IncomingLogin {
+ IncomingLogin {
+ login: enc_login(id, password),
+ unknown: Default::default(),
+ }
+ }
+
+ #[test]
+ fn test_deletes() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ insert_login(&db, "login1", Some("password"), Some("password"));
+ insert_login(&db, "login2", Some("password"), Some("password"));
+ insert_login(&db, "login3", Some("password"), Some("password"));
+ insert_login(&db, "login4", Some("password"), Some("password"));
+
+ UpdatePlan {
+ delete_mirror: vec![Guid::new("login1"), Guid::new("login2")],
+ delete_local: vec![Guid::new("login2"), Guid::new("login3")],
+ ..UpdatePlan::default()
+ }
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+
+ assert_eq!(get_local_guids(&db), vec!["login1", "login4"]);
+ assert_eq!(get_mirror_guids(&db), vec!["login3", "login4"]);
+ }
+
+ #[test]
+ fn test_mirror_updates() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ insert_login(&db, "unchanged", None, Some("password"));
+ insert_login(&db, "changed", None, Some("password"));
+ insert_login(
+ &db,
+ "changed2",
+ Some("new-local-password"),
+ Some("password"),
+ );
+ let initial_modified = get_server_modified(&db, "unchanged");
+
+ UpdatePlan {
+ mirror_updates: vec![
+ (inc_login("changed", "new-password"), 20000),
+ (inc_login("changed2", "new-password2"), 21000),
+ ],
+ ..UpdatePlan::default()
+ }
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+ check_mirror_login(&db, "unchanged", "password", initial_modified, false);
+ check_mirror_login(&db, "changed", "new-password", 20000, false);
+ check_mirror_login(&db, "changed2", "new-password2", 21000, true);
+ }
+
+ #[test]
+ fn test_mirror_inserts() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ UpdatePlan {
+ mirror_inserts: vec![
+ (inc_login("login1", "new-password"), 20000, false),
+ (inc_login("login2", "new-password2"), 21000, true),
+ ],
+ ..UpdatePlan::default()
+ }
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+ check_mirror_login(&db, "login1", "new-password", 20000, false);
+ check_mirror_login(&db, "login2", "new-password2", 21000, true);
+ }
+
+ #[test]
+ fn test_local_updates() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ insert_login(&db, "login", Some("password"), Some("password"));
+ let before_update = util::system_time_ms_i64(SystemTime::now());
+
+ UpdatePlan {
+ local_updates: vec![MirrorLogin {
+ login: enc_login("login", "new-password"),
+ server_modified: ServerTimestamp(10000),
+ }],
+ ..UpdatePlan::default()
+ }
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+ check_local_login(&db, "login", "new-password", before_update);
+ }
+
+ #[test]
+ fn test_plan_three_way_merge_server_wins() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ // First we create our expected logins
+ let login = enc_login("login", "old local password");
+ let mirror_login = enc_login("login", "mirror password");
+ let server_login = enc_login("login", "new upstream password");
+
+ // Then, we create a new, empty update plan
+ let mut update_plan = UpdatePlan::default();
+ // Here, we define all the timestamps, remember, if difference between the
+ // upstream record timestamp and the server timestamp is less than the
+ // difference between the local record timestamp and time **now** then the server wins.
+ //
+ // In other words, if server_time - upstream_time < now - local_record_time then the server
+ // wins. This is because we determine which record to "prefer" based on the "age" of the
+ // update
+ let now = SystemTime::now();
+ // local record's timestamps is now - 100 second, so the local age is 100
+ let local_modified = now.checked_sub(Duration::from_secs(100)).unwrap();
+ // mirror timestamp is not too relevant here, but we set it for completeness
+ let mirror_timestamp = now.checked_sub(Duration::from_secs(1000)).unwrap();
+ // Server's timestamp is now
+ let server_timestamp = now;
+ // Server's record timestamp is now - 1 second, so the server age is: 1
+ // And since the local age is 100, then the server should win.
+ let server_record_timestamp = now.checked_sub(Duration::from_secs(1)).unwrap();
+ let local_login = LocalLogin::Alive {
+ login: login.clone(),
+ local_modified,
+ };
+
+ let mirror_login = MirrorLogin {
+ login: mirror_login,
+ server_modified: mirror_timestamp.try_into().unwrap(),
+ };
+
+ // Lets make sure our local login is in the database, so that it can be updated later
+ insert_encrypted_login(
+ &db,
+ &login,
+ &mirror_login.login,
+ &mirror_login.server_modified,
+ );
+ let upstream_login = IncomingLogin {
+ login: server_login,
+ unknown: None,
+ };
+
+ update_plan
+ .plan_three_way_merge(
+ local_login,
+ mirror_login,
+ upstream_login,
+ server_record_timestamp.try_into().unwrap(),
+ server_timestamp.try_into().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ update_plan
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+
+ check_local_login(&db, "login", "new upstream password", 0);
+ }
+
+ #[test]
+ fn test_plan_three_way_merge_local_wins() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ // First we create our expected logins
+ let login = enc_login("login", "new local password");
+ let mirror_login = enc_login("login", "mirror password");
+ let server_login = enc_login("login", "old upstream password");
+
+ // Then, we create a new, empty update plan
+ let mut update_plan = UpdatePlan::default();
+ // Here, we define all the timestamps, remember, if difference between the
+ // upstream record timestamp and the server timestamp is less than the
+ // difference between the local record timestamp and time **now** then the server wins.
+ //
+ // In other words, if server_time - upstream_time < now - local_record_time then the server
+ // wins. This is because we determine which record to "prefer" based on the "age" of the
+ // update
+ let now = SystemTime::now();
+ // local record's timestamps is now - 1 second, so the local age is 1
+ let local_modified = now.checked_sub(Duration::from_secs(1)).unwrap();
+ // mirror timestamp is not too relevant here, but we set it for completeness
+ let mirror_timestamp = now.checked_sub(Duration::from_secs(1000)).unwrap();
+ // Server's timestamp is now
+ let server_timestamp = now;
+ // Server's record timestamp is now - 500 second, so the server age is: 500
+ // And since the local age is 1, the local record should win!
+ let server_record_timestamp = now.checked_sub(Duration::from_secs(500)).unwrap();
+ let local_login = LocalLogin::Alive {
+ login: login.clone(),
+ local_modified,
+ };
+ let mirror_login = MirrorLogin {
+ login: mirror_login,
+ server_modified: mirror_timestamp.try_into().unwrap(),
+ };
+
+ // Lets make sure our local login is in the database, so that it can be updated later
+ insert_encrypted_login(
+ &db,
+ &login,
+ &mirror_login.login,
+ &mirror_login.server_modified,
+ );
+
+ let upstream_login = IncomingLogin {
+ login: server_login,
+ unknown: None,
+ };
+
+ update_plan
+ .plan_three_way_merge(
+ local_login,
+ mirror_login,
+ upstream_login,
+ server_record_timestamp.try_into().unwrap(),
+ server_timestamp.try_into().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ update_plan
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+
+ check_local_login(&db, "login", "new local password", 0);
+ }
+
+ #[test]
+ fn test_plan_three_way_merge_local_tombstone_loses() {
+ ensure_initialized();
+ let db = LoginDb::open_in_memory();
+ // First we create our expected logins
+ let login = enc_login("login", "new local password");
+ let mirror_login = enc_login("login", "mirror password");
+ let server_login = enc_login("login", "old upstream password");
+
+ // Then, we create a new, empty update plan
+ let mut update_plan = UpdatePlan::default();
+ // Here, we define all the timestamps, remember, if difference between the
+ // upstream record timestamp and the server timestamp is less than the
+ // difference between the local record timestamp and time **now** then the server wins.
+ //
+ // In other words, if server_time - upstream_time < now - local_record_time then the server
+ // wins. This is because we determine which record to "prefer" based on the "age" of the
+ // update
+ let now = SystemTime::now();
+ // local record's timestamps is now - 1 second, so the local age is 1
+ let local_modified = now.checked_sub(Duration::from_secs(1)).unwrap();
+ // mirror timestamp is not too relevant here, but we set it for completeness
+ let mirror_timestamp = now.checked_sub(Duration::from_secs(1000)).unwrap();
+ // Server's timestamp is now
+ let server_timestamp = now;
+ // Server's record timestamp is now - 500 second, so the server age is: 500
+ // And since the local age is 1, the local record should win!
+ let server_record_timestamp = now.checked_sub(Duration::from_secs(500)).unwrap();
+ let mirror_login = MirrorLogin {
+ login: mirror_login,
+ server_modified: mirror_timestamp.try_into().unwrap(),
+ };
+
+ // Lets make sure our local login is in the database, so that it can be updated later
+ insert_encrypted_login(
+ &db,
+ &login,
+ &mirror_login.login,
+ &mirror_login.server_modified,
+ );
+
+ // Now, lets delete our local login
+ db.delete("login").unwrap();
+
+ // Then, lets set our tombstone
+ let local_login = LocalLogin::Tombstone {
+ id: login.meta.id.clone(),
+ local_modified,
+ };
+
+ let upstream_login = IncomingLogin {
+ login: server_login,
+ unknown: None,
+ };
+
+ update_plan
+ .plan_three_way_merge(
+ local_login,
+ mirror_login,
+ upstream_login,
+ server_record_timestamp.try_into().unwrap(),
+ server_timestamp.try_into().unwrap(),
+ &*TEST_ENCDEC,
+ )
+ .unwrap();
+ update_plan
+ .execute(&db, &db.begin_interrupt_scope().unwrap())
+ .unwrap();
+
+ // Now we verify that even though our login deletion was "younger"
+ // then the upstream modification, the upstream modification wins because
+ // modifications always beat tombstones
+ check_local_login(&db, "login", "old upstream password", 0);
+ }
+
+ #[test]
+ fn test_plan_two_way_merge_local_tombstone_loses() {
+ ensure_initialized();
+ let mut update_plan = UpdatePlan::default();
+ // Ensure the local tombstone is newer than the incoming - it still loses.
+ let local = LocalLogin::Tombstone {
+ id: "login-id".to_string(),
+ local_modified: SystemTime::now(),
+ };
+ let incoming = IncomingLogin {
+ login: enc_login("login-id", "new local password"),
+ unknown: None,
+ };
+
+ update_plan.plan_two_way_merge(local, (incoming, ServerTimestamp::from_millis(1234)));
+
+ // Plan should be to apply the incoming.
+ assert_eq!(update_plan.mirror_inserts.len(), 1);
+ assert_eq!(update_plan.delete_local.len(), 1);
+ assert_eq!(update_plan.delete_mirror.len(), 0);
+ }
+}
diff --git a/third_party/rust/logins/src/util.rs b/third_party/rust/logins/src/util.rs
@@ -0,0 +1,40 @@
+/* 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 crate::error::*;
+use rusqlite::Row;
+use std::time;
+use url::Url;
+
+pub fn url_host_port(url_str: &str) -> Option<String> {
+ let url = Url::parse(url_str).ok()?;
+ let host = url.host_str()?;
+ Some(if let Some(p) = url.port() {
+ format!("{}:{}", host, p)
+ } else {
+ host.to_string()
+ })
+}
+
+pub fn system_time_millis_from_row(row: &Row<'_>, col_name: &str) -> Result<time::SystemTime> {
+ let time_ms = row.get::<_, Option<i64>>(col_name)?.unwrap_or_default() as u64;
+ Ok(time::UNIX_EPOCH + time::Duration::from_millis(time_ms))
+}
+
+pub fn duration_ms_i64(d: time::Duration) -> i64 {
+ (d.as_secs() as i64) * 1000 + (i64::from(d.subsec_nanos()) / 1_000_000)
+}
+
+pub fn system_time_ms_i64(t: time::SystemTime) -> i64 {
+ duration_ms_i64(t.duration_since(time::UNIX_EPOCH).unwrap_or_default())
+}
+
+#[cfg(test)]
+pub(crate) fn init_test_logging() {
+ use std::sync::Once;
+ static INIT_LOGGING: Once = Once::new();
+ INIT_LOGGING.call_once(|| {
+ error_support::init_for_tests_with_level(error_support::Level::Trace);
+ });
+}
diff --git a/third_party/rust/logins/uniffi.toml b/third_party/rust/logins/uniffi.toml
@@ -0,0 +1,6 @@
+[bindings.kotlin]
+package_name = "mozilla.appservices.logins"
+
+[bindings.swift]
+ffi_module_name = "MozillaRustComponents"
+ffi_module_filename = "loginsFFI"
diff --git a/third_party/rust/nss/.cargo-checksum.json b/third_party/rust/nss/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"a02789df36131f32a60b54968c08b6cb77b75735011d2d4a8932b4f538ddd139","README.md":"14dd59e435d179c21c3b4b880bbe3cc6e5999b9f9ac9431f3f9aa3f43902e3fa","src/aes.rs":"bf3b115fecfc445fed978f43fed4076249c99d72db203acacd8297f418c347e5","src/cert.rs":"8195da7dc86bb9f60306106be08e622d0a116dabdbd31967e227435933ee50d0","src/ec.rs":"c495042a6f92254b7c9941ef0e253340922b0c1d1c43c7d3e725aa1068ae5d0b","src/ecdh.rs":"4acddfaebbc43f4e59c9dd0df56e582f5d0db65c4fd15dcc634c2e27d84efc2c","src/error.rs":"58a923bb8651160bb17c582cf876046792e79f3a190c8572f836b218f16cee74","src/lib.rs":"862ae2d8dbbe29f83579209286198b19bdccdcd81b99e55646d25de874a76d13","src/pbkdf2.rs":"40d5facfdc434571455283265823dd2b0334d2a8db0a09b50ee05d5b1f2a02d7","src/pk11/context.rs":"b4927fe401ed113d79f03aed1c0d9a007d3ce3b3706921ebc3e239e1f472dad6","src/pk11/mod.rs":"d78368654f9a8bc12f1403c4a096b63cf9834820ea6ed48418b9afaa0fc2299e","src/pk11/slot.rs":"99cb603b6d561b86d7655ca33da4aa0e4fb355d065f56d1bfc22b0778a745989","src/pk11/sym_key.rs":"28c01518126a2460c14266fad3dfcbbf50a6bbf4d40bfbf66d1b9d9ae47b47da","src/pk11/types.rs":"010e926224d29c9fe12d8804add17e2130f4c383bc8186ac1dad08d16678ae4e","src/pkixc.rs":"939fd8bd84be5eef57c6e9a970e1509e8cb94566ad42f1427a3beaaa214cc62b","src/secport.rs":"99a2c5112939bda2558dd7f0760f1092ab42052871448181083f92ce56f73f05","src/util.rs":"5d19265429cb707dc51a7b712ae6f5dd013db0975d215a314a31e8110902f4a5"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/nss/Cargo.toml b/third_party/rust/nss/Cargo.toml
@@ -0,0 +1,51 @@
+# 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 = "nss"
+version = "0.1.0"
+authors = ["Sync Team <sync-team@mozilla.com>"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = "README.md"
+license = "MPL-2.0"
+
+[features]
+backtrace = ["error-support/backtrace"]
+default = []
+gecko = ["nss_sys/gecko"]
+keydb = ["dep:once_cell"]
+
+[lib]
+name = "nss"
+crate-type = ["lib"]
+path = "src/lib.rs"
+
+[dependencies]
+base64 = "0.21"
+serde = "1"
+serde_derive = "1"
+thiserror = "2"
+
+[dependencies.error-support]
+path = "../../error"
+
+[dependencies.nss_sys]
+path = "nss_sys"
+
+[dependencies.once_cell]
+version = "1.20.2"
+optional = true
diff --git a/third_party/rust/nss/README.md b/third_party/rust/nss/README.md
@@ -0,0 +1,21 @@
+## nss
+
+This crate provides various cryptographic routines backed by
+[NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS).
+
+The API is designed to operate at approximately the same level of abstraction as the
+[`crypto.subtle`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) API, although the details are obviously
+different given the different host language. It provides:
+
+* Cryptographically secure [pseudorandom number generation](./src/pk11/slot.rs).
+* Cryptographic [digests](./src/pk11/context.rs) and [hkdf](./src/pk11/sym_key.rs).
+* [AES encryption and decryption](./src/aes.rs) in various modes.
+* Generation, import and export of [elliptic-curve keys](./src/ec.rs).
+* ECDH [key agreement](./src/ecdh.rs).
+* Constant-time [string comparison](./src/secport.rs).
+
+Like the `crypto.subtle` API, these primitives are quite low-level and involve some subtlety in order to use correctly.
+Consumers should prefer the higher-level abstractions offered by the [rc_crypto](../) crate where possible.
+
+These features are in turn built on even-lower-level bindings to the raw NSS API, provided by the [nss_sys](./nss_sys)
+crate.
diff --git a/third_party/rust/nss/src/aes.rs b/third_party/rust/nss/src/aes.rs
@@ -0,0 +1,116 @@
+/* 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 crate::{
+ error::*,
+ pk11::sym_key::import_sym_key,
+ util::{assert_nss_initialized, map_nss_secstatus, ScopedPtr},
+};
+use std::{
+ mem,
+ os::raw::{c_uchar, c_uint},
+};
+
+const AES_GCM_TAG_LENGTH: usize = 16;
+
+#[derive(Debug, Copy, Clone)]
+pub enum Operation {
+ Encrypt,
+ Decrypt,
+}
+
+pub fn aes_gcm_crypt(
+ key: &[u8],
+ nonce: &[u8],
+ aad: &[u8],
+ data: &[u8],
+ operation: Operation,
+) -> Result<Vec<u8>> {
+ let mut gcm_params = nss_sys::CK_GCM_PARAMS {
+ pIv: nonce.as_ptr() as nss_sys::CK_BYTE_PTR,
+ ulIvLen: nss_sys::CK_ULONG::try_from(nonce.len())?,
+ ulIvBits: nss_sys::CK_ULONG::try_from(
+ nonce.len().checked_mul(8).ok_or(ErrorKind::InternalError)?,
+ )?,
+ pAAD: aad.as_ptr() as nss_sys::CK_BYTE_PTR,
+ ulAADLen: nss_sys::CK_ULONG::try_from(aad.len())?,
+ ulTagBits: nss_sys::CK_ULONG::try_from(AES_GCM_TAG_LENGTH * 8)?,
+ };
+ let mut params = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: &mut gcm_params as *mut _ as *mut c_uchar,
+ len: c_uint::try_from(mem::size_of::<nss_sys::CK_GCM_PARAMS>())?,
+ };
+ common_crypt(
+ nss_sys::CKM_AES_GCM.into(),
+ key,
+ data,
+ AES_GCM_TAG_LENGTH,
+ &mut params,
+ operation,
+ )
+}
+
+pub fn aes_cbc_crypt(
+ key: &[u8],
+ nonce: &[u8],
+ data: &[u8],
+ operation: Operation,
+) -> Result<Vec<u8>> {
+ let mut params = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: nonce.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(nonce.len())?,
+ };
+ common_crypt(
+ nss_sys::CKM_AES_CBC_PAD.into(),
+ key,
+ data,
+ usize::try_from(nss_sys::AES_BLOCK_SIZE)?, // CBC mode might pad the result.
+ &mut params,
+ operation,
+ )
+}
+
+pub fn common_crypt(
+ mech: nss_sys::CK_MECHANISM_TYPE,
+ key: &[u8],
+ data: &[u8],
+ extra_data_len: usize,
+ params: &mut nss_sys::SECItem,
+ operation: Operation,
+) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+ // Most of the following code is inspired by the Firefox WebCrypto implementation:
+ // https://searchfox.org/mozilla-central/rev/f46e2bf881d522a440b30cbf5cf8d76fc212eaf4/dom/crypto/WebCryptoTask.cpp#566
+ // CKA_ENCRYPT always is fine.
+ let sym_key = import_sym_key(mech, nss_sys::CKA_ENCRYPT.into(), key)?;
+ // Initialize the output buffer (enough space for padding / a full tag).
+ let result_max_len = data
+ .len()
+ .checked_add(extra_data_len)
+ .ok_or(ErrorKind::InternalError)?;
+ let mut out_len: c_uint = 0;
+ let mut out = vec![0u8; result_max_len];
+ let result_max_len_uint = c_uint::try_from(result_max_len)?;
+ let data_len = c_uint::try_from(data.len())?;
+ let f = match operation {
+ Operation::Decrypt => nss_sys::PK11_Decrypt,
+ Operation::Encrypt => nss_sys::PK11_Encrypt,
+ };
+ map_nss_secstatus(|| unsafe {
+ f(
+ sym_key.as_mut_ptr(),
+ mech,
+ params,
+ out.as_mut_ptr(),
+ &mut out_len,
+ result_max_len_uint,
+ data.as_ptr(),
+ data_len,
+ )
+ })?;
+ out.truncate(usize::try_from(out_len)?);
+ Ok(out)
+}
diff --git a/third_party/rust/nss/src/cert.rs b/third_party/rust/nss/src/cert.rs
@@ -0,0 +1,43 @@
+/* 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 crate::error::*;
+use crate::pk11::types::{Certificate, PublicKey};
+use crate::util::{assert_nss_initialized, sec_item_as_slice, ScopedPtr};
+use nss_sys::{CERT_ExtractPublicKey, CERT_GetDefaultCertDB, CERT_NewTempCertificate};
+
+pub fn extract_ec_public_key(der: &[u8]) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+
+ let certdb = unsafe { CERT_GetDefaultCertDB() };
+ let mut data = nss_sys::SECItem {
+ len: u32::try_from(der.len())?,
+ data: der.as_ptr() as *mut u8,
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ };
+
+ let cert = unsafe {
+ Certificate::from_ptr(CERT_NewTempCertificate(
+ certdb,
+ &mut data,
+ std::ptr::null_mut(),
+ nss_sys::PR_FALSE,
+ nss_sys::PR_TRUE,
+ ))?
+ };
+
+ let pub_key = unsafe { PublicKey::from_ptr(CERT_ExtractPublicKey(cert.as_mut_ptr()))? };
+ let pub_key_raw = unsafe { &*pub_key.as_ptr() };
+
+ if pub_key_raw.keyType != nss_sys::KeyType::ecKey as u32 {
+ return Err(
+ ErrorKind::InputError("public key is not of type EC (Elliptic Curve).".into()).into(),
+ );
+ }
+
+ let mut pub_key_data = unsafe { pub_key_raw.u.ec.publicValue };
+ let pub_key_data_raw = unsafe { sec_item_as_slice(&mut pub_key_data)? };
+
+ Ok(pub_key_data_raw.to_vec())
+}
diff --git a/third_party/rust/nss/src/ec.rs b/third_party/rust/nss/src/ec.rs
@@ -0,0 +1,422 @@
+/* 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 crate::{
+ error::*,
+ pk11::{
+ self,
+ context::HashAlgorithm,
+ slot,
+ types::{Pkcs11Object, PrivateKey as PK11PrivateKey, PublicKey as PK11PublicKey},
+ },
+ util::{assert_nss_initialized, map_nss_secstatus, sec_item_as_slice, ScopedPtr},
+};
+use serde_derive::{Deserialize, Serialize};
+use std::{
+ mem,
+ ops::Deref,
+ os::raw::{c_uchar, c_uint, c_void},
+ ptr,
+};
+
+#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
+#[repr(u8)]
+pub enum Curve {
+ P256,
+ P384,
+}
+
+impl Curve {
+ pub fn get_field_len(&self) -> u32 {
+ match &self {
+ Curve::P256 => 32,
+ Curve::P384 => 48,
+ }
+ }
+}
+
+const CRV_P256: &str = "P-256";
+const CRV_P384: &str = "P-384";
+
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct EcKey {
+ curve: String,
+ // The `d` value of the EC Key.
+ private_key: Vec<u8>,
+ // The uncompressed x,y-representation of the public component of the EC Key.
+ public_key: Vec<u8>,
+}
+
+impl EcKey {
+ pub fn new(curve: Curve, private_key: &[u8], public_key: &[u8]) -> Self {
+ let curve = match curve {
+ Curve::P256 => CRV_P256,
+ Curve::P384 => CRV_P384,
+ };
+ Self {
+ curve: curve.to_owned(),
+ private_key: private_key.to_vec(),
+ public_key: public_key.to_vec(),
+ }
+ }
+
+ pub fn from_coordinates(curve: Curve, d: &[u8], x: &[u8], y: &[u8]) -> Result<Self> {
+ let ec_point = create_ec_point_for_coordinates(x, y)?;
+ Ok(EcKey::new(curve, d, &ec_point))
+ }
+
+ pub fn curve(&self) -> Curve {
+ if self.curve == CRV_P256 {
+ return Curve::P256;
+ } else if self.curve == CRV_P384 {
+ return Curve::P384;
+ }
+ unimplemented!("It is impossible to create a curve object with a different CRV.")
+ }
+
+ pub fn public_key(&self) -> &[u8] {
+ &self.public_key
+ }
+
+ pub fn private_key(&self) -> &[u8] {
+ &self.private_key
+ }
+}
+
+fn create_ec_point_for_coordinates(x: &[u8], y: &[u8]) -> Result<Vec<u8>> {
+ if x.len() != y.len() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ let mut buf = vec![0u8; x.len() + y.len() + 1];
+ buf[0] = u8::try_from(nss_sys::EC_POINT_FORM_UNCOMPRESSED)?;
+ let mut offset = 1;
+ buf[offset..offset + x.len()].copy_from_slice(x);
+ offset += x.len();
+ buf[offset..offset + y.len()].copy_from_slice(y);
+ Ok(buf)
+}
+
+pub fn generate_keypair(curve: Curve) -> Result<(PrivateKey, PublicKey)> {
+ assert_nss_initialized();
+ // 1. Create EC params
+ let params_buf = create_ec_params_for_curve(curve)?;
+ let mut params = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: params_buf.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(params_buf.len())?,
+ };
+
+ // 2. Generate the key pair
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/f46e2bf881d522a440b30cbf5cf8d76fc212eaf4/dom/crypto/WebCryptoTask.cpp#2389
+ let mech = nss_sys::CKM_EC_KEY_PAIR_GEN;
+ let slot = slot::get_internal_slot()?;
+ let mut pub_key: *mut nss_sys::SECKEYPublicKey = ptr::null_mut();
+ let prv_key = PrivateKey::from(curve, unsafe {
+ PK11PrivateKey::from_ptr(nss_sys::PK11_GenerateKeyPair(
+ slot.as_mut_ptr(),
+ mech.into(),
+ &mut params as *mut _ as *mut c_void,
+ &mut pub_key,
+ nss_sys::PR_FALSE,
+ nss_sys::PR_FALSE,
+ ptr::null_mut(),
+ ))?
+ });
+ let pub_key = PublicKey::from(curve, unsafe { PK11PublicKey::from_ptr(pub_key)? });
+ Ok((prv_key, pub_key))
+}
+
+pub struct PrivateKey {
+ curve: Curve,
+ wrapped: PK11PrivateKey,
+}
+
+impl Deref for PrivateKey {
+ type Target = PK11PrivateKey;
+ #[inline]
+ fn deref(&self) -> &PK11PrivateKey {
+ &self.wrapped
+ }
+}
+
+impl PrivateKey {
+ pub fn convert_to_public_key(&self) -> Result<PublicKey> {
+ let mut pub_key = self.wrapped.convert_to_public_key()?;
+
+ // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1562046.
+ let field_len = self.curve.get_field_len();
+ let expected_len = 2 * field_len + 1;
+ let mut pub_value = unsafe { (*pub_key.as_ptr()).u.ec.publicValue };
+ if pub_value.len == expected_len - 2 {
+ let old_pub_value_raw = unsafe { sec_item_as_slice(&mut pub_value)?.to_vec() };
+ let mut new_pub_value_raw = vec![0u8; usize::try_from(expected_len)?];
+ new_pub_value_raw[0] = u8::try_from(nss_sys::EC_POINT_FORM_UNCOMPRESSED)?;
+ new_pub_value_raw[1] = u8::try_from(old_pub_value_raw.len())?;
+ new_pub_value_raw[2..].copy_from_slice(&old_pub_value_raw);
+ pub_key = PublicKey::from_bytes(self.curve, &new_pub_value_raw)?.wrapped;
+ }
+ Ok(PublicKey {
+ wrapped: pub_key,
+ curve: self.curve,
+ })
+ }
+
+ #[inline]
+ pub(crate) fn from(curve: Curve, key: PK11PrivateKey) -> Self {
+ Self {
+ curve,
+ wrapped: key,
+ }
+ }
+
+ pub fn curve(&self) -> Curve {
+ self.curve
+ }
+
+ pub fn private_value(&self) -> Result<Vec<u8>> {
+ let mut private_value = self.read_raw_attribute(nss_sys::CKA_VALUE.into()).unwrap();
+ let private_key = unsafe { sec_item_as_slice(private_value.as_mut_ref())?.to_vec() };
+ Ok(private_key)
+ }
+
+ fn from_nss_params(
+ curve: Curve,
+ ec_params: &[u8],
+ ec_point: &[u8],
+ private_value: &[u8],
+ ) -> Result<Self> {
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/444ee13e14fe30451651c0f62b3979c76766ada4/dom/crypto/CryptoKey.cpp#322
+ // These explicit variable type declarations are *VERY* important, as we pass to NSS a pointer to them
+ // and we need these variables to be of the right size!
+ let mut private_key_value: nss_sys::CK_OBJECT_CLASS = nss_sys::CKO_PRIVATE_KEY.into();
+ let mut false_value: nss_sys::CK_BBOOL = nss_sys::CK_FALSE;
+ let mut ec_value: nss_sys::CK_KEY_TYPE = nss_sys::CKK_EC.into();
+ let bbool_size = mem::size_of::<nss_sys::CK_BBOOL>();
+ let key_template = vec![
+ ck_attribute(
+ nss_sys::CKA_CLASS.into(),
+ &mut private_key_value as *mut _ as *mut c_void,
+ mem::size_of::<nss_sys::CK_OBJECT_CLASS>(),
+ )?,
+ ck_attribute(
+ nss_sys::CKA_KEY_TYPE.into(),
+ &mut ec_value as *mut _ as *mut c_void,
+ mem::size_of::<nss_sys::CK_KEY_TYPE>(),
+ )?,
+ ck_attribute(
+ nss_sys::CKA_TOKEN.into(),
+ &mut false_value as *mut _ as *mut c_void,
+ bbool_size,
+ )?,
+ ck_attribute(
+ nss_sys::CKA_SENSITIVE.into(),
+ &mut false_value as *mut _ as *mut c_void,
+ bbool_size,
+ )?,
+ ck_attribute(
+ nss_sys::CKA_PRIVATE.into(),
+ &mut false_value as *mut _ as *mut c_void,
+ bbool_size,
+ )?,
+ // PrivateKeyFromPrivateKeyTemplate sets the ID.
+ ck_attribute(nss_sys::CKA_ID.into(), ptr::null_mut(), 0)?,
+ ck_attribute(
+ nss_sys::CKA_EC_PARAMS.into(),
+ ec_params.as_ptr() as *mut c_void,
+ ec_params.len(),
+ )?,
+ ck_attribute(
+ nss_sys::CKA_EC_POINT.into(),
+ ec_point.as_ptr() as *mut c_void,
+ ec_point.len(),
+ )?,
+ ck_attribute(
+ nss_sys::CKA_VALUE.into(),
+ private_value.as_ptr() as *mut c_void,
+ private_value.len(),
+ )?,
+ ];
+ Ok(Self::from(
+ curve,
+ PK11PrivateKey::from_private_key_template(key_template)?,
+ ))
+ }
+
+ pub fn import(ec_key: &EcKey) -> Result<Self> {
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/66086345467c69685434dd1c5177b30a7511b1a5/dom/crypto/CryptoKey.cpp#652
+ assert_nss_initialized();
+ let curve = ec_key.curve();
+ let ec_params = create_ec_params_for_curve(curve)?;
+ Self::from_nss_params(curve, &ec_params, &ec_key.public_key, &ec_key.private_key)
+ }
+
+ pub fn export(&self) -> Result<EcKey> {
+ let public_key = self.convert_to_public_key()?;
+ let public_key_bytes = public_key.to_bytes()?;
+ let private_key_bytes = self.private_value()?;
+ Ok(EcKey::new(
+ self.curve,
+ &private_key_bytes,
+ &public_key_bytes,
+ ))
+ }
+}
+
+#[inline]
+fn ck_attribute(
+ r#type: nss_sys::CK_ATTRIBUTE_TYPE,
+ p_value: nss_sys::CK_VOID_PTR,
+ value_len: usize,
+) -> Result<nss_sys::CK_ATTRIBUTE> {
+ Ok(nss_sys::CK_ATTRIBUTE {
+ type_: r#type,
+ pValue: p_value,
+ ulValueLen: nss_sys::CK_ULONG::try_from(value_len)?,
+ })
+}
+
+pub struct PublicKey {
+ curve: Curve,
+ wrapped: PK11PublicKey,
+}
+
+impl Deref for PublicKey {
+ type Target = PK11PublicKey;
+ #[inline]
+ fn deref(&self) -> &PK11PublicKey {
+ &self.wrapped
+ }
+}
+
+impl PublicKey {
+ #[inline]
+ pub(crate) fn from(curve: Curve, key: PK11PublicKey) -> Self {
+ Self {
+ curve,
+ wrapped: key,
+ }
+ }
+
+ pub fn curve(&self) -> Curve {
+ self.curve
+ }
+
+ /// ECDSA verify operation
+ pub fn verify(
+ &self,
+ message: &[u8],
+ signature: &[u8],
+ hash_algorithm: HashAlgorithm,
+ ) -> Result<()> {
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/b2716c233e9b4398fc5923cbe150e7f83c7c6c5b/dom/crypto/WebCryptoTask.cpp#1144
+ let signature = nss_sys::SECItem {
+ len: u32::try_from(signature.len())?,
+ data: signature.as_ptr() as *mut u8,
+ type_: 0,
+ };
+ let hash = pk11::context::hash_buf(&hash_algorithm, message)?;
+ let hash = nss_sys::SECItem {
+ len: u32::try_from(hash.len())?,
+ data: hash.as_ptr() as *mut u8,
+ type_: 0,
+ };
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_VerifyWithMechanism(
+ self.as_mut_ptr(),
+ nss_sys::PK11_MapSignKeyType((*self.wrapped.as_ptr()).keyType),
+ ptr::null(),
+ &signature,
+ &hash,
+ ptr::null_mut(),
+ )
+ })?;
+ Ok(())
+ }
+
+ pub fn to_bytes(&self) -> Result<Vec<u8>> {
+ // Some public keys we create do not have an associated PCKS#11 slot
+ // therefore we cannot use `read_raw_attribute(CKA_EC_POINT)`
+ // so we read the `publicValue` field directly instead.
+ let mut ec_point = unsafe { (*self.as_ptr()).u.ec.publicValue };
+ let public_key = unsafe { sec_item_as_slice(&mut ec_point)?.to_vec() };
+ check_pub_key_bytes(&public_key, self.curve)?;
+ Ok(public_key)
+ }
+
+ pub fn from_bytes(curve: Curve, bytes: &[u8]) -> Result<PublicKey> {
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/ec489aa170b6486891cf3625717d6fa12bcd11c1/dom/crypto/CryptoKey.cpp#1078
+ check_pub_key_bytes(bytes, curve)?;
+ let key_data = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: bytes.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(bytes.len())?,
+ };
+ let params_buf = create_ec_params_for_curve(curve)?;
+ let params = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: params_buf.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(params_buf.len())?,
+ };
+
+ let pub_key = nss_sys::SECKEYPublicKey {
+ arena: ptr::null_mut(),
+ keyType: nss_sys::KeyType::ecKey as u32,
+ pkcs11Slot: ptr::null_mut(),
+ pkcs11ID: nss_sys::CK_INVALID_HANDLE.into(),
+ u: nss_sys::SECKEYPublicKeyStr_u {
+ ec: nss_sys::SECKEYECPublicKey {
+ DEREncodedParams: params,
+ publicValue: key_data,
+ encoding: nss_sys::ECPointEncoding::ECPoint_Uncompressed as u32,
+ size: 0,
+ },
+ },
+ };
+ Ok(Self::from(curve, unsafe {
+ PK11PublicKey::from_ptr(nss_sys::SECKEY_CopyPublicKey(&pub_key))?
+ }))
+ }
+}
+
+fn check_pub_key_bytes(bytes: &[u8], curve: Curve) -> Result<()> {
+ let field_len = curve.get_field_len();
+ // Check length of uncompressed point coordinates. There are 2 field elements
+ // and a leading "point form" octet (which must be EC_POINT_FORM_UNCOMPRESSED).
+ if bytes.len() != usize::try_from(2 * field_len + 1)? {
+ return Err(ErrorKind::InternalError.into());
+ }
+ // No support for compressed points.
+ if bytes[0] != u8::try_from(nss_sys::EC_POINT_FORM_UNCOMPRESSED)? {
+ return Err(ErrorKind::InternalError.into());
+ }
+ Ok(())
+}
+
+fn create_ec_params_for_curve(curve: Curve) -> Result<Vec<u8>> {
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/ec489aa170b6486891cf3625717d6fa12bcd11c1/dom/crypto/WebCryptoCommon.h#299
+ let curve_oid_tag = match curve {
+ Curve::P256 => nss_sys::SECOidTag::SEC_OID_SECG_EC_SECP256R1,
+ Curve::P384 => nss_sys::SECOidTag::SEC_OID_SECG_EC_SECP384R1,
+ };
+ // Retrieve curve data by OID tag.
+ let oid_data = unsafe { nss_sys::SECOID_FindOIDByTag(curve_oid_tag as u32) };
+ if oid_data.is_null() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ // Set parameters
+ let oid_data_len = unsafe { (*oid_data).oid.len };
+ let mut buf = vec![0u8; usize::try_from(oid_data_len)? + 2];
+ buf[0] = c_uchar::try_from(nss_sys::SEC_ASN1_OBJECT_ID)?;
+ buf[1] = c_uchar::try_from(oid_data_len)?;
+ let oid_data_data =
+ unsafe { std::slice::from_raw_parts((*oid_data).oid.data, usize::try_from(oid_data_len)?) };
+ buf[2..].copy_from_slice(oid_data_data);
+ Ok(buf)
+}
diff --git a/third_party/rust/nss/src/ecdh.rs b/third_party/rust/nss/src/ecdh.rs
@@ -0,0 +1,46 @@
+/* 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 crate::{
+ ec::{PrivateKey, PublicKey},
+ error::*,
+ pk11::types::SymKey,
+ util::{assert_nss_initialized, map_nss_secstatus, sec_item_as_slice, ScopedPtr},
+};
+
+pub fn ecdh_agreement(priv_key: &PrivateKey, pub_key: &PublicKey) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+ if priv_key.curve() != pub_key.curve() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ // The following code is adapted from:
+ // https://searchfox.org/mozilla-central/rev/444ee13e14fe30451651c0f62b3979c76766ada4/dom/crypto/WebCryptoTask.cpp#2835
+
+ // CKM_SHA512_HMAC and CKA_SIGN are key type and usage attributes of the
+ // derived symmetric key and don't matter because we ignore them anyway.
+ let sym_key = unsafe {
+ SymKey::from_ptr(nss_sys::PK11_PubDeriveWithKDF(
+ priv_key.as_mut_ptr(),
+ pub_key.as_mut_ptr(),
+ nss_sys::PR_FALSE,
+ std::ptr::null_mut(),
+ std::ptr::null_mut(),
+ nss_sys::CKM_ECDH1_DERIVE.into(),
+ nss_sys::CKM_SHA512_HMAC.into(),
+ nss_sys::CKA_SIGN.into(),
+ 0,
+ nss_sys::CKD_NULL.into(),
+ std::ptr::null_mut(),
+ std::ptr::null_mut(),
+ ))?
+ };
+
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_ExtractKeyValue(sym_key.as_mut_ptr()) })?;
+
+ // This doesn't leak, because the SECItem* returned by PK11_GetKeyData
+ // just refers to a buffer managed by `sym_key` which we copy into `buf`.
+ let mut key_data = unsafe { *nss_sys::PK11_GetKeyData(sym_key.as_mut_ptr()) };
+ let buf = unsafe { sec_item_as_slice(&mut key_data)? };
+ Ok(buf.to_vec())
+}
diff --git a/third_party/rust/nss/src/error.rs b/third_party/rust/nss/src/error.rs
@@ -0,0 +1,38 @@
+/* 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/. */
+
+#[derive(Debug, thiserror::Error)]
+pub enum ErrorKind {
+ #[error("NSS error: {0} {1}")]
+ NSSError(i32, String),
+ #[error("SSL error: {0} {1}")]
+ SSLError(i32, String),
+ #[error("PKIX error: {0} {1}")]
+ PKIXError(i32, String),
+ #[error("Input or format error: {0}")]
+ InputError(String),
+ #[error("Internal crypto error")]
+ InternalError,
+ #[error("invalid key length")]
+ InvalidKeyLength,
+ #[error("Interior nul byte was found")]
+ NulError,
+ #[error("Conversion error: {0}")]
+ ConversionError(#[from] std::num::TryFromIntError),
+ #[error("Base64 decode error: {0}")]
+ Base64Decode(#[from] base64::DecodeError),
+ #[error("Certificate issuer does not match")]
+ CertificateIssuerError,
+ #[error("Certificate subject does not match")]
+ CertificateSubjectError,
+ #[error("Certificate not yet valid or expired")]
+ CertificateValidityError,
+}
+
+error_support::define_error! {
+ ErrorKind {
+ (Base64Decode, base64::DecodeError),
+ (ConversionError, std::num::TryFromIntError),
+ }
+}
diff --git a/third_party/rust/nss/src/lib.rs b/third_party/rust/nss/src/lib.rs
@@ -0,0 +1,23 @@
+/* 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/. */
+
+#![allow(unknown_lints)]
+#![warn(rust_2018_idioms)]
+#[macro_use]
+mod util;
+pub mod aes;
+pub mod cert;
+pub mod ec;
+pub mod ecdh;
+mod error;
+pub mod pbkdf2;
+pub mod pk11;
+pub mod pkixc;
+pub mod secport;
+pub use crate::error::{Error, ErrorKind, Result};
+pub use util::assert_nss_initialized as assert_initialized;
+pub use util::ensure_nss_initialized as ensure_initialized;
+
+#[cfg(feature = "keydb")]
+pub use util::ensure_nss_initialized_with_profile_dir as ensure_initialized_with_profile_dir;
diff --git a/third_party/rust/nss/src/pbkdf2.rs b/third_party/rust/nss/src/pbkdf2.rs
@@ -0,0 +1,77 @@
+/* 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 crate::util::{assert_nss_initialized, map_nss_secstatus, sec_item_as_slice, ScopedPtr};
+use crate::{
+ error::*,
+ pk11::{
+ slot::get_internal_slot,
+ types::{AlgorithmID, SymKey},
+ },
+};
+
+// Expose for consumers to choose the hashing algorithm
+// Currently only SHA256 supported
+pub use crate::pk11::context::HashAlgorithm;
+use nss_sys::SECOidTag;
+
+// ***** BASED ON THE FOLLOWING IMPLEMENTATION *****
+// https://searchfox.org/mozilla-central/rev/8ccea36c4fb09412609fb738c722830d7098602b/dom/crypto/WebCryptoTask.cpp#2567
+
+pub fn pbkdf2_key_derive(
+ password: &[u8],
+ salt: &[u8],
+ iterations: u32,
+ hash_algorithm: HashAlgorithm,
+ out: &mut [u8],
+) -> Result<()> {
+ assert_nss_initialized();
+ let oid_tag = match hash_algorithm {
+ HashAlgorithm::SHA256 => SECOidTag::SEC_OID_HMAC_SHA256 as u32,
+ HashAlgorithm::SHA384 => SECOidTag::SEC_OID_HMAC_SHA384 as u32,
+ };
+ let mut sec_salt = nss_sys::SECItem {
+ len: u32::try_from(salt.len())?,
+ data: salt.as_ptr() as *mut u8,
+ type_: 0,
+ };
+ let alg_id = unsafe {
+ AlgorithmID::from_ptr(nss_sys::PK11_CreatePBEV2AlgorithmID(
+ SECOidTag::SEC_OID_PKCS5_PBKDF2 as u32,
+ SECOidTag::SEC_OID_HMAC_SHA1 as u32,
+ oid_tag,
+ i32::try_from(out.len())?,
+ i32::try_from(iterations)?,
+ &mut sec_salt as *mut nss_sys::SECItem,
+ ))?
+ };
+
+ let slot = get_internal_slot()?;
+ let mut sec_pw = nss_sys::SECItem {
+ len: u32::try_from(password.len())?,
+ data: password.as_ptr() as *mut u8,
+ type_: 0,
+ };
+ let sym_key = unsafe {
+ SymKey::from_ptr(nss_sys::PK11_PBEKeyGen(
+ slot.as_mut_ptr(),
+ alg_id.as_mut_ptr(),
+ &mut sec_pw as *mut nss_sys::SECItem,
+ nss_sys::PR_FALSE,
+ std::ptr::null_mut(),
+ ))?
+ };
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_ExtractKeyValue(sym_key.as_mut_ptr()) })?;
+
+ // This doesn't leak, because the SECItem* returned by PK11_GetKeyData
+ // just refers to a buffer managed by `sym_key` which we copy into `buf`
+ let mut key_data = unsafe { *nss_sys::PK11_GetKeyData(sym_key.as_mut_ptr()) };
+ let buf = unsafe { sec_item_as_slice(&mut key_data)? };
+ // Stop panic in swap_with_slice by returning an error if the sizes mismatch
+ if buf.len() != out.len() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ out.swap_with_slice(buf);
+ Ok(())
+}
diff --git a/third_party/rust/nss/src/pk11/context.rs b/third_party/rust/nss/src/pk11/context.rs
@@ -0,0 +1,123 @@
+/* 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 crate::{
+ error::*,
+ pk11::{
+ sym_key::import_sym_key,
+ types::{Context, SymKey},
+ },
+ util::{assert_nss_initialized, map_nss_secstatus, ScopedPtr},
+};
+use std::ptr;
+
+#[derive(Copy, Clone, Debug)]
+#[repr(u8)]
+pub enum HashAlgorithm {
+ SHA256,
+ SHA384,
+}
+
+impl HashAlgorithm {
+ fn result_len(&self) -> u32 {
+ match self {
+ HashAlgorithm::SHA256 => nss_sys::SHA256_LENGTH,
+ HashAlgorithm::SHA384 => nss_sys::SHA384_LENGTH,
+ }
+ }
+
+ fn as_hmac_mechanism(&self) -> u32 {
+ match self {
+ HashAlgorithm::SHA256 => nss_sys::CKM_SHA256_HMAC,
+ HashAlgorithm::SHA384 => nss_sys::CKM_SHA384_HMAC,
+ }
+ }
+
+ pub(crate) fn as_hkdf_mechanism(&self) -> u32 {
+ match self {
+ HashAlgorithm::SHA256 => nss_sys::CKM_NSS_HKDF_SHA256,
+ HashAlgorithm::SHA384 => nss_sys::CKM_NSS_HKDF_SHA384,
+ }
+ }
+}
+
+impl From<&HashAlgorithm> for nss_sys::SECOidTag {
+ fn from(alg: &HashAlgorithm) -> Self {
+ match alg {
+ HashAlgorithm::SHA256 => nss_sys::SECOidTag::SEC_OID_SHA256,
+ HashAlgorithm::SHA384 => nss_sys::SECOidTag::SEC_OID_SHA384,
+ }
+ }
+}
+
+pub fn hash_buf(algorithm: &HashAlgorithm, data: &[u8]) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+ let result_len = usize::try_from(algorithm.result_len())?;
+ let mut out = vec![0u8; result_len];
+ let data_len = i32::try_from(data.len())?;
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_HashBuf(
+ Into::<nss_sys::SECOidTag>::into(algorithm) as u32,
+ out.as_mut_ptr(),
+ data.as_ptr(),
+ data_len,
+ )
+ })?;
+ Ok(out)
+}
+
+pub fn hmac_sign(digest_alg: &HashAlgorithm, sym_key_bytes: &[u8], data: &[u8]) -> Result<Vec<u8>> {
+ let mech = digest_alg.as_hmac_mechanism();
+ let sym_key = import_sym_key(mech.into(), nss_sys::CKA_SIGN.into(), sym_key_bytes)?;
+ let context = create_context_by_sym_key(mech.into(), nss_sys::CKA_SIGN.into(), &sym_key)?;
+ hash_buf_with_context(&context, data)
+}
+
+/// Similar to hash_buf except the consumer has to provide the digest context.
+fn hash_buf_with_context(context: &Context, data: &[u8]) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_DigestBegin(context.as_mut_ptr()) })?;
+ let data_len = u32::try_from(data.len())?;
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_DigestOp(context.as_mut_ptr(), data.as_ptr(), data_len)
+ })?;
+ // We allocate the maximum possible length for the out buffer then we'll
+ // slice it after nss fills `out_len`.
+ let mut out_len: u32 = 0;
+ let mut out = vec![0u8; nss_sys::HASH_LENGTH_MAX as usize];
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_DigestFinal(
+ context.as_mut_ptr(),
+ out.as_mut_ptr(),
+ &mut out_len,
+ nss_sys::HASH_LENGTH_MAX,
+ )
+ })?;
+ out.truncate(usize::try_from(out_len)?);
+ Ok(out)
+}
+
+/// Safe wrapper around PK11_CreateContextBySymKey that
+/// de-allocates memory when the context goes out of
+/// scope.
+pub fn create_context_by_sym_key(
+ mechanism: nss_sys::CK_MECHANISM_TYPE,
+ operation: nss_sys::CK_ATTRIBUTE_TYPE,
+ sym_key: &SymKey,
+) -> Result<Context> {
+ assert_nss_initialized();
+ let param = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: ptr::null_mut(),
+ len: 0,
+ };
+ unsafe {
+ Context::from_ptr(nss_sys::PK11_CreateContextBySymKey(
+ mechanism,
+ operation,
+ sym_key.as_mut_ptr(),
+ ¶m,
+ ))
+ }
+}
diff --git a/third_party/rust/nss/src/pk11/mod.rs b/third_party/rust/nss/src/pk11/mod.rs
@@ -0,0 +1,8 @@
+/* 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/. */
+
+pub mod context;
+pub mod slot;
+pub mod sym_key;
+pub mod types;
diff --git a/third_party/rust/nss/src/pk11/slot.rs b/third_party/rust/nss/src/pk11/slot.rs
@@ -0,0 +1,32 @@
+/* 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 crate::{
+ error::*,
+ pk11::types::Slot,
+ util::{assert_nss_initialized, map_nss_secstatus, ScopedPtr},
+};
+
+pub fn generate_random(data: &mut [u8]) -> Result<()> {
+ // `NSS_Init` will initialize the RNG with data from `/dev/urandom`.
+ assert_nss_initialized();
+ let len = i32::try_from(data.len())?;
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_GenerateRandom(data.as_mut_ptr(), len) })?;
+ Ok(())
+}
+
+/// Safe wrapper around `PK11_GetInternalSlot` that
+/// de-allocates memory when the slot goes out of
+/// scope.
+pub(crate) fn get_internal_slot() -> Result<Slot> {
+ unsafe { Slot::from_ptr(nss_sys::PK11_GetInternalSlot()) }
+}
+
+/// Safe wrapper around `PK11_GetInternalKeySlot` that
+/// de-allocates memory when the slot goes out of
+/// scope.
+#[cfg(feature = "keydb")]
+pub(crate) fn get_internal_key_slot() -> Result<Slot> {
+ unsafe { Slot::from_ptr(nss_sys::PK11_GetInternalKeySlot()) }
+}
diff --git a/third_party/rust/nss/src/pk11/sym_key.rs b/third_party/rust/nss/src/pk11/sym_key.rs
@@ -0,0 +1,277 @@
+/* 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(feature = "keydb")]
+use crate::util::get_last_error;
+use crate::{
+ error::*,
+ pk11::{context::HashAlgorithm, slot, types::SymKey},
+ util::{assert_nss_initialized, map_nss_secstatus, sec_item_as_slice, ScopedPtr},
+};
+#[cfg(feature = "keydb")]
+use std::ffi::{c_char, CString};
+use std::{
+ mem,
+ os::raw::{c_uchar, c_uint, c_ulong},
+ ptr,
+};
+
+pub fn hkdf_expand(
+ digest_alg: &HashAlgorithm,
+ key_bytes: &[u8],
+ info: &[u8],
+ len: usize,
+) -> Result<Vec<u8>> {
+ assert_nss_initialized();
+ let mech = digest_alg.as_hkdf_mechanism();
+ // Most of the following code is inspired by the Firefox WebCrypto implementation:
+ // https://searchfox.org/mozilla-central/rev/ee3905439acbf81e9c829ece0b46d09d2fa26c5c/dom/crypto/WebCryptoTask.cpp#2530-2597
+ // Except that we only do the expand part, which explains why we use null pointers below.
+ let mut hkdf_params = nss_sys::CK_NSS_HKDFParams {
+ bExtract: nss_sys::CK_FALSE,
+ pSalt: ptr::null_mut(),
+ ulSaltLen: 0,
+ bExpand: nss_sys::CK_TRUE,
+ pInfo: info.as_ptr() as *mut u8,
+ ulInfoLen: c_ulong::try_from(info.len())?,
+ };
+ let mut params = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: &mut hkdf_params as *mut _ as *mut c_uchar,
+ len: u32::try_from(mem::size_of::<nss_sys::CK_NSS_HKDFParams>())?,
+ };
+ let base_key = import_sym_key(mech.into(), nss_sys::CKA_WRAP.into(), key_bytes)?;
+ let derived_len = i32::try_from(len)?;
+ let sym_key = unsafe {
+ SymKey::from_ptr(
+ // CKM_SHA512_HMAC and CKA_SIGN are key type and usage attributes of the
+ // derived symmetric key and don't matter because we ignore them anyway.
+ nss_sys::PK11_Derive(
+ base_key.as_mut_ptr(),
+ mech.into(),
+ &mut params,
+ nss_sys::CKM_SHA512_HMAC.into(),
+ nss_sys::CKA_SIGN.into(),
+ derived_len,
+ ),
+ )?
+ };
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_ExtractKeyValue(sym_key.as_mut_ptr()) })?;
+ // SAFETY: This doesn't leak, because the SECItem* returned by PK11_GetKeyData just refers to a
+ // buffer managed by `sym_key` which we copy into `out`.
+ let mut key_data = unsafe { *nss_sys::PK11_GetKeyData(sym_key.as_mut_ptr()) };
+ if u32::try_from(len)? > key_data.len {
+ return Err(ErrorKind::InternalError.into());
+ }
+ let buf = unsafe { sec_item_as_slice(&mut key_data)? };
+ Ok(buf.to_vec())
+}
+
+/// Safe wrapper around PK11_ImportSymKey that
+/// de-allocates memory when the key goes out of
+/// scope.
+pub(crate) fn import_sym_key(
+ mechanism: nss_sys::CK_MECHANISM_TYPE,
+ operation: nss_sys::CK_ATTRIBUTE_TYPE,
+ buf: &[u8],
+) -> Result<SymKey> {
+ assert_nss_initialized();
+ let mut item = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: buf.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(buf.len())?,
+ };
+ let slot = slot::get_internal_slot()?;
+ unsafe {
+ SymKey::from_ptr(nss_sys::PK11_ImportSymKey(
+ slot.as_mut_ptr(),
+ mechanism,
+ nss_sys::PK11Origin::PK11_OriginUnwrap as u32,
+ operation,
+ &mut item,
+ ptr::null_mut(),
+ ))
+ }
+}
+
+/// Check weather a primary password has been set and NSS needs to be authenticated.
+/// Only available with the `keydb` feature.
+#[cfg(feature = "keydb")]
+pub fn authentication_with_primary_password_is_needed() -> Result<bool> {
+ let slot = slot::get_internal_key_slot()?;
+
+ unsafe {
+ Ok(
+ nss_sys::PK11_NeedLogin(slot.as_mut_ptr()) == nss_sys::PR_TRUE
+ && nss_sys::PK11_IsLoggedIn(slot.as_mut_ptr(), ptr::null_mut()) != nss_sys::PR_TRUE,
+ )
+ }
+}
+
+/// Authorize NSS key store against a user-provided primary password.
+/// Only available with the `keydb` feature.
+#[cfg(feature = "keydb")]
+pub fn authenticate_with_primary_password(primary_password: &str) -> Result<bool> {
+ let slot = slot::get_internal_key_slot()?;
+
+ let password_cstr = CString::new(primary_password).map_err(|_| ErrorKind::NulError)?;
+ unsafe {
+ Ok(
+ nss_sys::PK11_CheckUserPassword(slot.as_mut_ptr(), password_cstr.as_ptr())
+ == nss_sys::SECStatus::SECSuccess,
+ )
+ }
+}
+
+/// Retrieve a key, identified by `name`, from the internal NSS key store. If none exists, create
+/// one, persist, and return.
+/// Only available with the `keydb` feature.
+#[cfg(feature = "keydb")]
+pub fn get_or_create_aes256_key(name: &str) -> Result<Vec<u8>> {
+ let sym_key = match get_aes256_key(name) {
+ Ok(sym_key) => sym_key,
+ Err(_) => create_aes256_key(name)?,
+ };
+ let mut key_data = unsafe { *nss_sys::PK11_GetKeyData(sym_key.as_mut_ptr()) };
+ if key_data.len != nss_sys::AES_256_KEY_LENGTH {
+ return Err(ErrorKind::InvalidKeyLength.into());
+ }
+ let buf = unsafe { sec_item_as_slice(&mut key_data)? };
+ // SAFETY: `to_vec` copies the data out before there's any chance for `sym_key` to be
+ // destroyed.
+ Ok(buf.to_vec())
+}
+
+#[cfg(feature = "keydb")]
+fn get_aes256_key(name: &str) -> Result<SymKey> {
+ let slot = slot::get_internal_key_slot()?;
+ let name = CString::new(name).map_err(|_| ErrorKind::NulError)?;
+ let sym_key = unsafe {
+ SymKey::from_ptr(nss_sys::PK11_ListFixedKeysInSlot(
+ slot.as_mut_ptr(),
+ name.as_ptr() as *mut c_char,
+ ptr::null_mut(),
+ ))
+ };
+ match sym_key {
+ Ok(sym_key) => {
+ // See
+ // https://searchfox.org/mozilla-central/source/security/manager/ssl/NSSKeyStore.cpp#163-201
+ // Unfortunately we can't use PK11_ExtractKeyValue(symKey.get()) here because softoken
+ // marks all token objects of type CKO_SECRET_KEY as sensitive. So we have to wrap and
+ // unwrap symKey to obtain a non-sensitive copy of symKey as a session object.
+ let wrapping_key = unsafe {
+ SymKey::from_ptr(nss_sys::PK11_KeyGen(
+ slot.as_mut_ptr(),
+ nss_sys::CKM_AES_KEY_GEN,
+ ptr::null_mut(),
+ 16,
+ ptr::null_mut(),
+ ))
+ .map_err(|_| get_last_error())?
+ };
+ let mut wrap_len = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: ptr::null_mut(),
+ len: 0,
+ };
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_WrapSymKey(
+ nss_sys::CKM_AES_KEY_WRAP_KWP,
+ ptr::null_mut(),
+ wrapping_key.as_mut_ptr(),
+ sym_key.as_mut_ptr(),
+ &mut wrap_len,
+ )
+ })
+ .map_err(|_| get_last_error())?;
+ // PK11_UnwrapSymKey takes an int keySize
+ if wrap_len.len > u32::MAX - 8 {
+ return Err(ErrorKind::InvalidKeyLength.into());
+ }
+ // Allocate an extra 8 bytes for CKM_AES_KEY_WRAP_KWP overhead.
+ let wrapped_key = unsafe {
+ nss_sys::SECITEM_AllocItem(ptr::null_mut(), ptr::null_mut(), wrap_len.len + 8)
+ };
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_WrapSymKey(
+ nss_sys::CKM_AES_KEY_WRAP_KWP,
+ ptr::null_mut(),
+ wrapping_key.as_mut_ptr(),
+ sym_key.as_mut_ptr(),
+ wrapped_key,
+ )
+ })
+ .map_err(|_| get_last_error())?;
+ let sym_key = unsafe {
+ SymKey::from_ptr(nss_sys::PK11_UnwrapSymKey(
+ wrapping_key.as_mut_ptr(),
+ nss_sys::CKM_AES_KEY_WRAP_KWP,
+ ptr::null_mut(),
+ wrapped_key,
+ nss_sys::CKM_AES_GCM.into(),
+ (nss_sys::CKA_ENCRYPT | nss_sys::CKA_DECRYPT).into(),
+ wrap_len.len as i32,
+ ))
+ }
+ .map_err(|_| get_last_error())?;
+
+ map_nss_secstatus(|| unsafe { nss_sys::PK11_ExtractKeyValue(sym_key.as_mut_ptr()) })?;
+ Ok(sym_key)
+ }
+ Err(e) => Err(e),
+ }
+}
+
+#[cfg(feature = "keydb")]
+fn create_aes256_key(name: &str) -> Result<SymKey> {
+ let mut key_bytes: [u8; nss_sys::AES_256_KEY_LENGTH as usize] =
+ [0; nss_sys::AES_256_KEY_LENGTH as usize];
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_GenerateRandom(key_bytes.as_mut_ptr(), nss_sys::AES_256_KEY_LENGTH as i32)
+ })?;
+ match import_and_persist_sym_key(
+ nss_sys::CKM_AES_GCM.into(),
+ nss_sys::PK11Origin::PK11_OriginGenerated,
+ (nss_sys::CKA_ENCRYPT | nss_sys::CKA_DECRYPT).into(),
+ &key_bytes,
+ ) {
+ Ok(sym_key) => {
+ let name = CString::new(name).map_err(|_| ErrorKind::NulError)?;
+ unsafe { nss_sys::PK11_SetSymKeyNickname(sym_key.as_mut_ptr(), name.as_ptr()) };
+ Ok(sym_key)
+ }
+ Err(e) => Err(e),
+ }
+}
+
+/// Safe wrapper around PK11_ImportSymKey that
+/// de-allocates memory when the key goes out of
+/// scope, and persists key in key4.db.
+#[cfg(feature = "keydb")]
+fn import_and_persist_sym_key(
+ mechanism: nss_sys::CK_MECHANISM_TYPE,
+ origin: nss_sys::PK11Origin,
+ operation: nss_sys::CK_ATTRIBUTE_TYPE,
+ buf: &[u8],
+) -> Result<SymKey> {
+ let mut item = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: buf.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(buf.len())?,
+ };
+ let slot = slot::get_internal_key_slot()?;
+ unsafe {
+ SymKey::from_ptr(nss_sys::PK11_ImportSymKeyWithFlags(
+ slot.as_mut_ptr(),
+ mechanism,
+ origin as u32,
+ operation,
+ &mut item,
+ nss_sys::CK_FLAGS::default(),
+ nss_sys::PR_TRUE,
+ ptr::null_mut(),
+ ))
+ }
+}
diff --git a/third_party/rust/nss/src/pk11/types.rs b/third_party/rust/nss/src/pk11/types.rs
@@ -0,0 +1,229 @@
+/* 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 crate::{
+ error::*,
+ pk11::slot::{generate_random, get_internal_slot},
+ util::{map_nss_secstatus, ScopedPtr},
+};
+use std::{
+ ops::Deref,
+ os::raw::{c_int, c_uchar, c_uint, c_void},
+ ptr,
+};
+
+scoped_ptr!(SymKey, nss_sys::PK11SymKey, nss_sys::PK11_FreeSymKey);
+scoped_ptr!(
+ PrivateKey,
+ nss_sys::SECKEYPrivateKey,
+ nss_sys::SECKEY_DestroyPrivateKey
+);
+scoped_ptr!(
+ PublicKey,
+ nss_sys::SECKEYPublicKey,
+ nss_sys::SECKEY_DestroyPublicKey
+);
+scoped_ptr!(
+ GenericObject,
+ nss_sys::PK11GenericObject,
+ nss_sys::PK11_DestroyGenericObject
+);
+
+scoped_ptr!(
+ Certificate,
+ nss_sys::CERTCertificate,
+ nss_sys::CERT_DestroyCertificate
+);
+
+scoped_ptr!(Context, nss_sys::PK11Context, pk11_destroy_context_true);
+scoped_ptr!(Slot, nss_sys::PK11SlotInfo, nss_sys::PK11_FreeSlot);
+
+scoped_ptr!(
+ AlgorithmID,
+ nss_sys::SECAlgorithmID,
+ secoid_destroy_algorithm_id_true
+);
+
+#[inline]
+unsafe fn secoid_destroy_algorithm_id_true(alg_id: *mut nss_sys::SECAlgorithmID) {
+ nss_sys::SECOID_DestroyAlgorithmID(alg_id, nss_sys::PR_TRUE);
+}
+
+#[inline]
+unsafe fn pk11_destroy_context_true(context: *mut nss_sys::PK11Context) {
+ nss_sys::PK11_DestroyContext(context, nss_sys::PR_TRUE);
+}
+
+// Trait for types that have PCKS#11 attributes that are readable. See
+// https://searchfox.org/mozilla-central/rev/8ed8474757695cdae047150a0eaf94a5f1c96dbe/security/nss/lib/pk11wrap/pk11pub.h#842-864
+/// # Safety
+/// Unsafe since it needs to call [`nss_sys::PK11_ReadRawAttribute`] which is
+/// a C NSS function, and thus inherently unsafe to call
+pub(crate) unsafe trait Pkcs11Object: ScopedPtr {
+ const PK11_OBJECT_TYPE: nss_sys::PK11ObjectType;
+ fn read_raw_attribute(
+ &self,
+ attribute_type: nss_sys::CK_ATTRIBUTE_TYPE,
+ ) -> Result<ScopedSECItem> {
+ let mut out_sec = ScopedSECItem::empty(nss_sys::SECItemType::siBuffer);
+ map_nss_secstatus(|| unsafe {
+ nss_sys::PK11_ReadRawAttribute(
+ Self::PK11_OBJECT_TYPE as u32,
+ self.as_mut_ptr() as *mut c_void,
+ attribute_type,
+ out_sec.as_mut_ref(),
+ )
+ })?;
+ Ok(out_sec)
+ }
+}
+
+unsafe impl Pkcs11Object for GenericObject {
+ const PK11_OBJECT_TYPE: nss_sys::PK11ObjectType = nss_sys::PK11ObjectType::PK11_TypeGeneric;
+}
+unsafe impl Pkcs11Object for PrivateKey {
+ const PK11_OBJECT_TYPE: nss_sys::PK11ObjectType = nss_sys::PK11ObjectType::PK11_TypePrivKey;
+}
+unsafe impl Pkcs11Object for PublicKey {
+ const PK11_OBJECT_TYPE: nss_sys::PK11ObjectType = nss_sys::PK11ObjectType::PK11_TypePubKey;
+}
+unsafe impl Pkcs11Object for SymKey {
+ const PK11_OBJECT_TYPE: nss_sys::PK11ObjectType = nss_sys::PK11ObjectType::PK11_TypeSymKey;
+}
+
+// From https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_API_Guidelines#Thread_Safety:
+// "Data structures that are read only, like SECKEYPublicKeys or PK11SymKeys, need not be protected."
+unsafe impl Send for PrivateKey {}
+unsafe impl Send for PublicKey {}
+
+impl PrivateKey {
+ pub fn convert_to_public_key(&self) -> Result<PublicKey> {
+ Ok(unsafe { PublicKey::from_ptr(nss_sys::SECKEY_ConvertToPublicKey(self.as_mut_ptr()))? })
+ }
+
+ // To protect against key ID collisions, PrivateKeyFromPrivateKeyTemplate
+ // generates a random ID for each key. The given template must contain an
+ // attribute slot for a key ID, but it must consist of a null pointer and have a
+ // length of 0.
+ pub(crate) fn from_private_key_template(
+ mut template: Vec<nss_sys::CK_ATTRIBUTE>,
+ ) -> Result<Self> {
+ // Generate a random 160-bit object ID. This ID must be unique.
+ let mut obj_id_buf = vec![0u8; 160 / 8];
+ generate_random(&mut obj_id_buf)?;
+ let mut obj_id = nss_sys::SECItem {
+ type_: nss_sys::SECItemType::siBuffer as u32,
+ data: obj_id_buf.as_ptr() as *mut c_uchar,
+ len: c_uint::try_from(obj_id_buf.len())?,
+ };
+ let slot = get_internal_slot()?;
+ let mut pre_existing_key = unsafe {
+ nss_sys::PK11_FindKeyByKeyID(slot.as_mut_ptr(), &mut obj_id, std::ptr::null_mut())
+ };
+ if !pre_existing_key.is_null() {
+ // Note that we can't just call SECKEY_DestroyPrivateKey here because that
+ // will destroy the PKCS#11 object that is backing a preexisting key (that
+ // we still have a handle on somewhere else in memory). If that object were
+ // destroyed, cryptographic operations performed by that other key would
+ // fail.
+ unsafe {
+ destroy_private_key_without_destroying_pkcs11_object(pre_existing_key);
+ }
+ // Try again with a new ID (but only once - collisions are very unlikely).
+ generate_random(&mut obj_id_buf)?;
+ pre_existing_key = unsafe {
+ nss_sys::PK11_FindKeyByKeyID(slot.as_mut_ptr(), &mut obj_id, std::ptr::null_mut())
+ };
+ if !pre_existing_key.is_null() {
+ unsafe {
+ destroy_private_key_without_destroying_pkcs11_object(pre_existing_key);
+ }
+ return Err(ErrorKind::InternalError.into());
+ }
+ }
+ let template_len = c_int::try_from(template.len())?;
+ let id_attr: &mut nss_sys::CK_ATTRIBUTE = template
+ .iter_mut()
+ .find(|&&mut attr| {
+ attr.type_ == (nss_sys::CKA_ID as nss_sys::CK_ATTRIBUTE_TYPE)
+ && attr.pValue.is_null()
+ && attr.ulValueLen == 0
+ })
+ .ok_or(ErrorKind::InternalError)?;
+ id_attr.pValue = obj_id_buf.as_mut_ptr() as *mut c_void;
+ id_attr.ulValueLen = nss_sys::CK_ULONG::try_from(obj_id_buf.len())?;
+ // We use `PK11_CreateGenericObject` instead of `PK11_CreateManagedGenericObject`
+ // to leak the reference on purpose because `PK11_FindKeyByKeyID` will take
+ // ownership of it.
+ let _obj = unsafe {
+ GenericObject::from_ptr(nss_sys::PK11_CreateGenericObject(
+ slot.as_mut_ptr(),
+ template.as_mut_ptr(),
+ template_len,
+ nss_sys::PR_FALSE,
+ ))?
+ };
+ // Have NSS translate the object to a private key.
+ Ok(unsafe {
+ PrivateKey::from_ptr(nss_sys::PK11_FindKeyByKeyID(
+ slot.as_mut_ptr(),
+ &mut obj_id,
+ std::ptr::null_mut(),
+ ))?
+ })
+ }
+}
+
+// This is typically used by functions receiving a pointer to an `out SECItem`,
+// where we allocate the struct, but NSS allocates the elements it points to.
+pub(crate) struct ScopedSECItem {
+ wrapped: nss_sys::SECItem,
+}
+
+impl ScopedSECItem {
+ pub(crate) fn empty(r#type: nss_sys::SECItemType) -> Self {
+ ScopedSECItem {
+ wrapped: nss_sys::SECItem {
+ type_: r#type as u32,
+ data: ptr::null_mut(),
+ len: 0,
+ },
+ }
+ }
+
+ pub(crate) fn as_mut_ref(&mut self) -> &mut nss_sys::SECItem {
+ &mut self.wrapped
+ }
+}
+
+impl Deref for ScopedSECItem {
+ type Target = nss_sys::SECItem;
+ #[inline]
+ fn deref(&self) -> &nss_sys::SECItem {
+ &self.wrapped
+ }
+}
+
+impl Drop for ScopedSECItem {
+ fn drop(&mut self) {
+ unsafe {
+ // PR_FALSE asks the NSS allocator not to free the SECItem
+ // itself, and just the pointee of `self.wrapped.data`.
+ nss_sys::SECITEM_FreeItem(&mut self.wrapped, nss_sys::PR_FALSE);
+ }
+ }
+}
+
+// This helper function will release the memory backing a SECKEYPrivateKey and
+// any resources acquired in its creation. It will leave the backing PKCS#11
+// object untouched, however. This should only be called from
+// PrivateKeyFromPrivateKeyTemplate.
+// From: https://searchfox.org/mozilla-central/rev/444ee13e14fe30451651c0f62b3979c76766ada4/dom/crypto/CryptoKey.cpp#80
+unsafe fn destroy_private_key_without_destroying_pkcs11_object(
+ key: *mut nss_sys::SECKEYPrivateKey,
+) {
+ assert!(!key.is_null());
+ nss_sys::PK11_FreeSlot((*key).pkcs11Slot);
+ nss_sys::PORT_FreeArena((*key).arena, nss_sys::PR_TRUE);
+}
diff --git a/third_party/rust/nss/src/pkixc.rs b/third_party/rust/nss/src/pkixc.rs
@@ -0,0 +1,101 @@
+/* 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 crate::error::*;
+use crate::util::assert_nss_initialized;
+
+use nss_sys::PRErrorCode;
+
+// NSS error codes.
+// https://searchfox.org/mozilla-central/rev/352b525/security/nss/lib/util/secerr.h#29
+const SEC_ERROR_BASE: i32 = -0x2000; // -8192
+const SEC_ERROR_EXPIRED_CERTIFICATE: i32 = SEC_ERROR_BASE + 11;
+const SEC_ERROR_UNKNOWN_ISSUER: i32 = SEC_ERROR_BASE + 13;
+const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: i32 = SEC_ERROR_BASE + 30;
+
+// SSL error codes.
+// https://searchfox.org/mozilla-central/rev/352b525/security/nss/lib/ssl/sslerr.h#42
+const SSL_ERROR_BASE: i32 = -0x3000; // -12288
+const SSL_ERROR_BAD_CERT_DOMAIN: i32 = SSL_ERROR_BASE + 12;
+
+// PKIX error codes.
+// https://searchfox.org/mozilla-central/rev/352b525/security/nss/lib/mozpkix/include/pkix/pkixnss.h#81
+const PKIX_ERROR_BASE: i32 = -0x4000; // -16384
+const PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: i32 = PKIX_ERROR_BASE + 5;
+const PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE: i32 = PKIX_ERROR_BASE + 6;
+
+const ROOT_HASH_LENGTH: usize = 32;
+
+pub fn verify_code_signing_certificate_chain(
+ certificates: Vec<&[u8]>,
+ seconds_since_epoch: u64,
+ root_sha256_hash: &[u8],
+ hostname: &str,
+) -> Result<()> {
+ assert_nss_initialized();
+
+ let mut cert_lens: Vec<u16> = vec![];
+ for certificate in &certificates {
+ match u16::try_from(certificate.len()) {
+ Ok(v) => cert_lens.push(v),
+ Err(e) => {
+ return Err(ErrorKind::InputError(format!(
+ "certificate length is more than 65536 bytes: {}",
+ e
+ ))
+ .into());
+ }
+ }
+ }
+
+ let mut p_certificates: Vec<_> = certificates.iter().map(|c| c.as_ptr()).collect();
+
+ if root_sha256_hash.len() != ROOT_HASH_LENGTH {
+ return Err(ErrorKind::InputError(format!(
+ "root hash contains {} bytes instead of {}",
+ root_sha256_hash.len(),
+ ROOT_HASH_LENGTH
+ ))
+ .into());
+ }
+
+ let mut out: PRErrorCode = 0;
+
+ let result = unsafe {
+ nss_sys::VerifyCodeSigningCertificateChain(
+ p_certificates.as_mut_ptr(), // Ideally the exposed API should not require mutability here.
+ cert_lens.as_ptr(),
+ certificates.len(),
+ seconds_since_epoch,
+ root_sha256_hash.as_ptr(),
+ hostname.as_ptr(),
+ hostname.len(),
+ &mut out,
+ )
+ };
+
+ if !result {
+ let kind = match out {
+ SEC_ERROR_UNKNOWN_ISSUER => ErrorKind::CertificateIssuerError,
+ SEC_ERROR_EXPIRED_CERTIFICATE => ErrorKind::CertificateValidityError,
+ SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE => ErrorKind::CertificateValidityError,
+ PKIX_ERROR_NOT_YET_VALID_CERTIFICATE => ErrorKind::CertificateValidityError,
+ PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE => ErrorKind::CertificateValidityError,
+ SSL_ERROR_BAD_CERT_DOMAIN => ErrorKind::CertificateSubjectError,
+ _ => {
+ let msg = "invalid chain of trust".to_string();
+ if SSL_ERROR_BASE < out && out < SSL_ERROR_BASE + 1000 {
+ ErrorKind::SSLError(out, msg)
+ } else if PKIX_ERROR_BASE < out && out < PKIX_ERROR_BASE + 1000 {
+ ErrorKind::PKIXError(out, msg)
+ } else {
+ ErrorKind::NSSError(out, msg)
+ }
+ }
+ };
+ return Err(kind.into());
+ }
+
+ Ok(())
+}
diff --git a/third_party/rust/nss/src/secport.rs b/third_party/rust/nss/src/secport.rs
@@ -0,0 +1,24 @@
+/* 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 crate::error::*;
+use crate::util::assert_nss_initialized;
+use std::os::raw::c_void;
+
+pub fn secure_memcmp(a: &[u8], b: &[u8]) -> Result<bool> {
+ assert_nss_initialized();
+ // NSS_SecureMemcmp will compare N elements fron our slices,
+ // so make sure they are the same length first.
+ if a.len() != b.len() {
+ return Ok(false);
+ }
+ let result = unsafe {
+ nss_sys::NSS_SecureMemcmp(
+ a.as_ptr() as *const c_void,
+ b.as_ptr() as *const c_void,
+ a.len(),
+ )
+ };
+ Ok(result == 0)
+}
diff --git a/third_party/rust/nss/src/util.rs b/third_party/rust/nss/src/util.rs
@@ -0,0 +1,282 @@
+/* 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 crate::error::*;
+use nss_sys::*;
+use std::{ffi::CString, os::raw::c_char};
+
+use std::path::PathBuf;
+use std::sync::OnceLock;
+
+#[cfg(feature = "keydb")]
+use crate::pk11::slot;
+
+// This is the NSS version that this crate is claiming to be compatible with.
+// We check it at runtime using `NSS_VersionCheck`.
+pub const COMPATIBLE_NSS_VERSION: &str = "3.26";
+
+// Expect NSS has been initialized. This is usually be done via `init_rust_components`, see
+// components/init_rust_components/README.md.
+pub fn assert_nss_initialized() {
+ INITIALIZED.get().expect(
+ "NSS has not initialized.
+ Please ensure you include the initialization component and call it early in your code. See
+ https://mozilla.github.io/application-services/book/rust-docs/init_rust_components/index.html",
+ );
+}
+
+// This and many other nss init code were either taken directly from or are inspired by
+// https://github.com/mozilla/neqo/blob/b931a289eee7d62c0815535f01cfa34c5a929f9d/neqo-crypto/src/lib.rs#L73-L77
+enum NssLoaded {
+ External,
+ NoDb,
+ #[cfg(feature = "keydb")]
+ Db,
+}
+
+static INITIALIZED: OnceLock<NssLoaded> = OnceLock::new();
+
+fn assert_compatible_version() {
+ let min_ver = CString::new(COMPATIBLE_NSS_VERSION).unwrap();
+ if unsafe { NSS_VersionCheck(min_ver.as_ptr()) } == PR_FALSE {
+ panic!("Incompatible NSS version!")
+ }
+}
+
+fn init_once(profile_path: Option<PathBuf>) -> NssLoaded {
+ assert_compatible_version();
+
+ if unsafe { NSS_IsInitialized() != PR_FALSE } {
+ return NssLoaded::External;
+ }
+
+ match profile_path {
+ #[cfg(feature = "keydb")]
+ Some(path) => {
+ if !path.is_dir() {
+ panic!("missing profile directory {:?}", path);
+ }
+ let pathstr = path.to_str().expect("invalid path");
+ let dircstr = CString::new(pathstr).expect("could not build CString from path");
+ let empty = CString::new("").expect("could not build empty CString");
+ let flags = NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE;
+
+ let context = unsafe {
+ NSS_InitContext(
+ dircstr.as_ptr(),
+ empty.as_ptr(),
+ empty.as_ptr(),
+ empty.as_ptr(),
+ std::ptr::null_mut(),
+ flags,
+ )
+ };
+ if context.is_null() {
+ let error = get_last_error();
+ panic!("could not initialize context: {}", error);
+ }
+
+ let slot = slot::get_internal_key_slot().expect("could not get internal key slot");
+
+ if unsafe { PK11_NeedUserInit(slot.as_mut_ptr()) } == nss_sys::PR_TRUE {
+ let result = unsafe {
+ PK11_InitPin(
+ slot.as_mut_ptr(),
+ std::ptr::null_mut(),
+ std::ptr::null_mut(),
+ )
+ };
+ if result != SECStatus::SECSuccess {
+ let error = get_last_error();
+ panic!("could not initialize context: {}", error);
+ }
+ }
+
+ NssLoaded::Db
+ }
+
+ #[cfg(not(feature = "keydb"))]
+ Some(_) => panic!("Use the keydb feature to enable nss initialization with profile path"),
+
+ None => {
+ let empty = CString::default();
+ let flags = NSS_INIT_READONLY
+ | NSS_INIT_NOCERTDB
+ | NSS_INIT_NOMODDB
+ | NSS_INIT_FORCEOPEN
+ | NSS_INIT_OPTIMIZESPACE;
+ let context = unsafe {
+ NSS_InitContext(
+ empty.as_ptr(),
+ empty.as_ptr(),
+ empty.as_ptr(),
+ empty.as_ptr(),
+ std::ptr::null_mut(),
+ flags,
+ )
+ };
+ if context.is_null() {
+ let error = get_last_error();
+ panic!("Could not initialize NSS: {}", error);
+ }
+
+ NssLoaded::NoDb
+ }
+ }
+}
+
+/// Initialize NSS. This only executes the initialization routines once, so if there is any chance
+/// that this is invoked twice, that's OK.
+///
+/// # Errors
+///
+/// When NSS initialization fails.
+pub fn ensure_nss_initialized() {
+ INITIALIZED.get_or_init(|| init_once(None));
+}
+
+/// Use this function to initialize NSS if you want to manage keys with NSS.
+/// ensure_initialized_with_profile_dir initializes NSS with a profile directory (where key4.db
+/// will be stored) and appropriate flags to persist keys (and certificates) in its internal PKCS11
+/// software implementation.
+/// If it has been called previously with a different path, it will fail.
+/// If `ensure_initialized` has been called before, it will also fail.
+#[cfg(feature = "keydb")]
+pub fn ensure_nss_initialized_with_profile_dir<P: Into<PathBuf>>(dir: P) {
+ INITIALIZED.get_or_init(|| init_once(Some(dir.into())));
+}
+
+pub fn map_nss_secstatus<F>(callback: F) -> Result<()>
+where
+ F: FnOnce() -> SECStatus,
+{
+ if callback() == SECStatus::SECSuccess {
+ return Ok(());
+ }
+ Err(get_last_error())
+}
+
+/// Retrieve and wrap the last NSS/NSPR error in the current thread.
+#[cold]
+pub fn get_last_error() -> Error {
+ let error_code = unsafe { PR_GetError() };
+ let error_text: String = usize::try_from(unsafe { PR_GetErrorTextLength() })
+ .map(|error_text_len| {
+ let mut out_str = vec![0u8; error_text_len + 1];
+ unsafe { PR_GetErrorText(out_str.as_mut_ptr() as *mut c_char) };
+ CString::new(&out_str[0..error_text_len])
+ .unwrap_or_else(|_| CString::default())
+ .to_str()
+ .unwrap_or("")
+ .to_owned()
+ })
+ .unwrap_or_else(|_| "".to_string());
+ ErrorKind::NSSError(error_code, error_text).into()
+}
+
+pub(crate) trait ScopedPtr
+where
+ Self: std::marker::Sized,
+{
+ type RawType;
+ unsafe fn from_ptr(ptr: *mut Self::RawType) -> Result<Self>;
+ fn as_ptr(&self) -> *const Self::RawType;
+ fn as_mut_ptr(&self) -> *mut Self::RawType;
+}
+
+// The macro defines a wrapper around pointers referring to types allocated by NSS,
+// calling their NSS destructor method when they go out of scope to avoid memory leaks.
+// The `as_ptr`/`as_mut_ptr` are provided to retrieve the raw pointers to pass to
+// NSS functions that consume them.
+#[macro_export]
+macro_rules! scoped_ptr {
+ ($scoped:ident, $target:ty, $dtor:path) => {
+ pub struct $scoped {
+ ptr: *mut $target,
+ }
+
+ impl $crate::util::ScopedPtr for $scoped {
+ type RawType = $target;
+
+ #[allow(dead_code)]
+ unsafe fn from_ptr(ptr: *mut $target) -> $crate::error::Result<$scoped> {
+ if !ptr.is_null() {
+ Ok($scoped { ptr })
+ } else {
+ Err($crate::error::ErrorKind::InternalError.into())
+ }
+ }
+
+ #[inline]
+ fn as_ptr(&self) -> *const $target {
+ self.ptr
+ }
+
+ #[inline]
+ fn as_mut_ptr(&self) -> *mut $target {
+ self.ptr
+ }
+ }
+
+ impl Drop for $scoped {
+ fn drop(&mut self) {
+ assert!(!self.ptr.is_null());
+ unsafe { $dtor(self.ptr) };
+ }
+ }
+ };
+}
+
+/// Copies a SECItem into a slice
+///
+/// # Safety
+///
+/// The returned reference must not outlive the `sym_key`, since that owns the `SecItem` buffer.
+pub(crate) unsafe fn sec_item_as_slice(sec_item: &mut SECItem) -> Result<&mut [u8]> {
+ let sec_item_buf_len = usize::try_from(sec_item.len)?;
+ let buf = std::slice::from_raw_parts_mut(sec_item.data, sec_item_buf_len);
+ Ok(buf)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use std::thread;
+
+ #[test]
+ fn test_assert_initialized() {
+ ensure_nss_initialized();
+ assert_nss_initialized();
+ }
+
+ #[cfg(feature = "keydb")]
+ #[test]
+ fn test_assert_initialized_with_profile_dir() {
+ ensure_nss_initialized_with_profile_dir("./");
+ assert_nss_initialized();
+ }
+
+ #[test]
+ fn test_ensure_initialized_multithread() {
+ let threads: Vec<_> = (0..2)
+ .map(|_| thread::spawn(ensure_nss_initialized))
+ .collect();
+
+ for handle in threads {
+ handle.join().unwrap();
+ }
+ }
+
+ #[cfg(feature = "keydb")]
+ #[test]
+ fn test_ensure_initialized_with_profile_dir_multithread() {
+ let threads: Vec<_> = (0..2)
+ .map(|_| thread::spawn(move || ensure_nss_initialized_with_profile_dir("./")))
+ .collect();
+
+ for handle in threads {
+ handle.join().unwrap();
+ }
+ }
+}
diff --git a/third_party/rust/nss_build_common/.cargo-checksum.json b/third_party/rust/nss_build_common/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"59bb44e9fda258667a117c29c7ebe563eba3a69dd5aa63b04a8303e311f0c5c6","src/lib.rs":"0086dca9a1c0f0b3ea67bcb5881583fd877912bfc3657620544d52982d3ebf2d"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/nss_build_common/Cargo.toml b/third_party/rust/nss_build_common/Cargo.toml
@@ -0,0 +1,30 @@
+# 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 = "nss_build_common"
+version = "0.1.0"
+authors = ["Thom Chiovoloni <tchiovoloni@mozilla.com>"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = false
+license = "MPL-2.0"
+
+[lib]
+name = "nss_build_common"
+path = "src/lib.rs"
+
+[dependencies]
diff --git a/third_party/rust/nss_build_common/src/lib.rs b/third_party/rust/nss_build_common/src/lib.rs
@@ -0,0 +1,193 @@
+/* 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/. */
+
+//! This shouldn't exist, but does because if something isn't going to link
+//! against `nss` but has an `nss`-enabled `sqlcipher` turned on (for example,
+//! by a `cargo` feature activated by something else in the workspace).
+//! it might need to issue link commands for NSS.
+
+use std::{
+ env,
+ ffi::OsString,
+ path::{Path, PathBuf},
+};
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub enum LinkingKind {
+ Dynamic { folded_libs: bool },
+ Static,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct NoNssDir;
+
+pub fn link_nss() -> Result<(), NoNssDir> {
+ let is_gecko = env::var_os("MOZ_TOPOBJDIR").is_some();
+ if !is_gecko {
+ let (lib_dir, include_dir) = get_nss()?;
+ println!(
+ "cargo:rustc-link-search=native={}",
+ lib_dir.to_string_lossy()
+ );
+ println!("cargo:include={}", include_dir.to_string_lossy());
+ let kind = determine_kind();
+ link_nss_libs(kind);
+ } else {
+ let libs = match env::var("CARGO_CFG_TARGET_OS")
+ .as_ref()
+ .map(std::string::String::as_str)
+ {
+ Ok("android") | Ok("macos") => vec!["nss3"],
+ _ => vec!["nssutil3", "nss3", "plds4", "plc4", "nspr4"],
+ };
+ for lib in &libs {
+ println!("cargo:rustc-link-lib=dylib={}", lib);
+ }
+ }
+ Ok(())
+}
+
+fn get_nss() -> Result<(PathBuf, PathBuf), NoNssDir> {
+ let nss_dir = env("NSS_DIR").ok_or(NoNssDir)?;
+ let nss_dir = Path::new(&nss_dir);
+ if !nss_dir.exists() {
+ println!(
+ "NSS_DIR path (obtained via `env`) does not exist: {}",
+ nss_dir.display()
+ );
+ panic!("It looks like NSS is not built. Please run `libs/verify-[platform]-environment.sh` first!");
+ }
+ let lib_dir = nss_dir.join("lib");
+ let include_dir = nss_dir.join("include");
+ Ok((lib_dir, include_dir))
+}
+
+fn determine_kind() -> LinkingKind {
+ if env_flag("NSS_STATIC") {
+ LinkingKind::Static
+ } else {
+ let folded_libs = env_flag("NSS_USE_FOLDED_LIBS");
+ LinkingKind::Dynamic { folded_libs }
+ }
+}
+
+fn link_nss_libs(kind: LinkingKind) {
+ let libs = get_nss_libs(kind);
+ // Emit -L flags
+ let kind_str = match kind {
+ LinkingKind::Dynamic { .. } => "dylib",
+ LinkingKind::Static => "static",
+ };
+ for lib in libs {
+ println!("cargo:rustc-link-lib={}={}", kind_str, lib);
+ }
+ // Link against C++ stdlib (for mozpkix)
+ let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
+ if target_os == "android" || target_os == "linux" {
+ println!("cargo:rustc-link-lib=stdc++");
+ } else {
+ println!("cargo:rustc-link-lib=c++");
+ }
+ let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
+ if target_arch == "x86_64" && target_os == "android" {
+ let android_home = env::var("ANDROID_HOME").expect("ANDROID_HOME not set");
+ const ANDROID_NDK_VERSION: &str = "28.2.13676358";
+ // One of these will exist, depending on the host platform.
+ const DARWIN_X86_64_LIB_DIR: &str =
+ "/toolchains/llvm/prebuilt/darwin-x86_64/lib/clang/19/lib/linux/";
+ println!("cargo:rustc-link-search={android_home}/ndk/{ANDROID_NDK_VERSION}/{DARWIN_X86_64_LIB_DIR}");
+ const LINUX_X86_64_LIB_DIR: &str =
+ "/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/19/lib/linux/";
+ println!("cargo:rustc-link-search={android_home}/ndk/{ANDROID_NDK_VERSION}/{LINUX_X86_64_LIB_DIR}");
+ println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
+ }
+}
+
+fn get_nss_libs(kind: LinkingKind) -> Vec<&'static str> {
+ match kind {
+ LinkingKind::Static => {
+ let mut static_libs = vec![
+ "certdb",
+ "certhi",
+ "cryptohi",
+ "freebl_static",
+ "mozpkix",
+ "nspr4",
+ "nss_static",
+ "nssb",
+ "nssdev",
+ "nsspki",
+ "nssutil",
+ "pk11wrap_static",
+ "plc4",
+ "plds4",
+ "softokn_static",
+ ];
+ // Hardware specific libs.
+ let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
+ let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
+ // https://searchfox.org/nss/rev/0d5696b3edce5124353f03159d2aa15549db8306/lib/freebl/freebl.gyp#508-542
+ if target_arch == "arm" || target_arch == "aarch64" {
+ static_libs.push("armv8_c_lib");
+ }
+ if target_arch == "x86_64" || target_arch == "x86" {
+ static_libs.push("gcm-aes-x86_c_lib");
+ static_libs.push("sha-x86_c_lib");
+ }
+ if target_arch == "arm" {
+ static_libs.push("gcm-aes-arm32-neon_c_lib")
+ }
+ if target_arch == "aarch64" {
+ static_libs.push("gcm-aes-aarch64_c_lib");
+ }
+ if target_arch == "x86_64" {
+ static_libs.push("hw-acc-crypto-avx");
+ static_libs.push("hw-acc-crypto-avx2");
+ }
+ // https://searchfox.org/nss/rev/08c4d05078d00089f8d7540651b0717a9d66f87e/lib/freebl/freebl.gyp#315-324
+ if ((target_os == "android" || target_os == "linux") && target_arch == "x86_64")
+ || target_os == "windows"
+ {
+ static_libs.push("intel-gcm-wrap_c_lib");
+ // https://searchfox.org/nss/rev/08c4d05078d00089f8d7540651b0717a9d66f87e/lib/freebl/freebl.gyp#43-47
+ if (target_os == "android" || target_os == "linux") && target_arch == "x86_64" {
+ static_libs.push("intel-gcm-s_lib");
+ }
+ }
+ static_libs
+ }
+ LinkingKind::Dynamic { folded_libs } => {
+ let mut dylibs = vec!["freebl3", "nss3", "nssckbi", "softokn3"];
+ if !folded_libs {
+ dylibs.append(&mut vec!["nspr4", "nssutil3", "plc4", "plds4"]);
+ }
+ dylibs
+ }
+ }
+}
+
+pub fn env(name: &str) -> Option<OsString> {
+ println!("cargo:rerun-if-env-changed={}", name);
+ env::var_os(name)
+}
+
+pub fn env_str(name: &str) -> Option<String> {
+ println!("cargo:rerun-if-env-changed={}", name);
+ env::var(name).ok()
+}
+
+pub fn env_flag(name: &str) -> bool {
+ match env_str(name).as_ref().map(String::as_ref) {
+ Some("1") => true,
+ Some("0") => false,
+ Some(s) => {
+ println!(
+ "cargo:warning=unknown value for environment var {:?}: {:?}. Ignoring",
+ name, s
+ );
+ false
+ }
+ None => false,
+ }
+}
diff --git a/third_party/rust/nss_sys/.cargo-checksum.json b/third_party/rust/nss_sys/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"fadb4d4c210bd6bfb89552c4421f22151acdbbc1fc72f4eb97c7bceb271385e8","README.md":"5f931f614978589f2343ad2ae405e21ccf49496d4593f3fec818b1a9bc2f194b","build.rs":"b541496d108a9e85545b9ee28c84790aa5b361805f691a082403233588423fd0","src/bindings/blapit.rs":"9f83f4d66c7164f75d714ea569714a36c2d2e9fda981e3aa1b890c54567c9e79","src/bindings/certdb.rs":"00411907215d7b427952a0200f91e4c564158fc5883cdb7332d92afcb424375b","src/bindings/keyhi.rs":"cdf9c3735343a718f86cfe5f822530dc7c7e4fc2c36e2a11797d9054dd0bfd05","src/bindings/keythi.rs":"ea9a1a8c33c3f2b8b78bd58d8d627d9f8d8c22ee4e1cd26c78701106bf0db69f","src/bindings/mod.rs":"c5cefb78172bd7bc1650123edf92f7005bb5e74ed090beaa73772c1b2fd26cf6","src/bindings/nss.rs":"c221cfcdaf00e9e024b335ff137d4df5feca5d3e30af0fe680e6feac33450ed7","src/bindings/pk11pub.rs":"c49d433cc87a9039ee5a278ca0a1e8d90c2406f1d05bc0001be2eb9e34b6ca53","src/bindings/pkcs11n.rs":"bc1ba0d903891d5331aeb6b1921fde7c2cd31cbbe75338e145b5aaff5c94c147","src/bindings/pkcs11t.rs":"5d84bfd36df100b026b6ddf4c48b75f2b0f3475108ba309985341c228f9e6955","src/bindings/pkixc.rs":"61d2bf93ad07ada57338dbf4f3418f782502e76a316759044ab20e80c284016d","src/bindings/plarena.rs":"8de09e3c378df457988729ca4d58e1ef1f2883dfa68e62acb79a55fb19a9d6f5","src/bindings/prerror.rs":"b7bda8a6511c43f59351a17f4311ceb272231a55473895b999a34e3a3ff76722","src/bindings/prtypes.rs":"5afd17e4d24880609320f8cc5a9c06f57ac766524ca5f6cbc5edc65195974c6e","src/bindings/secasn1t.rs":"5a79f0a4057fb934786ef9407c7b134c7bc2f3560f9af0d58dd27ede62c66391","src/bindings/seccomon.rs":"1538dc6226e3c731e3028b6e3859de7f51c7bf996b0a48e9019c766187c61576","src/bindings/secitem.rs":"7a1593f87dcbb4d9ef462fda9932486d169bea9f12b4ed83e3a7102d0b33127e","src/bindings/seckey.rs":"dd7b90e263c19855e38f6df657d60c532a509a3a9180acddc8f5f612da76889b","src/bindings/secmodt.rs":"f1c002df25b598e6fbed5285c98c0d8cfe4188254ca31f829cb993d321a4f6d0","src/bindings/secoid.rs":"1a1e3d8106c26d081daa56b22f6214b6b2456e14f6d5b34db77bb428e7dc4525","src/bindings/secoidt.rs":"d3841fa00100d081fd355ef65d8ff10e2341440715c937017d795fc7efd0d31d","src/bindings/secport.rs":"6b9c691f7a80467ad2db76e2168d9dceee781e5edaadd48b76e66852f632db12","src/lib.rs":"3081488f34b747cbe852e6692389db5df3dae65b180558aa7af9bf6ae809faa2"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/nss_sys/Cargo.toml b/third_party/rust/nss_sys/Cargo.toml
@@ -0,0 +1,45 @@
+# 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 = "nss_sys"
+version = "0.1.0"
+authors = ["Sync Team <sync-team@mozilla.com>"]
+build = "build.rs"
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = "README.md"
+license = "MPL-2.0"
+
+[features]
+default = []
+gecko = []
+
+[lib]
+name = "nss_sys"
+crate-type = ["lib"]
+path = "src/lib.rs"
+
+[dependencies.libsqlite3-sys]
+version = "0.35.0"
+features = ["bundled"]
+
+[build-dependencies.nss_build_common]
+path = "../nss_build_common"
+
+[lints.rust.unexpected_cfgs]
+level = "warn"
+priority = 0
+check-cfg = ["cfg(__appsvc_ci_hack)"]
diff --git a/third_party/rust/nss_sys/README.md b/third_party/rust/nss_sys/README.md
@@ -0,0 +1,18 @@
+## nss_sys
+
+Low-level NSS bindings for Rust.
+
+This crate defines low-level FFI bindings for NSS. They are maintained by hand.
+
+The directory structure of this crate is meant to mirror that of NSS itself.
+For each header file provided by NSS, there should be a corresponding `.rs` file
+in the `nss_sys::bindings` module that declares the corresponding functions and
+data types.
+
+To add new bindings in this crate, you'll need to:
+
+* Identify the NSS header file that contains the functionality of interest.
+* Edit the Rust file of the corresponding name under `./src/bindings`.
+ * If one doesn't currently exist then create it.
+* Add `#[recpr(C)]` structs and `pub extern "C"` functions as necessary to make the
+ new functionality visible to Rust.
diff --git a/third_party/rust/nss_sys/build.rs b/third_party/rust/nss_sys/build.rs
@@ -0,0 +1,7 @@
+/* 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/. */
+
+fn main() {
+ nss_build_common::link_nss().unwrap();
+}
diff --git a/third_party/rust/nss_sys/src/bindings/blapit.rs b/third_party/rust/nss_sys/src/bindings/blapit.rs
@@ -0,0 +1,10 @@
+/* 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/. */
+
+pub const EC_POINT_FORM_UNCOMPRESSED: u32 = 4;
+pub const SHA256_LENGTH: u32 = 32;
+pub const SHA384_LENGTH: u32 = 48;
+pub const HASH_LENGTH_MAX: u32 = 64;
+pub const AES_BLOCK_SIZE: u32 = 16;
+pub const AES_256_KEY_LENGTH: u32 = 32;
diff --git a/third_party/rust/nss_sys/src/bindings/certdb.rs b/third_party/rust/nss_sys/src/bindings/certdb.rs
@@ -0,0 +1,24 @@
+/* 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 crate::*;
+use std::os::raw::c_char;
+
+// Opaque types
+pub type CERTCertDBHandle = u8;
+pub type CERTCertificate = u8;
+
+extern "C" {
+ pub fn CERT_GetDefaultCertDB() -> *mut CERTCertDBHandle;
+
+ pub fn CERT_NewTempCertificate(
+ handle: *mut CERTCertDBHandle,
+ derCert: *mut SECItem,
+ nickname: *mut c_char,
+ isperm: PRBool,
+ copyDER: PRBool,
+ ) -> *mut CERTCertificate;
+
+ pub fn CERT_DestroyCertificate(cert: *mut CERTCertificate);
+}
diff --git a/third_party/rust/nss_sys/src/bindings/keyhi.rs b/third_party/rust/nss_sys/src/bindings/keyhi.rs
@@ -0,0 +1,12 @@
+/* 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 crate::*;
+
+extern "C" {
+ pub fn SECKEY_CopyPublicKey(pubKey: *const SECKEYPublicKey) -> *mut SECKEYPublicKey;
+ pub fn SECKEY_ConvertToPublicKey(privateKey: *mut SECKEYPrivateKey) -> *mut SECKEYPublicKey;
+ pub fn SECKEY_DestroyPrivateKey(key: *mut SECKEYPrivateKey);
+ pub fn SECKEY_DestroyPublicKey(key: *mut SECKEYPublicKey);
+}
diff --git a/third_party/rust/nss_sys/src/bindings/keythi.rs b/third_party/rust/nss_sys/src/bindings/keythi.rs
@@ -0,0 +1,140 @@
+/* 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 crate::*;
+use std::os::raw::{c_int, c_uchar, c_void};
+
+pub type SECKEYPublicKey = SECKEYPublicKeyStr;
+#[repr(C)]
+pub struct SECKEYPublicKeyStr {
+ pub arena: *mut PLArenaPool,
+ pub keyType: u32, /* KeyType */
+ pub pkcs11Slot: *mut PK11SlotInfo,
+ pub pkcs11ID: CK_OBJECT_HANDLE,
+ pub u: SECKEYPublicKeyStr_u,
+}
+
+#[repr(C)]
+pub union SECKEYPublicKeyStr_u {
+ pub rsa: SECKEYRSAPublicKey,
+ pub dsa: SECKEYDSAPublicKey,
+ pub dh: SECKEYDHPublicKey,
+ pub kea: SECKEYKEAPublicKey,
+ pub fortezza: SECKEYFortezzaPublicKey,
+ pub ec: SECKEYECPublicKey,
+}
+
+pub type SECKEYPrivateKey = SECKEYPrivateKeyStr;
+#[repr(C)]
+pub struct SECKEYPrivateKeyStr {
+ pub arena: *mut PLArenaPool,
+ pub keyType: u32, /* KeyType */
+ pub pkcs11Slot: *mut PK11SlotInfo,
+ pub pkcs11ID: CK_OBJECT_HANDLE,
+ pub pkcs11IsTemp: PRBool,
+ pub wincx: *mut c_void,
+ pub staticflags: PRUint32,
+}
+
+#[repr(u32)]
+pub enum KeyType {
+ nullKey = 0,
+ rsaKey = 1,
+ dsaKey = 2,
+ fortezzaKey = 3,
+ dhKey = 4,
+ keaKey = 5,
+ ecKey = 6,
+ rsaPssKey = 7,
+ rsaOaepKey = 8,
+}
+
+pub type SECKEYRSAPublicKey = SECKEYRSAPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYRSAPublicKeyStr {
+ pub arena: *mut PLArenaPool,
+ pub modulus: SECItem,
+ pub publicExponent: SECItem,
+}
+
+pub type SECKEYDSAPublicKey = SECKEYDSAPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYDSAPublicKeyStr {
+ pub params: SECKEYPQGParams,
+ pub publicValue: SECItem,
+}
+
+pub type SECKEYPQGParams = SECKEYPQGParamsStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYPQGParamsStr {
+ pub arena: *mut PLArenaPool,
+ pub prime: SECItem,
+ pub subPrime: SECItem,
+ pub base: SECItem,
+}
+
+pub type SECKEYDHPublicKey = SECKEYDHPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYDHPublicKeyStr {
+ pub arena: *mut PLArenaPool,
+ pub prime: SECItem,
+ pub base: SECItem,
+ pub publicValue: SECItem,
+}
+
+pub type SECKEYKEAPublicKey = SECKEYKEAPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYKEAPublicKeyStr {
+ pub params: SECKEYKEAParams,
+ pub publicValue: SECItem,
+}
+
+pub type SECKEYKEAParams = SECKEYKEAParamsStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYKEAParamsStr {
+ pub arena: *mut PLArenaPool,
+ pub hash: SECItem,
+}
+
+pub type SECKEYFortezzaPublicKey = SECKEYFortezzaPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYFortezzaPublicKeyStr {
+ pub KEAversion: c_int,
+ pub DSSversion: c_int,
+ pub KMID: [c_uchar; 8usize],
+ pub clearance: SECItem,
+ pub KEApriviledge: SECItem,
+ pub DSSpriviledge: SECItem,
+ pub KEAKey: SECItem,
+ pub DSSKey: SECItem,
+ pub params: SECKEYPQGParams,
+ pub keaParams: SECKEYPQGParams,
+}
+
+pub type SECKEYECPublicKey = SECKEYECPublicKeyStr;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECKEYECPublicKeyStr {
+ pub DEREncodedParams: SECKEYECParams,
+ pub size: c_int,
+ pub publicValue: SECItem,
+ pub encoding: u32, /* ECPointEncoding */
+}
+
+pub type SECKEYECParams = SECItem;
+
+#[repr(u32)]
+#[derive(Copy, Clone)]
+pub enum ECPointEncoding {
+ ECPoint_Uncompressed = 0,
+ ECPoint_XOnly = 1,
+ ECPoint_Undefined = 2,
+}
diff --git a/third_party/rust/nss_sys/src/bindings/mod.rs b/third_party/rust/nss_sys/src/bindings/mod.rs
@@ -0,0 +1,44 @@
+/* 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/. */
+
+mod blapit;
+pub use blapit::*;
+mod certdb;
+pub use certdb::*;
+mod keyhi;
+pub use keyhi::*;
+mod keythi;
+pub use keythi::*;
+mod nss;
+pub use nss::*;
+mod pk11pub;
+pub use pk11pub::*;
+mod pkcs11n;
+pub use pkcs11n::*;
+mod pkcs11t;
+pub use pkcs11t::*;
+mod pkixc;
+pub use pkixc::*;
+mod plarena;
+pub use plarena::*;
+mod prerror;
+pub use prerror::*;
+mod prtypes;
+pub use prtypes::*;
+mod secasn1t;
+pub use secasn1t::*;
+mod seccomon;
+pub use seccomon::*;
+mod secitem;
+pub use secitem::*;
+mod seckey;
+pub use seckey::*;
+mod secmodt;
+pub use secmodt::*;
+mod secoid;
+pub use secoid::*;
+mod secoidt;
+pub use secoidt::*;
+mod secport;
+pub use secport::*;
diff --git a/third_party/rust/nss_sys/src/bindings/nss.rs b/third_party/rust/nss_sys/src/bindings/nss.rs
@@ -0,0 +1,29 @@
+/* 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 crate::*;
+use std::os::raw::c_char;
+
+extern "C" {
+ pub fn NSS_VersionCheck(importedVersion: *const c_char) -> PRBool;
+ pub fn NSS_InitContext(
+ configdir: *const c_char,
+ certPrefix: *const c_char,
+ keyPrefix: *const c_char,
+ secmodName: *const c_char,
+ initParams: *mut NSSInitParameters,
+ flags: PRUint32,
+ ) -> *mut NSSInitContext;
+ pub fn NSS_IsInitialized() -> PRBool;
+}
+
+pub const NSS_INIT_READONLY: u32 = 1;
+pub const NSS_INIT_NOCERTDB: u32 = 2;
+pub const NSS_INIT_NOMODDB: u32 = 4;
+pub const NSS_INIT_FORCEOPEN: u32 = 8;
+pub const NSS_INIT_OPTIMIZESPACE: u32 = 32;
+
+// Opaque types
+pub type NSSInitContext = u8;
+pub type NSSInitParameters = [u64; 10usize];
diff --git a/third_party/rust/nss_sys/src/bindings/pk11pub.rs b/third_party/rust/nss_sys/src/bindings/pk11pub.rs
@@ -0,0 +1,191 @@
+/* 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/. */
+
+pub use crate::*;
+use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_void};
+
+extern "C" {
+ pub fn PK11_FreeSlot(slot: *mut PK11SlotInfo);
+ pub fn PK11_GetInternalSlot() -> *mut PK11SlotInfo;
+ pub fn PK11_GetInternalKeySlot() -> *mut PK11SlotInfo;
+ pub fn PK11_NeedUserInit(slot: *mut PK11SlotInfo) -> PRBool;
+ pub fn PK11_NeedLogin(slot: *mut PK11SlotInfo) -> PRBool;
+ pub fn PK11_IsLoggedIn(slot: *mut PK11SlotInfo, wincx: *mut c_void) -> PRBool;
+ pub fn PK11_CheckUserPassword(slot: *mut PK11SlotInfo, password: *const c_char) -> SECStatus;
+ pub fn PK11_GenerateRandom(data: *mut c_uchar, len: c_int) -> SECStatus;
+ pub fn PK11_FreeSymKey(key: *mut PK11SymKey);
+ pub fn PK11_InitPin(
+ slot: *mut PK11SlotInfo,
+ ssopw: *const c_char,
+ pk11_userpwd: *const c_char,
+ ) -> SECStatus;
+ pub fn PK11_KeyGen(
+ slot: *mut PK11SlotInfo,
+ type_: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ keySize: c_int,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_ImportSymKey(
+ slot: *mut PK11SlotInfo,
+ type_: CK_MECHANISM_TYPE,
+ origin: u32, /* PK11Origin */
+ operation: CK_ATTRIBUTE_TYPE,
+ key: *mut SECItem,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_ImportSymKeyWithFlags(
+ slot: *mut PK11SlotInfo,
+ type_: CK_MECHANISM_TYPE,
+ origin: u32, /* PK11Origin */
+ operation: CK_ATTRIBUTE_TYPE,
+ key: *mut SECItem,
+ flags: CK_FLAGS,
+ isPerm: PRBool,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_SetSymKeyNickname(key: *mut PK11SymKey, name: *const c_char) -> SECStatus;
+ pub fn PK11_Derive(
+ baseKey: *mut PK11SymKey,
+ mechanism: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ target: CK_MECHANISM_TYPE,
+ operation: CK_ATTRIBUTE_TYPE,
+ keySize: c_int,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_PubDeriveWithKDF(
+ privKey: *mut SECKEYPrivateKey,
+ pubKey: *mut SECKEYPublicKey,
+ isSender: PRBool,
+ randomA: *mut SECItem,
+ randomB: *mut SECItem,
+ derive: CK_MECHANISM_TYPE,
+ target: CK_MECHANISM_TYPE,
+ operation: CK_ATTRIBUTE_TYPE,
+ keySize: c_int,
+ kdf: CK_ULONG,
+ sharedData: *mut SECItem,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_WrapSymKey(
+ type_: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ wrappingKey: *mut PK11SymKey,
+ symKey: *mut PK11SymKey,
+ wrappedKey: *mut SECItem,
+ ) -> SECStatus;
+ pub fn PK11_UnwrapSymKey(
+ wrappingKey: *mut PK11SymKey,
+ wrapType: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ wrappedKey: *mut SECItem,
+ target: CK_MECHANISM_TYPE,
+ operation: CK_ATTRIBUTE_TYPE,
+ keySize: c_int,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_ExtractKeyValue(symKey: *mut PK11SymKey) -> SECStatus;
+ pub fn PK11_GetKeyData(symKey: *mut PK11SymKey) -> *mut SECItem;
+ pub fn PK11_GenerateKeyPair(
+ slot: *mut PK11SlotInfo,
+ type_: CK_MECHANISM_TYPE,
+ param: *mut c_void,
+ pubk: *mut *mut SECKEYPublicKey,
+ isPerm: PRBool,
+ isSensitive: PRBool,
+ wincx: *mut c_void,
+ ) -> *mut SECKEYPrivateKey;
+ pub fn PK11_FindKeyByKeyID(
+ slot: *mut PK11SlotInfo,
+ keyID: *mut SECItem,
+ wincx: *mut c_void,
+ ) -> *mut SECKEYPrivateKey;
+ pub fn PK11_ListFixedKeysInSlot(
+ slot: *mut PK11SlotInfo,
+ nickname: *mut c_char,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn PK11_Decrypt(
+ symkey: *mut PK11SymKey,
+ mechanism: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ out: *mut c_uchar,
+ outLen: *mut c_uint,
+ maxLen: c_uint,
+ enc: *const c_uchar,
+ encLen: c_uint,
+ ) -> SECStatus;
+ pub fn PK11_Encrypt(
+ symKey: *mut PK11SymKey,
+ mechanism: CK_MECHANISM_TYPE,
+ param: *mut SECItem,
+ out: *mut c_uchar,
+ outLen: *mut c_uint,
+ maxLen: c_uint,
+ data: *const c_uchar,
+ dataLen: c_uint,
+ ) -> SECStatus;
+ pub fn PK11_VerifyWithMechanism(
+ key: *mut SECKEYPublicKey,
+ mechanism: CK_MECHANISM_TYPE,
+ param: *const SECItem,
+ sig: *const SECItem,
+ hash: *const SECItem,
+ wincx: *mut c_void,
+ ) -> SECStatus;
+ pub fn PK11_MapSignKeyType(keyType: u32 /* KeyType */) -> CK_MECHANISM_TYPE;
+ pub fn PK11_DestroyContext(context: *mut PK11Context, freeit: PRBool);
+ pub fn PK11_CreateContextBySymKey(
+ type_: CK_MECHANISM_TYPE,
+ operation: CK_ATTRIBUTE_TYPE,
+ symKey: *mut PK11SymKey,
+ param: *const SECItem,
+ ) -> *mut PK11Context;
+ pub fn PK11_DigestBegin(cx: *mut PK11Context) -> SECStatus;
+ pub fn PK11_HashBuf(
+ hashAlg: u32, /* SECOidTag */
+ out: *mut c_uchar,
+ in_: *const c_uchar,
+ len: PRInt32,
+ ) -> SECStatus;
+ pub fn PK11_DigestOp(context: *mut PK11Context, in_: *const c_uchar, len: c_uint) -> SECStatus;
+ pub fn PK11_DigestFinal(
+ context: *mut PK11Context,
+ data: *mut c_uchar,
+ outLen: *mut c_uint,
+ length: c_uint,
+ ) -> SECStatus;
+ pub fn PK11_DestroyGenericObject(object: *mut PK11GenericObject) -> SECStatus;
+ pub fn PK11_CreateGenericObject(
+ slot: *mut PK11SlotInfo,
+ pTemplate: *const CK_ATTRIBUTE,
+ count: c_int,
+ token: PRBool,
+ ) -> *mut PK11GenericObject;
+ pub fn PK11_ReadRawAttribute(
+ type_: u32, /* PK11ObjectType */
+ object: *mut c_void,
+ attr: CK_ATTRIBUTE_TYPE,
+ item: *mut SECItem,
+ ) -> SECStatus;
+ pub fn PK11_CreatePBEV2AlgorithmID(
+ pbeAlgTag: u32, /* SECOidTag */
+ cipherAlgTag: u32, /* SECOidTag */
+ prfAlgTag: u32, /* SECOidTag */
+ keyLength: c_int,
+ iteration: c_int,
+ salt: *mut SECItem,
+ ) -> *mut SECAlgorithmID;
+ pub fn PK11_PBEKeyGen(
+ slot: *mut PK11SlotInfo,
+ algid: *mut SECAlgorithmID,
+ pwitem: *mut SECItem,
+ faulty3DES: PRBool,
+ wincx: *mut c_void,
+ ) -> *mut PK11SymKey;
+ pub fn SECITEM_AllocItem(
+ arena: *mut PLArenaPool,
+ item: *mut SECItem,
+ len: c_uint,
+ ) -> *mut SECItem;
+}
diff --git a/third_party/rust/nss_sys/src/bindings/pkcs11n.rs b/third_party/rust/nss_sys/src/bindings/pkcs11n.rs
@@ -0,0 +1,32 @@
+/* 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/. */
+
+pub use crate::*;
+
+// https://searchfox.org/nss/rev/4d480919bbf204df5e199b9fdedec8f2a6295778/lib/util/pkcs11n.h#27
+pub const NSSCK_VENDOR_NSS: u32 = 0x4E534350;
+
+pub const CKM_NSS: u32 = CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS;
+pub const CKM_NSS_HKDF_SHA256: u32 = CKM_NSS + 4;
+pub const CKM_NSS_HKDF_SHA384: u32 = CKM_NSS + 5;
+
+pub type CK_GCM_PARAMS = CK_GCM_PARAMS_V3;
+#[repr(C)]
+pub struct CK_GCM_PARAMS_V3 {
+ pub pIv: CK_BYTE_PTR,
+ pub ulIvLen: CK_ULONG,
+ pub ulIvBits: CK_ULONG,
+ pub pAAD: CK_BYTE_PTR,
+ pub ulAADLen: CK_ULONG,
+ pub ulTagBits: CK_ULONG,
+}
+#[repr(C)]
+pub struct CK_NSS_HKDFParams {
+ pub bExtract: CK_BBOOL,
+ pub pSalt: CK_BYTE_PTR,
+ pub ulSaltLen: CK_ULONG,
+ pub bExpand: CK_BBOOL,
+ pub pInfo: CK_BYTE_PTR,
+ pub ulInfoLen: CK_ULONG,
+}
diff --git a/third_party/rust/nss_sys/src/bindings/pkcs11t.rs b/third_party/rust/nss_sys/src/bindings/pkcs11t.rs
@@ -0,0 +1,55 @@
+/* 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::os::raw::{c_uchar, c_ulong, c_void};
+
+pub const CK_TRUE: CK_BBOOL = 1;
+pub const CK_FALSE: CK_BBOOL = 0;
+pub type CK_BYTE = c_uchar;
+pub type CK_BBOOL = CK_BYTE;
+pub type CK_ULONG = c_ulong;
+pub type CK_BYTE_PTR = *mut CK_BYTE;
+pub type CK_VOID_PTR = *mut c_void;
+pub type CK_OBJECT_HANDLE = CK_ULONG;
+pub type CK_OBJECT_CLASS = CK_ULONG;
+pub type CK_KEY_TYPE = CK_ULONG;
+pub type CK_ATTRIBUTE_TYPE = CK_ULONG;
+pub type CK_FLAGS = CK_ULONG;
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct CK_ATTRIBUTE {
+ pub type_: CK_ATTRIBUTE_TYPE,
+ pub pValue: CK_VOID_PTR,
+ pub ulValueLen: CK_ULONG,
+}
+pub type CK_MECHANISM_TYPE = CK_ULONG;
+
+pub const CK_INVALID_HANDLE: u32 = 0;
+pub const CKO_PRIVATE_KEY: u32 = 3;
+pub const CKK_EC: u32 = 3;
+pub const CKA_CLASS: u32 = 0;
+pub const CKA_TOKEN: u32 = 1;
+pub const CKA_PRIVATE: u32 = 2;
+pub const CKA_VALUE: u32 = 17;
+pub const CKA_KEY_TYPE: u32 = 256;
+pub const CKA_ID: u32 = 258;
+pub const CKA_SENSITIVE: u32 = 259;
+pub const CKA_ENCRYPT: u32 = 260;
+pub const CKA_DECRYPT: u32 = 261;
+pub const CKA_WRAP: u32 = 262;
+pub const CKA_SIGN: u32 = 264;
+pub const CKA_EC_PARAMS: u32 = 384;
+pub const CKA_EC_POINT: u32 = 385;
+// https://searchfox.org/nss/rev/4d480919bbf204df5e199b9fdedec8f2a6295778/lib/util/pkcs11t.h#1244
+pub const CKM_VENDOR_DEFINED: u32 = 0x80000000;
+pub const CKM_SHA256_HMAC: u32 = 593;
+pub const CKM_SHA384_HMAC: u32 = 609;
+pub const CKM_SHA512_HMAC: u32 = 625;
+pub const CKM_EC_KEY_PAIR_GEN: u32 = 4160;
+pub const CKM_ECDH1_DERIVE: u32 = 4176;
+pub const CKM_AES_CBC_PAD: u32 = 4229;
+pub const CKM_AES_GCM: u32 = 4231;
+pub const CKM_AES_KEY_GEN: CK_ULONG = 0x00001080;
+pub const CKM_AES_KEY_WRAP_KWP: CK_ULONG = 0x0000210B;
+pub const CKD_NULL: u32 = 1;
diff --git a/third_party/rust/nss_sys/src/bindings/pkixc.rs b/third_party/rust/nss_sys/src/bindings/pkixc.rs
@@ -0,0 +1,18 @@
+/* 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 crate::*;
+
+extern "C" {
+ pub fn VerifyCodeSigningCertificateChain(
+ certificates: *mut *const u8,
+ certificateLengths: *const u16,
+ numCertificates: size_t,
+ secondsSinceEpoch: u64,
+ rootSHA256Hash: *const u8,
+ hostname: *const u8,
+ hostnameLength: size_t,
+ error: *mut PRErrorCode,
+ ) -> bool;
+}
diff --git a/third_party/rust/nss_sys/src/bindings/plarena.rs b/third_party/rust/nss_sys/src/bindings/plarena.rs
@@ -0,0 +1,22 @@
+/* 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/. */
+
+pub use crate::*;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct PLArena {
+ pub next: *mut PLArena,
+ pub base: PRUword,
+ pub limit: PRUword,
+ pub avail: PRUword,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct PLArenaPool {
+ pub first: PLArena,
+ pub current: *mut PLArena,
+ pub arenasize: PRUint32,
+ pub mask: PRUword,
+}
diff --git a/third_party/rust/nss_sys/src/bindings/prerror.rs b/third_party/rust/nss_sys/src/bindings/prerror.rs
@@ -0,0 +1,14 @@
+/* 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/. */
+
+pub use crate::*;
+use std::os::raw::c_char;
+
+extern "C" {
+ pub fn PR_GetError() -> PRErrorCode;
+ pub fn PR_GetErrorTextLength() -> PRInt32;
+ pub fn PR_GetErrorText(text: *mut c_char) -> PRInt32;
+}
+
+pub type PRErrorCode = PRInt32;
diff --git a/third_party/rust/nss_sys/src/bindings/prtypes.rs b/third_party/rust/nss_sys/src/bindings/prtypes.rs
@@ -0,0 +1,13 @@
+/* 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::os::raw::{c_int, c_uint};
+
+pub type PRIntn = c_int;
+pub type PRBool = PRIntn;
+pub type PRUword = usize;
+pub type PRInt32 = c_int;
+pub type PRUint32 = c_uint;
+pub const PR_FALSE: PRBool = 0;
+pub const PR_TRUE: PRBool = 1;
diff --git a/third_party/rust/nss_sys/src/bindings/secasn1t.rs b/third_party/rust/nss_sys/src/bindings/secasn1t.rs
@@ -0,0 +1,5 @@
+/* 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/. */
+
+pub const SEC_ASN1_OBJECT_ID: u32 = 6;
diff --git a/third_party/rust/nss_sys/src/bindings/seccomon.rs b/third_party/rust/nss_sys/src/bindings/seccomon.rs
@@ -0,0 +1,43 @@
+/* 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::os::raw::{c_uchar, c_uint};
+
+#[repr(u32)]
+pub enum SECItemType {
+ siBuffer = 0,
+ siClearDataBuffer = 1,
+ siCipherDataBuffer = 2,
+ siDERCertBuffer = 3,
+ siEncodedCertBuffer = 4,
+ siDERNameBuffer = 5,
+ siEncodedNameBuffer = 6,
+ siAsciiNameString = 7,
+ siAsciiString = 8,
+ siDEROID = 9,
+ siUnsignedInteger = 10,
+ siUTCTime = 11,
+ siGeneralizedTime = 12,
+ siVisibleString = 13,
+ siUTF8String = 14,
+ siBMPString = 15,
+}
+
+pub type SECItem = SECItemStr;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct SECItemStr {
+ pub type_: u32, /* SECItemType */
+ pub data: *mut c_uchar,
+ pub len: c_uint,
+}
+
+#[repr(i32)]
+#[derive(PartialEq, Eq)]
+pub enum _SECStatus {
+ SECWouldBlock = -2,
+ SECFailure = -1,
+ SECSuccess = 0,
+}
+pub use _SECStatus as SECStatus;
diff --git a/third_party/rust/nss_sys/src/bindings/secitem.rs b/third_party/rust/nss_sys/src/bindings/secitem.rs
@@ -0,0 +1,9 @@
+/* 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/. */
+
+pub use crate::*;
+
+extern "C" {
+ pub fn SECITEM_FreeItem(zap: *mut SECItem, freeit: PRBool);
+}
diff --git a/third_party/rust/nss_sys/src/bindings/seckey.rs b/third_party/rust/nss_sys/src/bindings/seckey.rs
@@ -0,0 +1,9 @@
+/* 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/. */
+
+pub use crate::*;
+
+extern "C" {
+ pub fn CERT_ExtractPublicKey(cert: *mut CERTCertificate) -> *mut SECKEYPublicKey;
+}
diff --git a/third_party/rust/nss_sys/src/bindings/secmodt.rs b/third_party/rust/nss_sys/src/bindings/secmodt.rs
@@ -0,0 +1,33 @@
+/* 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/. */
+
+// Opaque pointers as these types are giant.
+pub type PK11SlotInfo = u8;
+pub type PK11SymKey = u8;
+pub type PK11Context = u8;
+
+#[repr(u32)]
+pub enum PK11Origin {
+ PK11_OriginNULL = 0,
+ PK11_OriginDerive = 1,
+ PK11_OriginGenerated = 2,
+ PK11_OriginFortezzaHack = 3,
+ PK11_OriginUnwrap = 4,
+}
+
+#[repr(u32)]
+pub enum PK11ObjectType {
+ PK11_TypeGeneric = 0,
+ PK11_TypePrivKey = 1,
+ PK11_TypePubKey = 2,
+ PK11_TypeCert = 3,
+ PK11_TypeSymKey = 4,
+}
+
+// #[repr(C)]
+// #[derive(Copy, Clone)]
+// pub struct PK11GenericObjectStr {
+// _unused: [u8; 0],
+// }
+pub type PK11GenericObject = u8;
diff --git a/third_party/rust/nss_sys/src/bindings/secoid.rs b/third_party/rust/nss_sys/src/bindings/secoid.rs
@@ -0,0 +1,10 @@
+/* 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/. */
+
+pub use crate::*;
+
+extern "C" {
+ pub fn SECOID_FindOIDByTag(tagnum: u32 /* SECOidTag */) -> *mut SECOidData;
+ pub fn SECOID_DestroyAlgorithmID(aid: *mut SECAlgorithmID, freeit: PRBool);
+}
diff --git a/third_party/rust/nss_sys/src/bindings/secoidt.rs b/third_party/rust/nss_sys/src/bindings/secoidt.rs
@@ -0,0 +1,401 @@
+/* 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/. */
+
+pub use crate::*;
+use std::os::raw::{c_char, c_ulong};
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECAlgorithmIDStr {
+ pub algorithm: SECItem,
+ pub parameters: SECItem,
+}
+
+pub type SECAlgorithmID = SECAlgorithmIDStr;
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct SECOidDataStr {
+ pub oid: SECItem,
+ pub offset: u32, /* SECOidTag */
+ pub desc: *const c_char,
+ pub mechanism: c_ulong,
+ pub supportedExtension: u32, /* SECSupportExtenTag */
+}
+pub type SECOidData = SECOidDataStr;
+
+pub enum SECSupportExtenTag {
+ INVALID_CERT_EXTENSION = 0,
+ UNSUPPORTED_CERT_EXTENSION = 1,
+ SUPPORTED_CERT_EXTENSION = 2,
+}
+
+#[repr(u32)]
+pub enum SECOidTag {
+ SEC_OID_UNKNOWN = 0,
+ SEC_OID_MD2 = 1,
+ SEC_OID_MD4 = 2,
+ SEC_OID_MD5 = 3,
+ SEC_OID_SHA1 = 4,
+ SEC_OID_RC2_CBC = 5,
+ SEC_OID_RC4 = 6,
+ SEC_OID_DES_EDE3_CBC = 7,
+ SEC_OID_RC5_CBC_PAD = 8,
+ SEC_OID_DES_ECB = 9,
+ SEC_OID_DES_CBC = 10,
+ SEC_OID_DES_OFB = 11,
+ SEC_OID_DES_CFB = 12,
+ SEC_OID_DES_MAC = 13,
+ SEC_OID_DES_EDE = 14,
+ SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE = 15,
+ SEC_OID_PKCS1_RSA_ENCRYPTION = 16,
+ SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION = 17,
+ SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION = 18,
+ SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION = 19,
+ SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION = 20,
+ SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC = 21,
+ SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC = 22,
+ SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC = 23,
+ SEC_OID_PKCS7 = 24,
+ SEC_OID_PKCS7_DATA = 25,
+ SEC_OID_PKCS7_SIGNED_DATA = 26,
+ SEC_OID_PKCS7_ENVELOPED_DATA = 27,
+ SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA = 28,
+ SEC_OID_PKCS7_DIGESTED_DATA = 29,
+ SEC_OID_PKCS7_ENCRYPTED_DATA = 30,
+ SEC_OID_PKCS9_EMAIL_ADDRESS = 31,
+ SEC_OID_PKCS9_UNSTRUCTURED_NAME = 32,
+ SEC_OID_PKCS9_CONTENT_TYPE = 33,
+ SEC_OID_PKCS9_MESSAGE_DIGEST = 34,
+ SEC_OID_PKCS9_SIGNING_TIME = 35,
+ SEC_OID_PKCS9_COUNTER_SIGNATURE = 36,
+ SEC_OID_PKCS9_CHALLENGE_PASSWORD = 37,
+ SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS = 38,
+ SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES = 39,
+ SEC_OID_PKCS9_SMIME_CAPABILITIES = 40,
+ SEC_OID_AVA_COMMON_NAME = 41,
+ SEC_OID_AVA_COUNTRY_NAME = 42,
+ SEC_OID_AVA_LOCALITY = 43,
+ SEC_OID_AVA_STATE_OR_PROVINCE = 44,
+ SEC_OID_AVA_ORGANIZATION_NAME = 45,
+ SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME = 46,
+ SEC_OID_AVA_DN_QUALIFIER = 47,
+ SEC_OID_AVA_DC = 48,
+ SEC_OID_NS_TYPE_GIF = 49,
+ SEC_OID_NS_TYPE_JPEG = 50,
+ SEC_OID_NS_TYPE_URL = 51,
+ SEC_OID_NS_TYPE_HTML = 52,
+ SEC_OID_NS_TYPE_CERT_SEQUENCE = 53,
+ SEC_OID_MISSI_KEA_DSS_OLD = 54,
+ SEC_OID_MISSI_DSS_OLD = 55,
+ SEC_OID_MISSI_KEA_DSS = 56,
+ SEC_OID_MISSI_DSS = 57,
+ SEC_OID_MISSI_KEA = 58,
+ SEC_OID_MISSI_ALT_KEA = 59,
+ SEC_OID_NS_CERT_EXT_NETSCAPE_OK = 60,
+ SEC_OID_NS_CERT_EXT_ISSUER_LOGO = 61,
+ SEC_OID_NS_CERT_EXT_SUBJECT_LOGO = 62,
+ SEC_OID_NS_CERT_EXT_CERT_TYPE = 63,
+ SEC_OID_NS_CERT_EXT_BASE_URL = 64,
+ SEC_OID_NS_CERT_EXT_REVOCATION_URL = 65,
+ SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL = 66,
+ SEC_OID_NS_CERT_EXT_CA_CRL_URL = 67,
+ SEC_OID_NS_CERT_EXT_CA_CERT_URL = 68,
+ SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL = 69,
+ SEC_OID_NS_CERT_EXT_CA_POLICY_URL = 70,
+ SEC_OID_NS_CERT_EXT_HOMEPAGE_URL = 71,
+ SEC_OID_NS_CERT_EXT_ENTITY_LOGO = 72,
+ SEC_OID_NS_CERT_EXT_USER_PICTURE = 73,
+ SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME = 74,
+ SEC_OID_NS_CERT_EXT_COMMENT = 75,
+ SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL = 76,
+ SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME = 77,
+ SEC_OID_NS_KEY_USAGE_GOVT_APPROVED = 78,
+ SEC_OID_X509_SUBJECT_DIRECTORY_ATTR = 79,
+ SEC_OID_X509_SUBJECT_KEY_ID = 80,
+ SEC_OID_X509_KEY_USAGE = 81,
+ SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD = 82,
+ SEC_OID_X509_SUBJECT_ALT_NAME = 83,
+ SEC_OID_X509_ISSUER_ALT_NAME = 84,
+ SEC_OID_X509_BASIC_CONSTRAINTS = 85,
+ SEC_OID_X509_NAME_CONSTRAINTS = 86,
+ SEC_OID_X509_CRL_DIST_POINTS = 87,
+ SEC_OID_X509_CERTIFICATE_POLICIES = 88,
+ SEC_OID_X509_POLICY_MAPPINGS = 89,
+ SEC_OID_X509_POLICY_CONSTRAINTS = 90,
+ SEC_OID_X509_AUTH_KEY_ID = 91,
+ SEC_OID_X509_EXT_KEY_USAGE = 92,
+ SEC_OID_X509_AUTH_INFO_ACCESS = 93,
+ SEC_OID_X509_CRL_NUMBER = 94,
+ SEC_OID_X509_REASON_CODE = 95,
+ SEC_OID_X509_INVALID_DATE = 96,
+ SEC_OID_X500_RSA_ENCRYPTION = 97,
+ SEC_OID_RFC1274_UID = 98,
+ SEC_OID_RFC1274_MAIL = 99,
+ SEC_OID_PKCS12 = 100,
+ SEC_OID_PKCS12_MODE_IDS = 101,
+ SEC_OID_PKCS12_ESPVK_IDS = 102,
+ SEC_OID_PKCS12_BAG_IDS = 103,
+ SEC_OID_PKCS12_CERT_BAG_IDS = 104,
+ SEC_OID_PKCS12_OIDS = 105,
+ SEC_OID_PKCS12_PBE_IDS = 106,
+ SEC_OID_PKCS12_SIGNATURE_IDS = 107,
+ SEC_OID_PKCS12_ENVELOPING_IDS = 108,
+ SEC_OID_PKCS12_PKCS8_KEY_SHROUDING = 109,
+ SEC_OID_PKCS12_KEY_BAG_ID = 110,
+ SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID = 111,
+ SEC_OID_PKCS12_SECRET_BAG_ID = 112,
+ SEC_OID_PKCS12_X509_CERT_CRL_BAG = 113,
+ SEC_OID_PKCS12_SDSI_CERT_BAG = 114,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4 = 115,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4 = 116,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC = 117,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 118,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 119,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4 = 120,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4 = 121,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES = 122,
+ SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST = 123,
+ SEC_OID_ANSIX9_DSA_SIGNATURE = 124,
+ SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST = 125,
+ SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST = 126,
+ SEC_OID_VERISIGN_USER_NOTICES = 127,
+ SEC_OID_PKIX_CPS_POINTER_QUALIFIER = 128,
+ SEC_OID_PKIX_USER_NOTICE_QUALIFIER = 129,
+ SEC_OID_PKIX_OCSP = 130,
+ SEC_OID_PKIX_OCSP_BASIC_RESPONSE = 131,
+ SEC_OID_PKIX_OCSP_NONCE = 132,
+ SEC_OID_PKIX_OCSP_CRL = 133,
+ SEC_OID_PKIX_OCSP_RESPONSE = 134,
+ SEC_OID_PKIX_OCSP_NO_CHECK = 135,
+ SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF = 136,
+ SEC_OID_PKIX_OCSP_SERVICE_LOCATOR = 137,
+ SEC_OID_PKIX_REGCTRL_REGTOKEN = 138,
+ SEC_OID_PKIX_REGCTRL_AUTHENTICATOR = 139,
+ SEC_OID_PKIX_REGCTRL_PKIPUBINFO = 140,
+ SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS = 141,
+ SEC_OID_PKIX_REGCTRL_OLD_CERT_ID = 142,
+ SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY = 143,
+ SEC_OID_PKIX_REGINFO_UTF8_PAIRS = 144,
+ SEC_OID_PKIX_REGINFO_CERT_REQUEST = 145,
+ SEC_OID_EXT_KEY_USAGE_SERVER_AUTH = 146,
+ SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH = 147,
+ SEC_OID_EXT_KEY_USAGE_CODE_SIGN = 148,
+ SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT = 149,
+ SEC_OID_EXT_KEY_USAGE_TIME_STAMP = 150,
+ SEC_OID_OCSP_RESPONDER = 151,
+ SEC_OID_NETSCAPE_SMIME_KEA = 152,
+ SEC_OID_FORTEZZA_SKIPJACK = 153,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4 = 154,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4 = 155,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC = 156,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC = 157,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 158,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 159,
+ SEC_OID_PKCS12_SAFE_CONTENTS_ID = 160,
+ SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID = 161,
+ SEC_OID_PKCS12_V1_KEY_BAG_ID = 162,
+ SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID = 163,
+ SEC_OID_PKCS12_V1_CERT_BAG_ID = 164,
+ SEC_OID_PKCS12_V1_CRL_BAG_ID = 165,
+ SEC_OID_PKCS12_V1_SECRET_BAG_ID = 166,
+ SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID = 167,
+ SEC_OID_PKCS9_X509_CERT = 168,
+ SEC_OID_PKCS9_SDSI_CERT = 169,
+ SEC_OID_PKCS9_X509_CRL = 170,
+ SEC_OID_PKCS9_FRIENDLY_NAME = 171,
+ SEC_OID_PKCS9_LOCAL_KEY_ID = 172,
+ SEC_OID_BOGUS_KEY_USAGE = 173,
+ SEC_OID_X942_DIFFIE_HELMAN_KEY = 174,
+ SEC_OID_NETSCAPE_NICKNAME = 175,
+ SEC_OID_NETSCAPE_RECOVERY_REQUEST = 176,
+ SEC_OID_CERT_RENEWAL_LOCATOR = 177,
+ SEC_OID_NS_CERT_EXT_SCOPE_OF_USE = 178,
+ SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN = 179,
+ SEC_OID_CMS_3DES_KEY_WRAP = 180,
+ SEC_OID_CMS_RC2_KEY_WRAP = 181,
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE = 182,
+ SEC_OID_AES_128_ECB = 183,
+ SEC_OID_AES_128_CBC = 184,
+ SEC_OID_AES_192_ECB = 185,
+ SEC_OID_AES_192_CBC = 186,
+ SEC_OID_AES_256_ECB = 187,
+ SEC_OID_AES_256_CBC = 188,
+ SEC_OID_SDN702_DSA_SIGNATURE = 189,
+ SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE = 190,
+ SEC_OID_SHA256 = 191,
+ SEC_OID_SHA384 = 192,
+ SEC_OID_SHA512 = 193,
+ SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION = 194,
+ SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION = 195,
+ SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION = 196,
+ SEC_OID_AES_128_KEY_WRAP = 197,
+ SEC_OID_AES_192_KEY_WRAP = 198,
+ SEC_OID_AES_256_KEY_WRAP = 199,
+ SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200,
+ SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201,
+ SEC_OID_ANSIX962_EC_PRIME192V1 = 202,
+ SEC_OID_ANSIX962_EC_PRIME192V2 = 203,
+ SEC_OID_ANSIX962_EC_PRIME192V3 = 204,
+ SEC_OID_ANSIX962_EC_PRIME239V1 = 205,
+ SEC_OID_ANSIX962_EC_PRIME239V2 = 206,
+ SEC_OID_ANSIX962_EC_PRIME239V3 = 207,
+ SEC_OID_SECG_EC_SECP256R1 = 208,
+ SEC_OID_SECG_EC_SECP112R1 = 209,
+ SEC_OID_SECG_EC_SECP112R2 = 210,
+ SEC_OID_SECG_EC_SECP128R1 = 211,
+ SEC_OID_SECG_EC_SECP128R2 = 212,
+ SEC_OID_SECG_EC_SECP160K1 = 213,
+ SEC_OID_SECG_EC_SECP160R1 = 214,
+ SEC_OID_SECG_EC_SECP160R2 = 215,
+ SEC_OID_SECG_EC_SECP192K1 = 216,
+ SEC_OID_SECG_EC_SECP224K1 = 217,
+ SEC_OID_SECG_EC_SECP224R1 = 218,
+ SEC_OID_SECG_EC_SECP256K1 = 219,
+ SEC_OID_SECG_EC_SECP384R1 = 220,
+ SEC_OID_SECG_EC_SECP521R1 = 221,
+ SEC_OID_ANSIX962_EC_C2PNB163V1 = 222,
+ SEC_OID_ANSIX962_EC_C2PNB163V2 = 223,
+ SEC_OID_ANSIX962_EC_C2PNB163V3 = 224,
+ SEC_OID_ANSIX962_EC_C2PNB176V1 = 225,
+ SEC_OID_ANSIX962_EC_C2TNB191V1 = 226,
+ SEC_OID_ANSIX962_EC_C2TNB191V2 = 227,
+ SEC_OID_ANSIX962_EC_C2TNB191V3 = 228,
+ SEC_OID_ANSIX962_EC_C2ONB191V4 = 229,
+ SEC_OID_ANSIX962_EC_C2ONB191V5 = 230,
+ SEC_OID_ANSIX962_EC_C2PNB208W1 = 231,
+ SEC_OID_ANSIX962_EC_C2TNB239V1 = 232,
+ SEC_OID_ANSIX962_EC_C2TNB239V2 = 233,
+ SEC_OID_ANSIX962_EC_C2TNB239V3 = 234,
+ SEC_OID_ANSIX962_EC_C2ONB239V4 = 235,
+ SEC_OID_ANSIX962_EC_C2ONB239V5 = 236,
+ SEC_OID_ANSIX962_EC_C2PNB272W1 = 237,
+ SEC_OID_ANSIX962_EC_C2PNB304W1 = 238,
+ SEC_OID_ANSIX962_EC_C2TNB359V1 = 239,
+ SEC_OID_ANSIX962_EC_C2PNB368W1 = 240,
+ SEC_OID_ANSIX962_EC_C2TNB431R1 = 241,
+ SEC_OID_SECG_EC_SECT113R1 = 242,
+ SEC_OID_SECG_EC_SECT113R2 = 243,
+ SEC_OID_SECG_EC_SECT131R1 = 244,
+ SEC_OID_SECG_EC_SECT131R2 = 245,
+ SEC_OID_SECG_EC_SECT163K1 = 246,
+ SEC_OID_SECG_EC_SECT163R1 = 247,
+ SEC_OID_SECG_EC_SECT163R2 = 248,
+ SEC_OID_SECG_EC_SECT193R1 = 249,
+ SEC_OID_SECG_EC_SECT193R2 = 250,
+ SEC_OID_SECG_EC_SECT233K1 = 251,
+ SEC_OID_SECG_EC_SECT233R1 = 252,
+ SEC_OID_SECG_EC_SECT239K1 = 253,
+ SEC_OID_SECG_EC_SECT283K1 = 254,
+ SEC_OID_SECG_EC_SECT283R1 = 255,
+ SEC_OID_SECG_EC_SECT409K1 = 256,
+ SEC_OID_SECG_EC_SECT409R1 = 257,
+ SEC_OID_SECG_EC_SECT571K1 = 258,
+ SEC_OID_SECG_EC_SECT571R1 = 259,
+ SEC_OID_NETSCAPE_AOLSCREENNAME = 260,
+ SEC_OID_AVA_SURNAME = 261,
+ SEC_OID_AVA_SERIAL_NUMBER = 262,
+ SEC_OID_AVA_STREET_ADDRESS = 263,
+ SEC_OID_AVA_TITLE = 264,
+ SEC_OID_AVA_POSTAL_ADDRESS = 265,
+ SEC_OID_AVA_POSTAL_CODE = 266,
+ SEC_OID_AVA_POST_OFFICE_BOX = 267,
+ SEC_OID_AVA_GIVEN_NAME = 268,
+ SEC_OID_AVA_INITIALS = 269,
+ SEC_OID_AVA_GENERATION_QUALIFIER = 270,
+ SEC_OID_AVA_HOUSE_IDENTIFIER = 271,
+ SEC_OID_AVA_PSEUDONYM = 272,
+ SEC_OID_PKIX_CA_ISSUERS = 273,
+ SEC_OID_PKCS9_EXTENSION_REQUEST = 274,
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275,
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276,
+ SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277,
+ SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278,
+ SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279,
+ SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280,
+ SEC_OID_X509_HOLD_INSTRUCTION_CODE = 281,
+ SEC_OID_X509_DELTA_CRL_INDICATOR = 282,
+ SEC_OID_X509_ISSUING_DISTRIBUTION_POINT = 283,
+ SEC_OID_X509_CERT_ISSUER = 284,
+ SEC_OID_X509_FRESHEST_CRL = 285,
+ SEC_OID_X509_INHIBIT_ANY_POLICY = 286,
+ SEC_OID_X509_SUBJECT_INFO_ACCESS = 287,
+ SEC_OID_CAMELLIA_128_CBC = 288,
+ SEC_OID_CAMELLIA_192_CBC = 289,
+ SEC_OID_CAMELLIA_256_CBC = 290,
+ SEC_OID_PKCS5_PBKDF2 = 291,
+ SEC_OID_PKCS5_PBES2 = 292,
+ SEC_OID_PKCS5_PBMAC1 = 293,
+ SEC_OID_HMAC_SHA1 = 294,
+ SEC_OID_HMAC_SHA224 = 295,
+ SEC_OID_HMAC_SHA256 = 296,
+ SEC_OID_HMAC_SHA384 = 297,
+ SEC_OID_HMAC_SHA512 = 298,
+ SEC_OID_PKIX_TIMESTAMPING = 299,
+ SEC_OID_PKIX_CA_REPOSITORY = 300,
+ SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE = 301,
+ SEC_OID_SEED_CBC = 302,
+ SEC_OID_X509_ANY_POLICY = 303,
+ SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION = 304,
+ SEC_OID_PKCS1_MGF1 = 305,
+ SEC_OID_PKCS1_PSPECIFIED = 306,
+ SEC_OID_PKCS1_RSA_PSS_SIGNATURE = 307,
+ SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION = 308,
+ SEC_OID_SHA224 = 309,
+ SEC_OID_EV_INCORPORATION_LOCALITY = 310,
+ SEC_OID_EV_INCORPORATION_STATE = 311,
+ SEC_OID_EV_INCORPORATION_COUNTRY = 312,
+ SEC_OID_BUSINESS_CATEGORY = 313,
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST = 314,
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST = 315,
+ SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING = 316,
+ SEC_OID_AVA_NAME = 317,
+ SEC_OID_AES_128_GCM = 318,
+ SEC_OID_AES_192_GCM = 319,
+ SEC_OID_AES_256_GCM = 320,
+ SEC_OID_IDEA_CBC = 321,
+ SEC_OID_RC2_40_CBC = 322,
+ SEC_OID_DES_40_CBC = 323,
+ SEC_OID_RC4_40 = 324,
+ SEC_OID_RC4_56 = 325,
+ SEC_OID_NULL_CIPHER = 326,
+ SEC_OID_HMAC_MD5 = 327,
+ SEC_OID_TLS_RSA = 328,
+ SEC_OID_TLS_DHE_RSA = 329,
+ SEC_OID_TLS_DHE_DSS = 330,
+ SEC_OID_TLS_DH_RSA = 331,
+ SEC_OID_TLS_DH_DSS = 332,
+ SEC_OID_TLS_DH_ANON = 333,
+ SEC_OID_TLS_ECDHE_ECDSA = 334,
+ SEC_OID_TLS_ECDHE_RSA = 335,
+ SEC_OID_TLS_ECDH_ECDSA = 336,
+ SEC_OID_TLS_ECDH_RSA = 337,
+ SEC_OID_TLS_ECDH_ANON = 338,
+ SEC_OID_TLS_RSA_EXPORT = 339,
+ SEC_OID_TLS_DHE_RSA_EXPORT = 340,
+ SEC_OID_TLS_DHE_DSS_EXPORT = 341,
+ SEC_OID_TLS_DH_RSA_EXPORT = 342,
+ SEC_OID_TLS_DH_DSS_EXPORT = 343,
+ SEC_OID_TLS_DH_ANON_EXPORT = 344,
+ SEC_OID_APPLY_SSL_POLICY = 345,
+ SEC_OID_CHACHA20_POLY1305 = 346,
+ SEC_OID_TLS_ECDHE_PSK = 347,
+ SEC_OID_TLS_DHE_PSK = 348,
+ SEC_OID_TLS_FFDHE_2048 = 349,
+ SEC_OID_TLS_FFDHE_3072 = 350,
+ SEC_OID_TLS_FFDHE_4096 = 351,
+ SEC_OID_TLS_FFDHE_6144 = 352,
+ SEC_OID_TLS_FFDHE_8192 = 353,
+ SEC_OID_TLS_DHE_CUSTOM = 354,
+ SEC_OID_CURVE25519 = 355,
+ SEC_OID_TLS13_KEA_ANY = 356,
+ SEC_OID_X509_ANY_EXT_KEY_USAGE = 357,
+ SEC_OID_EXT_KEY_USAGE_IPSEC_IKE = 358,
+ SEC_OID_IPSEC_IKE_END = 359,
+ SEC_OID_IPSEC_IKE_INTERMEDIATE = 360,
+ SEC_OID_EXT_KEY_USAGE_IPSEC_END = 361,
+ SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL = 362,
+ SEC_OID_EXT_KEY_USAGE_IPSEC_USER = 363,
+ SEC_OID_TOTAL = 364,
+}
diff --git a/third_party/rust/nss_sys/src/bindings/secport.rs b/third_party/rust/nss_sys/src/bindings/secport.rs
@@ -0,0 +1,13 @@
+/* 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 crate::*;
+use std::os::raw::{c_int, c_void};
+
+pub type size_t = usize;
+
+extern "C" {
+ pub fn PORT_FreeArena(arena: *mut PLArenaPool, zero: PRBool);
+ pub fn NSS_SecureMemcmp(a: *const c_void, b: *const c_void, n: size_t) -> c_int;
+}
diff --git a/third_party/rust/nss_sys/src/lib.rs b/third_party/rust/nss_sys/src/lib.rs
@@ -0,0 +1,16 @@
+/* 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/. */
+
+#![allow(unknown_lints)]
+#![warn(rust_2018_idioms)]
+#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
+
+mod bindings;
+pub use bindings::*;
+
+// So we link against the SQLite lib imported by parent crates
+// such as places and logins.
+#[allow(unused_extern_crates)]
+#[cfg(any(not(feature = "gecko"), __appsvc_ci_hack))]
+extern crate libsqlite3_sys;
diff --git a/third_party/rust/rc_crypto/.cargo-checksum.json b/third_party/rust/rc_crypto/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"4cb5761465758109551f7e58fbb94b423d8230a8c3200e022b297b69d5c176c2","README.md":"110e6647522bf94adb22a8659ac93b5f5213b0832d3610acc8f137964962311a","src/aead.rs":"056c58687489347442411a407600a4917c4c044ec8208215280c3d5b3a28acc1","src/aead/aes_cbc.rs":"a8de38ba4288c21662faceb0985ada899314ea242845146d40905801718b4fa6","src/aead/aes_gcm.rs":"161e05df2cd51261a188edc476ec0a6d7888731f94e661a48ee6e6299e39a2d2","src/agreement.rs":"3efd9e5df1559f716952cd31690f62a778930c09a33c116fa9d6431a07f94d14","src/constant_time.rs":"8856965601d0a4705b68d7ff87e35d57a2f59b007b2d6f519dac624efc7a0ff5","src/contentsignature.rs":"bd2378f965a0d8f99694f6efcff9a807862b8665e4963ef4016a10c3d14272e5","src/digest.rs":"8b0de193c351decd34245ceecb6b25ddd2a15e94bc50d720a6a3ca17a94c2c53","src/ece_crypto.rs":"8aff8da0e64d87e6707bc46bc0028d9aea5c6d3aa456aec74e2e05fe4f04a622","src/error.rs":"2e0ab278977fe511ac75d56517a67d1961f63acc5aa27d4140ae7eec07e9cf21","src/hawk_crypto.rs":"0c5408c303fd71feb2285ff31ccff121ce976ceb4cc3544ba356b1946d1dd50f","src/hkdf.rs":"0ee1f7992b9a491b176af335ee10f5cf38d3f3638a5b2649576db8ab57108d9e","src/hmac.rs":"8d521acd0b7b5c9373a1318213fbab0a3a469c0c175449d86f3160edbfbc789c","src/lib.rs":"40d9906485880f1b677967eb430b7b6d4941d56dfe5c9a77c34e49e4fd3956f8","src/pbkdf2.rs":"7dd3321b49e072046302020d0dacc924465f0cb9e431c10c51f55801c3bfe829","src/rand.rs":"ccdd1051d06e1a40b577a907702394e286c3e4825356a3666738187cb57f661e","src/signature.rs":"f8185f0586f6edec1dd1966c38f3dc6c0778bb50d488e671051fd55afe4d2ff8"},"package":null}
+\ No newline at end of file
diff --git a/third_party/rust/rc_crypto/Cargo.toml b/third_party/rust/rc_crypto/Cargo.toml
@@ -0,0 +1,64 @@
+# 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 = "rc_crypto"
+version = "0.1.0"
+authors = ["Sync Team <sync-team@mozilla.com>"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+readme = "README.md"
+license = "MPL-2.0"
+
+[features]
+backtrace = ["error-support/backtrace"]
+default = []
+gecko = ["nss/gecko"]
+
+[lib]
+name = "rc_crypto"
+crate-type = ["lib"]
+path = "src/lib.rs"
+
+[dependencies]
+base64 = "0.21"
+hex = "0.4"
+thiserror = "2"
+
+[dependencies.ece]
+version = "2.3"
+features = ["serializable-keys"]
+optional = true
+default-features = false
+
+[dependencies.error-support]
+path = "../error"
+
+[dependencies.hawk]
+version = "5"
+optional = true
+default-features = false
+
+[dependencies.nss]
+path = "nss"
+
+[dev-dependencies.ece]
+version = "2.0"
+features = [
+ "serializable-keys",
+ "backend-test-helper",
+]
+default-features = false
diff --git a/third_party/rust/rc_crypto/README.md b/third_party/rust/rc_crypto/README.md
@@ -0,0 +1,27 @@
+# rc_crypto
+
+The `rc_crypto` crate, like its name implies, handles all of our cryptographic needs.
+
+For consumers, it pretty much follows the very rust-idiomatic [ring crate API](https://briansmith.org/rustdoc/ring/) and
+offers the following functionality:
+
+* Cryptographically secure [pseudorandom number generation](./src/rand.rs).
+* Cryptographic [digests](./src/digest.rs), [hmac](./src/hmac.rs), and [hkdf](./src/hkdf.rs).
+* Authenticated encryption ([AEAD](./src/aead.rs)) routines.
+* ECDH [key agreement](./src/agreement.rs).
+* ECDSA [signature verification](./src/signature.rs).
+* Constant-time [string comparison](./src/constant_time.rs).
+* HTTP [Hawk Authentication](./src/hawk_crypto.rs) through the [rust-hawk crate](https://github.com/taskcluster/rust-hawk/).
+* HTTP [Encrypted Content-Encoding](./src/ece.rs) through the [ece crate](https://github.com/mozilla/rust-ece).
+
+Under the hood, it is backed by Mozilla's [NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS) library,
+through bindings in the [nss](./nss/) crate. This has a number of advantages for our use-case:
+
+* Uses Mozilla-owned-and-audited crypto primitives.
+* Decouples us from ring's fast-moving [versioning and stability
+ policy](https://github.com/briansmith/ring#versioning--stability).
+
+
+## Rust features
+
+- `gecko` will avoid linking against libsqlite3_sys's libsqlite. See [#2882](https://github.com/mozilla/application-services/issues/2882) for context.
diff --git a/third_party/rust/rc_crypto/src/aead.rs b/third_party/rust/rc_crypto/src/aead.rs
@@ -0,0 +1,324 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+mod aes_cbc;
+mod aes_gcm;
+
+use crate::error::*;
+pub use aes_cbc::LEGACY_SYNC_AES_256_CBC_HMAC_SHA256;
+pub use aes_gcm::{AES_128_GCM, AES_256_GCM};
+use nss::aes;
+
+pub fn open(
+ key: &OpeningKey,
+ nonce: Nonce,
+ aad: Aad<'_>,
+ ciphertext_and_tag: &[u8],
+) -> Result<Vec<u8>> {
+ (key.algorithm().open)(&key.key, nonce, &aad, ciphertext_and_tag)
+}
+
+pub fn seal(key: &SealingKey, nonce: Nonce, aad: Aad<'_>, plaintext: &[u8]) -> Result<Vec<u8>> {
+ (key.algorithm().seal)(&key.key, nonce, &aad, plaintext)
+}
+
+/// The additional authenticated data (AAD) for an opening or sealing
+/// operation. This data is authenticated but is **not** encrypted.
+/// This is a type-safe wrapper around the raw bytes designed to encourage
+/// correct use of the API.
+#[repr(transparent)]
+pub struct Aad<'a>(&'a [u8]);
+
+impl<'a> Aad<'a> {
+ /// Construct the `Aad` by borrowing a contiguous sequence of bytes.
+ #[inline]
+ pub fn from(aad: &'a [u8]) -> Self {
+ Aad(aad)
+ }
+}
+
+impl Aad<'static> {
+ /// Construct an empty `Aad`.
+ pub fn empty() -> Self {
+ Self::from(&[])
+ }
+}
+
+/// The nonce for an opening or sealing operation.
+/// This is a type-safe wrapper around the raw bytes designed to encourage
+/// correct use of the API.
+pub struct Nonce(Vec<u8>);
+
+impl Nonce {
+ #[inline]
+ pub fn try_assume_unique_for_key(algorithm: &'static Algorithm, value: &[u8]) -> Result<Self> {
+ if value.len() != algorithm.nonce_len() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ Ok(Self(value.to_vec()))
+ }
+}
+
+pub struct OpeningKey {
+ key: Key,
+}
+
+impl OpeningKey {
+ /// Create a new opening key.
+ ///
+ /// `key_bytes` must be exactly `algorithm.key_len` bytes long.
+ #[inline]
+ pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self> {
+ Ok(Self {
+ key: Key::new(algorithm, key_bytes)?,
+ })
+ }
+
+ /// The key's AEAD algorithm.
+ #[inline]
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.key.algorithm()
+ }
+}
+
+pub struct SealingKey {
+ key: Key,
+}
+
+impl SealingKey {
+ /// Create a new sealing key.
+ ///
+ /// `key_bytes` must be exactly `algorithm.key_len` bytes long.
+ #[inline]
+ pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self> {
+ Ok(Self {
+ key: Key::new(algorithm, key_bytes)?,
+ })
+ }
+
+ /// The key's AEAD algorithm.
+ #[inline]
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.key.algorithm()
+ }
+}
+
+/// `OpeningKey` and `SealingKey` are type-safety wrappers around `Key`.
+pub(crate) struct Key {
+ key_value: Vec<u8>,
+ algorithm: &'static Algorithm,
+}
+
+impl Key {
+ fn new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self> {
+ if key_bytes.len() != algorithm.key_len() {
+ return Err(ErrorKind::InternalError.into());
+ }
+ Ok(Key {
+ key_value: key_bytes.to_vec(),
+ algorithm,
+ })
+ }
+
+ #[inline]
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.algorithm
+ }
+}
+
+// An AEAD algorithm.
+#[allow(clippy::type_complexity)]
+pub struct Algorithm {
+ tag_len: usize,
+ key_len: usize,
+ nonce_len: usize,
+ open: fn(key: &Key, nonce: Nonce, aad: &Aad<'_>, ciphertext_and_tag: &[u8]) -> Result<Vec<u8>>,
+ seal: fn(key: &Key, nonce: Nonce, aad: &Aad<'_>, plaintext: &[u8]) -> Result<Vec<u8>>,
+}
+
+impl Algorithm {
+ /// The length of the key.
+ #[inline]
+ pub const fn key_len(&self) -> usize {
+ self.key_len
+ }
+
+ /// The length of a tag.
+ #[inline]
+ pub const fn tag_len(&self) -> usize {
+ self.tag_len
+ }
+
+ /// The length of the nonces.
+ #[inline]
+ pub const fn nonce_len(&self) -> usize {
+ self.nonce_len
+ }
+}
+
+pub(crate) enum Direction {
+ Opening,
+ Sealing,
+}
+
+impl Direction {
+ fn to_nss_operation(&self) -> aes::Operation {
+ match self {
+ Direction::Opening => aes::Operation::Decrypt,
+ Direction::Sealing => aes::Operation::Encrypt,
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use nss::ensure_initialized;
+
+ static ALL_ALGORITHMS: &[&Algorithm] = &[
+ &LEGACY_SYNC_AES_256_CBC_HMAC_SHA256,
+ &AES_128_GCM,
+ &AES_256_GCM,
+ ];
+ static ALL_ALGORITHMS_THAT_SUPPORT_AAD: &[&Algorithm] = &[&AES_128_GCM, &AES_256_GCM];
+
+ #[test]
+ fn test_roundtrip() {
+ ensure_initialized();
+ for algorithm in ALL_ALGORITHMS {
+ let mut cleartext_bytes = vec![0u8; 127];
+ crate::rand::fill(&mut cleartext_bytes).unwrap();
+
+ let mut key_bytes = vec![0u8; algorithm.key_len()];
+ crate::rand::fill(&mut key_bytes).unwrap();
+
+ let nonce_bytes = vec![0u8; algorithm.nonce_len()];
+
+ let key = SealingKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let ciphertext_bytes = seal(&key, nonce, Aad::empty(), &cleartext_bytes).unwrap();
+
+ let key = OpeningKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let roundtriped_cleartext_bytes =
+ open(&key, nonce, Aad::empty(), &ciphertext_bytes).unwrap();
+ assert_eq!(roundtriped_cleartext_bytes, cleartext_bytes);
+ }
+ }
+
+ #[test]
+ fn test_cant_open_with_mismatched_key() {
+ ensure_initialized();
+ let mut key_bytes_1 = vec![0u8; AES_256_GCM.key_len()];
+ crate::rand::fill(&mut key_bytes_1).unwrap();
+
+ let mut key_bytes_2 = vec![0u8; AES_128_GCM.key_len()];
+ crate::rand::fill(&mut key_bytes_2).unwrap();
+
+ let nonce_bytes = vec![0u8; AES_256_GCM.nonce_len()];
+
+ let key = SealingKey::new(&AES_256_GCM, &key_bytes_1).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(&AES_256_GCM, &nonce_bytes).unwrap();
+ let ciphertext_bytes = seal(&key, nonce, Aad::empty(), &[0u8; 0]).unwrap();
+
+ let key = OpeningKey::new(&AES_128_GCM, &key_bytes_2).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(&AES_128_GCM, &nonce_bytes).unwrap();
+ let result = open(&key, nonce, Aad::empty(), &ciphertext_bytes);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn test_cant_open_modified_ciphertext() {
+ ensure_initialized();
+ for algorithm in ALL_ALGORITHMS {
+ let mut key_bytes = vec![0u8; algorithm.key_len()];
+ crate::rand::fill(&mut key_bytes).unwrap();
+
+ let nonce_bytes = vec![0u8; algorithm.nonce_len()];
+
+ let key = SealingKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let ciphertext_bytes = seal(&key, nonce, Aad::empty(), &[0u8; 0]).unwrap();
+
+ for i in 0..ciphertext_bytes.len() {
+ let mut modified_ciphertext = ciphertext_bytes.clone();
+ modified_ciphertext[i] = modified_ciphertext[i].wrapping_add(1);
+
+ let key = OpeningKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let result = open(&key, nonce, Aad::empty(), &modified_ciphertext);
+ assert!(result.is_err());
+ }
+ }
+ }
+
+ #[test]
+ fn test_cant_open_with_incorrect_associated_data() {
+ ensure_initialized();
+ for algorithm in ALL_ALGORITHMS_THAT_SUPPORT_AAD {
+ let mut key_bytes = vec![0u8; algorithm.key_len()];
+ crate::rand::fill(&mut key_bytes).unwrap();
+
+ let nonce_bytes = vec![0u8; algorithm.nonce_len()];
+
+ let key = SealingKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let ciphertext_bytes = seal(&key, nonce, Aad::from(&[1, 2, 3]), &[0u8; 0]).unwrap();
+
+ let key = OpeningKey::new(algorithm, &key_bytes).unwrap();
+ let nonce = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes).unwrap();
+ let result = open(&key, nonce, Aad::empty(), &ciphertext_bytes);
+ assert!(result.is_err());
+
+ let nonce = Nonce::try_assume_unique_for_key(&AES_256_GCM, &nonce_bytes).unwrap();
+ let result = open(&key, nonce, Aad::from(&[2, 3, 4]), &ciphertext_bytes);
+ assert!(result.is_err());
+ }
+ }
+
+ #[test]
+ fn test_cant_use_incorrectly_sized_key() {
+ ensure_initialized();
+ for algorithm in ALL_ALGORITHMS {
+ let key_bytes = vec![0u8; algorithm.key_len() - 1];
+ let result = Key::new(algorithm, &key_bytes);
+ assert!(result.is_err());
+
+ let key_bytes = vec![0u8; algorithm.key_len() + 1];
+ let result = Key::new(algorithm, &key_bytes);
+ assert!(result.is_err());
+ }
+ }
+
+ #[test]
+ fn test_cant_use_incorrectly_sized_nonce() {
+ ensure_initialized();
+ for algorithm in ALL_ALGORITHMS {
+ let nonce_bytes = vec![0u8; algorithm.nonce_len() - 1];
+ let result = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes);
+ assert!(result.is_err());
+
+ let nonce_bytes = vec![0u8; algorithm.nonce_len() + 1];
+ let result = Nonce::try_assume_unique_for_key(algorithm, &nonce_bytes);
+ assert!(result.is_err());
+ }
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/aead/aes_cbc.rs b/third_party/rust/rc_crypto/src/aead/aes_cbc.rs
@@ -0,0 +1,268 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::{aead, digest, error::*, hmac};
+use base64::{engine::general_purpose::STANDARD, Engine};
+use nss::aes;
+
+/// AES-256 in CBC mode with HMAC-SHA256 tags and 128 bit nonces.
+/// This is a Sync 1.5 specific encryption scheme, do not use for new
+/// applications, there are better options out there nowadays.
+/// Important note: The HMAC tag verification is done against the
+/// base64 representation of the ciphertext.
+/// More details here: https://mozilla-services.readthedocs.io/en/latest/sync/storageformat5.html#record-encryption
+pub static LEGACY_SYNC_AES_256_CBC_HMAC_SHA256: aead::Algorithm = aead::Algorithm {
+ key_len: 64, // 32 bytes for the AES key, 32 bytes for the HMAC key.
+ tag_len: 32,
+ nonce_len: 128 / 8,
+ open,
+ seal,
+};
+
+// Warning: This does not run in constant time (which is fine for our usage).
+pub(crate) fn open(
+ key: &aead::Key,
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ ciphertext_and_tag: &[u8],
+) -> Result<Vec<u8>> {
+ let ciphertext_len = ciphertext_and_tag
+ .len()
+ .checked_sub(key.algorithm().tag_len())
+ .ok_or(ErrorKind::InternalError)?;
+ let (ciphertext, hmac_signature) = ciphertext_and_tag.split_at(ciphertext_len);
+ let (aes_key, hmac_key_bytes) = extract_keys(key);
+ // 1. Tag (HMAC signature) check.
+ let hmac_key = hmac::VerificationKey::new(&digest::SHA256, hmac_key_bytes);
+ hmac::verify(
+ &hmac_key,
+ STANDARD.encode(ciphertext).as_bytes(),
+ hmac_signature,
+ )?;
+ // 2. Decryption.
+ aes_cbc(aes_key, nonce, aad, ciphertext, aead::Direction::Opening)
+}
+
+pub(crate) fn seal(
+ key: &aead::Key,
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ plaintext: &[u8],
+) -> Result<Vec<u8>> {
+ let (aes_key, hmac_key_bytes) = extract_keys(key);
+ // 1. Encryption.
+ let mut ciphertext = aes_cbc(aes_key, nonce, aad, plaintext, aead::Direction::Sealing)?;
+ // 2. Tag (HMAC signature) generation.
+ let hmac_key = hmac::SigningKey::new(&digest::SHA256, hmac_key_bytes);
+ let signature = hmac::sign(&hmac_key, STANDARD.encode(&ciphertext).as_bytes())?;
+ ciphertext.extend(&signature.0.value);
+ Ok(ciphertext)
+}
+
+fn extract_keys(key: &aead::Key) -> (&[u8], &[u8]) {
+ // Always split at 32 since we only do AES 256 w/ HMAC 256 tag.
+ let (aes_key, hmac_key_bytes) = key.key_value.split_at(32);
+ (aes_key, hmac_key_bytes)
+}
+
+fn aes_cbc(
+ aes_key: &[u8],
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ data: &[u8],
+ direction: aead::Direction,
+) -> Result<Vec<u8>> {
+ if !aad.0.is_empty() {
+ // CBC mode does not support AAD.
+ return Err(ErrorKind::InternalError.into());
+ }
+ Ok(aes::aes_cbc_crypt(
+ aes_key,
+ &nonce.0,
+ data,
+ direction.to_nss_operation(),
+ )?)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use nss::ensure_initialized;
+
+ // These are the test vectors used by the sync15 crate, but concatenated
+ // together rather than split into individual pieces.
+ const IV_B64: &str = "GX8L37AAb2FZJMzIoXlX8w==";
+
+ const KEY_B64: &str = "9K/wLdXdw+nrTtXo4ZpECyHFNr4d7aYHqeg3KW9+m6Qwye0R+62At\
+ NzwWVMtAWazz/Ew+YKV2o+Wr9BBcSPHvQ==";
+
+ const CIPHERTEXT_AND_TAG_B64: &str =
+ "NMsdnRulLwQsVcwxKW9XwaUe7ouJk5Wn80QhbD80l0HEcZGCynh45qIbeYBik0lgcHbKm\
+ lIxTJNwU+OeqipN+/j7MqhjKOGIlvbpiPQQLC6/ffF2vbzL0nzMUuSyvaQzyGGkSYM2xU\
+ Ft06aNivoQTvU2GgGmUK6MvadoY38hhW2LCMkoZcNfgCqJ26lO1O0sEO6zHsk3IVz6vsK\
+ iJ2Hq6VCo7hu123wNegmujHWQSGyf8JeudZjKzfi0OFRRvvm4QAKyBWf0MgrW1F8SFDnV\
+ fkq8amCB7NhdwhgLWbN+21NitNwWYknoEWe1m6hmGZDgDT32uxzWxCV8QqqrpH/ZggViE\
+ r9uMgoy4lYaWqP7G5WKvvechc62aqnsNEYhH26A5QgzmlNyvB+KPFvPsYzxDnSCjOoRSL\
+ x7GG86wT59QZyx5sGKww3rcCNrwNZaRvek3OO4sOAs+SGCuRTjr6XuvA==";
+
+ const CLEARTEXT_B64: &str =
+ "eyJpZCI6IjVxUnNnWFdSSlpYciIsImhpc3RVcmkiOiJmaWxlOi8vL1VzZXJzL2phc29u\
+ L0xpYnJhcnkvQXBwbGljYXRpb24lMjBTdXBwb3J0L0ZpcmVmb3gvUHJvZmlsZXMva3Nn\
+ ZDd3cGsuTG9jYWxTeW5jU2VydmVyL3dlYXZlL2xvZ3MvIiwidGl0bGUiOiJJbmRleCBv\
+ ZiBmaWxlOi8vL1VzZXJzL2phc29uL0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9G\
+ aXJlZm94L1Byb2ZpbGVzL2tzZ2Q3d3BrLkxvY2FsU3luY1NlcnZlci93ZWF2ZS9sb2dz\
+ LyIsInZpc2l0cyI6W3siZGF0ZSI6MTMxOTE0OTAxMjM3MjQyNSwidHlwZSI6MX1dfQ==";
+
+ #[test]
+ fn test_decrypt() {
+ ensure_initialized();
+ let key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let ciphertext_and_tag = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+ let cleartext_bytes = open(&key, nonce, &aead::Aad::empty(), &ciphertext_and_tag).unwrap();
+
+ let expected_cleartext_bytes = STANDARD.decode(CLEARTEXT_B64).unwrap();
+ assert_eq!(&expected_cleartext_bytes, &cleartext_bytes);
+ }
+
+ #[test]
+ fn test_encrypt() {
+ ensure_initialized();
+ let key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let cleartext = STANDARD.decode(CLEARTEXT_B64).unwrap();
+
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+ let ciphertext_bytes = seal(&key, nonce, &aead::Aad::empty(), &cleartext).unwrap();
+
+ let expected_ciphertext_bytes = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+ assert_eq!(&expected_ciphertext_bytes, &ciphertext_bytes);
+ }
+
+ #[test]
+ fn test_roundtrip() {
+ ensure_initialized();
+ let key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let cleartext = STANDARD.decode(CLEARTEXT_B64).unwrap();
+
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+ let ciphertext_bytes = seal(&key, nonce, &aead::Aad::empty(), &cleartext).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+ let roundtriped_cleartext_bytes =
+ open(&key, nonce, &aead::Aad::empty(), &ciphertext_bytes).unwrap();
+ assert_eq!(roundtriped_cleartext_bytes, cleartext);
+ }
+
+ #[test]
+ fn test_decrypt_fails_with_wrong_aes_key() {
+ ensure_initialized();
+ let mut key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ key_bytes[1] = b'X';
+
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let ciphertext_and_tag = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+
+ let err = open(&key, nonce, &aead::Aad::empty(), &ciphertext_and_tag).unwrap_err();
+ match err.kind() {
+ ErrorKind::NSSError(_) | ErrorKind::InternalError => {}
+ _ => panic!("unexpected error kind"),
+ }
+ }
+
+ #[test]
+ fn test_decrypt_fails_with_wrong_hmac_key() {
+ ensure_initialized();
+ let mut key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ key_bytes[60] = b'X';
+
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let ciphertext_and_tag = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+
+ let err = open(&key, nonce, &aead::Aad::empty(), &ciphertext_and_tag).unwrap_err();
+ match err.kind() {
+ ErrorKind::InternalError => {}
+ _ => panic!("unexpected error kind"),
+ }
+ }
+
+ #[test]
+ fn test_decrypt_fails_with_modified_ciphertext() {
+ ensure_initialized();
+ let key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+
+ let mut ciphertext_and_tag = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+ ciphertext_and_tag[4] = b'Z';
+
+ let err = open(&key, nonce, &aead::Aad::empty(), &ciphertext_and_tag).unwrap_err();
+ match err.kind() {
+ ErrorKind::InternalError => {}
+ _ => panic!("unexpected error kind"),
+ }
+ }
+
+ #[test]
+ fn test_decrypt_fails_with_modified_tag() {
+ ensure_initialized();
+ let key_bytes = STANDARD.decode(KEY_B64).unwrap();
+ let key = aead::Key::new(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &key_bytes).unwrap();
+ let iv = STANDARD.decode(IV_B64).unwrap();
+ let nonce =
+ aead::Nonce::try_assume_unique_for_key(&LEGACY_SYNC_AES_256_CBC_HMAC_SHA256, &iv)
+ .unwrap();
+
+ let mut ciphertext_and_tag = STANDARD.decode(CIPHERTEXT_AND_TAG_B64).unwrap();
+ let end = ciphertext_and_tag.len();
+ ciphertext_and_tag[end - 4] = b'Z';
+
+ let err = open(&key, nonce, &aead::Aad::empty(), &ciphertext_and_tag).unwrap_err();
+ match err.kind() {
+ ErrorKind::InternalError => {}
+ _ => panic!("unexpected error kind"),
+ }
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/aead/aes_gcm.rs b/third_party/rust/rc_crypto/src/aead/aes_gcm.rs
@@ -0,0 +1,150 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::{aead, error::*};
+use nss::aes;
+
+/// AES-128 in GCM mode with 128-bit tags and 96 bit nonces.
+pub static AES_128_GCM: aead::Algorithm = aead::Algorithm {
+ key_len: 16,
+ tag_len: 16,
+ nonce_len: 96 / 8,
+ open,
+ seal,
+};
+
+/// AES-256 in GCM mode with 128-bit tags and 96 bit nonces.
+pub static AES_256_GCM: aead::Algorithm = aead::Algorithm {
+ key_len: 32,
+ tag_len: 16,
+ nonce_len: 96 / 8,
+ open,
+ seal,
+};
+
+pub(crate) fn open(
+ key: &aead::Key,
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ ciphertext_and_tag: &[u8],
+) -> Result<Vec<u8>> {
+ aes_gcm(
+ key,
+ nonce,
+ aad,
+ ciphertext_and_tag,
+ aead::Direction::Opening,
+ )
+}
+
+pub(crate) fn seal(
+ key: &aead::Key,
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ plaintext: &[u8],
+) -> Result<Vec<u8>> {
+ aes_gcm(key, nonce, aad, plaintext, aead::Direction::Sealing)
+}
+
+fn aes_gcm(
+ key: &aead::Key,
+ nonce: aead::Nonce,
+ aad: &aead::Aad<'_>,
+ data: &[u8],
+ direction: aead::Direction,
+) -> Result<Vec<u8>> {
+ Ok(aes::aes_gcm_crypt(
+ &key.key_value,
+ &nonce.0,
+ aad.0,
+ data,
+ direction.to_nss_operation(),
+ )?)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use nss::ensure_initialized;
+
+ // Test vector from the AES-GCM spec.
+ const NONCE_HEX: &str = "cafebabefacedbaddecaf888";
+ const KEY_HEX: &str = "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308";
+ const AAD_HEX: &str = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
+ const TAG_HEX: &str = "76fc6ece0f4e1768cddf8853bb2d551b";
+ const CIPHERTEXT_HEX: &str =
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662";
+ const CLEARTEXT_HEX: &str =
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39";
+
+ #[test]
+ fn test_decrypt() {
+ ensure_initialized();
+ let key_bytes = hex::decode(KEY_HEX).unwrap();
+ let key = aead::Key::new(&AES_256_GCM, &key_bytes).unwrap();
+ let mut ciphertext_and_tag = hex::decode(CIPHERTEXT_HEX).unwrap();
+ let tag = hex::decode(TAG_HEX).unwrap();
+ ciphertext_and_tag.extend(&tag);
+
+ let iv = hex::decode(NONCE_HEX).unwrap();
+ let nonce = aead::Nonce::try_assume_unique_for_key(&AES_256_GCM, &iv).unwrap();
+ let aad_bytes = hex::decode(AAD_HEX).unwrap();
+ let aad = aead::Aad::from(&aad_bytes);
+ let cleartext_bytes = open(&key, nonce, &aad, &ciphertext_and_tag).unwrap();
+ let encoded_cleartext = hex::encode(cleartext_bytes);
+ assert_eq!(&CLEARTEXT_HEX, &encoded_cleartext);
+ }
+
+ #[test]
+ fn test_encrypt() {
+ ensure_initialized();
+ let key_bytes = hex::decode(KEY_HEX).unwrap();
+ let key = aead::Key::new(&AES_256_GCM, &key_bytes).unwrap();
+ let cleartext = hex::decode(CLEARTEXT_HEX).unwrap();
+
+ let iv = hex::decode(NONCE_HEX).unwrap();
+ let nonce = aead::Nonce::try_assume_unique_for_key(&AES_256_GCM, &iv).unwrap();
+ let aad_bytes = hex::decode(AAD_HEX).unwrap();
+ let aad = aead::Aad::from(&aad_bytes);
+ let ciphertext_bytes = seal(&key, nonce, &aad, &cleartext).unwrap();
+
+ let expected_tag = hex::decode(TAG_HEX).unwrap();
+ let mut expected_ciphertext = hex::decode(CIPHERTEXT_HEX).unwrap();
+ expected_ciphertext.extend(&expected_tag);
+ assert_eq!(&expected_ciphertext, &ciphertext_bytes);
+ }
+
+ #[test]
+ fn test_roundtrip() {
+ ensure_initialized();
+ let key_bytes = hex::decode(KEY_HEX).unwrap();
+ let key = aead::Key::new(&AES_256_GCM, &key_bytes).unwrap();
+ let cleartext = hex::decode(CLEARTEXT_HEX).unwrap();
+
+ let iv = hex::decode(NONCE_HEX).unwrap();
+ let nonce = aead::Nonce::try_assume_unique_for_key(&AES_256_GCM, &iv).unwrap();
+ let ciphertext_bytes = seal(&key, nonce, &aead::Aad::empty(), &cleartext).unwrap();
+ let nonce = aead::Nonce::try_assume_unique_for_key(&AES_256_GCM, &iv).unwrap();
+ let roundtriped_cleartext_bytes =
+ open(&key, nonce, &aead::Aad::empty(), &ciphertext_bytes).unwrap();
+ assert_eq!(roundtriped_cleartext_bytes, cleartext);
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/agreement.rs b/third_party/rust/rc_crypto/src/agreement.rs
@@ -0,0 +1,417 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::error::*;
+use core::marker::PhantomData;
+
+pub use ec::{Curve, EcKey};
+use nss::{ec, ecdh};
+
+pub type EphemeralKeyPair = KeyPair<Ephemeral>;
+
+/// A key agreement algorithm.
+#[derive(PartialEq, Eq)]
+pub struct Algorithm {
+ pub(crate) curve_id: ec::Curve,
+}
+
+pub static ECDH_P256: Algorithm = Algorithm {
+ curve_id: ec::Curve::P256,
+};
+
+pub static ECDH_P384: Algorithm = Algorithm {
+ curve_id: ec::Curve::P384,
+};
+
+/// How many times the key may be used.
+pub trait Lifetime {}
+
+/// The key may be used at most once.
+pub struct Ephemeral {}
+impl Lifetime for Ephemeral {}
+
+/// The key may be used more than once.
+pub struct Static {}
+impl Lifetime for Static {}
+
+/// A key pair for key agreement.
+pub struct KeyPair<U: Lifetime> {
+ private_key: PrivateKey<U>,
+ public_key: PublicKey,
+}
+
+impl<U: Lifetime> KeyPair<U> {
+ /// Generate a new key pair for the given algorithm.
+ pub fn generate(alg: &'static Algorithm) -> Result<Self> {
+ let (prv_key, pub_key) = ec::generate_keypair(alg.curve_id)?;
+ Ok(Self {
+ private_key: PrivateKey {
+ alg,
+ wrapped: prv_key,
+ usage: PhantomData,
+ },
+ public_key: PublicKey {
+ alg,
+ wrapped: pub_key,
+ },
+ })
+ }
+
+ pub fn from_private_key(private_key: PrivateKey<U>) -> Result<Self> {
+ let public_key = private_key
+ .compute_public_key()
+ .map_err(|_| ErrorKind::InternalError)?;
+ Ok(Self {
+ private_key,
+ public_key,
+ })
+ }
+
+ /// The private key.
+ pub fn private_key(&self) -> &PrivateKey<U> {
+ &self.private_key
+ }
+
+ /// The public key.
+ pub fn public_key(&self) -> &PublicKey {
+ &self.public_key
+ }
+
+ /// Split the key pair apart.
+ pub fn split(self) -> (PrivateKey<U>, PublicKey) {
+ (self.private_key, self.public_key)
+ }
+}
+
+impl KeyPair<Static> {
+ pub fn from(private_key: PrivateKey<Static>) -> Result<Self> {
+ Self::from_private_key(private_key)
+ }
+}
+
+/// A public key for key agreement.
+pub struct PublicKey {
+ wrapped: ec::PublicKey,
+ alg: &'static Algorithm,
+}
+
+impl PublicKey {
+ #[inline]
+ pub fn to_bytes(&self) -> Result<Vec<u8>> {
+ Ok(self.wrapped.to_bytes()?)
+ }
+
+ #[inline]
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.alg
+ }
+}
+
+/// An unparsed public key for key agreement.
+pub struct UnparsedPublicKey<'a> {
+ alg: &'static Algorithm,
+ bytes: &'a [u8],
+}
+
+impl<'a> UnparsedPublicKey<'a> {
+ pub fn new(algorithm: &'static Algorithm, bytes: &'a [u8]) -> Self {
+ Self {
+ alg: algorithm,
+ bytes,
+ }
+ }
+
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.alg
+ }
+
+ pub fn bytes(&self) -> &'a [u8] {
+ self.bytes
+ }
+}
+
+/// A private key for key agreement.
+pub struct PrivateKey<U: Lifetime> {
+ wrapped: ec::PrivateKey,
+ alg: &'static Algorithm,
+ usage: PhantomData<U>,
+}
+
+impl<U: Lifetime> PrivateKey<U> {
+ #[inline]
+ pub fn algorithm(&self) -> &'static Algorithm {
+ self.alg
+ }
+
+ pub fn compute_public_key(&self) -> Result<PublicKey> {
+ let pub_key = self.wrapped.convert_to_public_key()?;
+ Ok(PublicKey {
+ wrapped: pub_key,
+ alg: self.alg,
+ })
+ }
+
+ /// Ephemeral agreement.
+ /// This consumes `self`, ensuring that the private key can
+ /// only be used for a single agreement operation.
+ pub fn agree(self, peer_public_key: &UnparsedPublicKey<'_>) -> Result<InputKeyMaterial> {
+ agree_(&self.wrapped, self.alg, peer_public_key)
+ }
+}
+
+impl PrivateKey<Static> {
+ /// Static agreement.
+ /// This borrows `self`, allowing the private key to
+ /// be used for a multiple agreement operations.
+ pub fn agree_static(
+ &self,
+ peer_public_key: &UnparsedPublicKey<'_>,
+ ) -> Result<InputKeyMaterial> {
+ agree_(&self.wrapped, self.alg, peer_public_key)
+ }
+
+ pub fn import(ec_key: &EcKey) -> Result<Self> {
+ // XXX: we should just let ec::PrivateKey own alg.
+ let alg = match ec_key.curve() {
+ Curve::P256 => &ECDH_P256,
+ Curve::P384 => &ECDH_P384,
+ };
+ let private_key = ec::PrivateKey::import(ec_key)?;
+ Ok(Self {
+ wrapped: private_key,
+ alg,
+ usage: PhantomData,
+ })
+ }
+
+ pub fn export(&self) -> Result<EcKey> {
+ Ok(self.wrapped.export()?)
+ }
+
+ /// The whole point of having `Ephemeral` and `Static` lifetimes is to use the type
+ /// system to avoid re-using the same ephemeral key. However for tests we might need
+ /// to create a "static" ephemeral key.
+ pub fn _tests_only_dangerously_convert_to_ephemeral(self) -> PrivateKey<Ephemeral> {
+ PrivateKey::<Ephemeral> {
+ wrapped: self.wrapped,
+ alg: self.alg,
+ usage: PhantomData,
+ }
+ }
+}
+
+fn agree_(
+ my_private_key: &ec::PrivateKey,
+ my_alg: &Algorithm,
+ peer_public_key: &UnparsedPublicKey<'_>,
+) -> Result<InputKeyMaterial> {
+ let alg = &my_alg;
+ if peer_public_key.algorithm() != *alg {
+ return Err(ErrorKind::InternalError.into());
+ }
+ let pub_key = ec::PublicKey::from_bytes(my_private_key.curve(), peer_public_key.bytes())?;
+ let value = ecdh::ecdh_agreement(my_private_key, &pub_key)?;
+ Ok(InputKeyMaterial { value })
+}
+
+/// The result of a key agreement operation, to be fed into a KDF.
+#[must_use]
+pub struct InputKeyMaterial {
+ value: Vec<u8>,
+}
+
+impl InputKeyMaterial {
+ /// Calls `kdf` with the raw key material and then returns what `kdf`
+ /// returns, consuming `Self` so that the key material can only be used
+ /// once.
+ pub fn derive<F, R>(self, kdf: F) -> R
+ where
+ F: FnOnce(&[u8]) -> R,
+ {
+ kdf(&self.value)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+ use nss::ensure_initialized;
+
+ // Test vectors copied from:
+ // https://chromium.googlesource.com/chromium/src/+/56f1232/components/test/data/webcrypto/ecdh.json#5
+
+ const PUB_KEY_1_B64: &str =
+ "BLunVoWkR67xRdAohVblFBWn1Oosb3kH_baxw1yfIYFfthSm4LIY35vDD-5LE454eB7TShn919DVVGZ_7tWdjTE";
+ const PRIV_KEY_1_JWK_D: &str = "CQ8uF_-zB1NftLO6ytwKM3Cnuol64PQw5qOuCzQJeFU";
+ const PRIV_KEY_1_JWK_X: &str = "u6dWhaRHrvFF0CiFVuUUFafU6ixveQf9trHDXJ8hgV8";
+ const PRIV_KEY_1_JWK_Y: &str = "thSm4LIY35vDD-5LE454eB7TShn919DVVGZ_7tWdjTE";
+
+ const PRIV_KEY_2_JWK_D: &str = "uN2YSQvxuxhQQ9Y1XXjYi1vr2ZTdzuoDX18PYu4LU-0";
+ const PRIV_KEY_2_JWK_X: &str = "S2S3tjygMB0DkM-N9jYUgGLt_9_H6km5P9V6V_KS4_4";
+ const PRIV_KEY_2_JWK_Y: &str = "03j8Tyqgrc4R4FAUV2C7-im96yMmfmO_5Om6Kr8YP3o";
+
+ const SHARED_SECRET_HEX: &str =
+ "163FAA3FC4815D47345C8E959F707B2F1D3537E7B2EA1DAEC23CA8D0A242CFF3";
+
+ fn load_priv_key_1() -> PrivateKey<Static> {
+ let private_key = URL_SAFE_NO_PAD.decode(PRIV_KEY_1_JWK_D).unwrap();
+ let x = URL_SAFE_NO_PAD.decode(PRIV_KEY_1_JWK_X).unwrap();
+ let y = URL_SAFE_NO_PAD.decode(PRIV_KEY_1_JWK_Y).unwrap();
+ PrivateKey::<Static>::import(
+ &EcKey::from_coordinates(Curve::P256, &private_key, &x, &y).unwrap(),
+ )
+ .unwrap()
+ }
+
+ fn load_priv_key_2() -> PrivateKey<Static> {
+ let private_key = URL_SAFE_NO_PAD.decode(PRIV_KEY_2_JWK_D).unwrap();
+ let x = URL_SAFE_NO_PAD.decode(PRIV_KEY_2_JWK_X).unwrap();
+ let y = URL_SAFE_NO_PAD.decode(PRIV_KEY_2_JWK_Y).unwrap();
+ PrivateKey::<Static>::import(
+ &EcKey::from_coordinates(Curve::P256, &private_key, &x, &y).unwrap(),
+ )
+ .unwrap()
+ }
+
+ #[test]
+ fn test_static_agreement() {
+ ensure_initialized();
+ let pub_key_raw = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap();
+ let peer_pub_key = UnparsedPublicKey::new(&ECDH_P256, &pub_key_raw);
+ let prv_key = load_priv_key_2();
+ let ikm = prv_key.agree_static(&peer_pub_key).unwrap();
+ let secret = ikm
+ .derive(|z| -> Result<Vec<u8>> { Ok(z.to_vec()) })
+ .unwrap();
+ let secret_b64 = hex::encode_upper(secret);
+ assert_eq!(secret_b64, *SHARED_SECRET_HEX);
+ }
+
+ #[test]
+ fn test_ephemeral_agreement_roundtrip() {
+ ensure_initialized();
+ let (our_prv_key, our_pub_key) =
+ KeyPair::<Ephemeral>::generate(&ECDH_P256).unwrap().split();
+ let (their_prv_key, their_pub_key) =
+ KeyPair::<Ephemeral>::generate(&ECDH_P256).unwrap().split();
+ let their_pub_key_raw = their_pub_key.to_bytes().unwrap();
+ let peer_public_key_1 = UnparsedPublicKey::new(&ECDH_P256, &their_pub_key_raw);
+ let ikm_1 = our_prv_key.agree(&peer_public_key_1).unwrap();
+ let secret_1 = ikm_1
+ .derive(|z| -> Result<Vec<u8>> { Ok(z.to_vec()) })
+ .unwrap();
+ let our_pub_key_raw = our_pub_key.to_bytes().unwrap();
+ let peer_public_key_2 = UnparsedPublicKey::new(&ECDH_P256, &our_pub_key_raw);
+ let ikm_2 = their_prv_key.agree(&peer_public_key_2).unwrap();
+ let secret_2 = ikm_2
+ .derive(|z| -> Result<Vec<u8>> { Ok(z.to_vec()) })
+ .unwrap();
+ assert_eq!(secret_1, secret_2);
+ }
+
+ #[test]
+ fn test_compute_public_key() {
+ ensure_initialized();
+ let (prv_key, pub_key) = KeyPair::<Static>::generate(&ECDH_P256).unwrap().split();
+ let computed_pub_key = prv_key.compute_public_key().unwrap();
+ assert_eq!(
+ computed_pub_key.to_bytes().unwrap(),
+ pub_key.to_bytes().unwrap()
+ );
+ }
+
+ #[test]
+ fn test_compute_public_key_known_values() {
+ ensure_initialized();
+ let prv_key = load_priv_key_1();
+ let pub_key = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap();
+ let computed_pub_key = prv_key.compute_public_key().unwrap();
+ assert_eq!(computed_pub_key.to_bytes().unwrap(), pub_key.as_slice());
+
+ let prv_key = load_priv_key_2();
+ let computed_pub_key = prv_key.compute_public_key().unwrap();
+ assert_ne!(computed_pub_key.to_bytes().unwrap(), pub_key.as_slice());
+ }
+
+ #[test]
+ fn test_keys_byte_representations_roundtrip() {
+ ensure_initialized();
+ let key_pair = KeyPair::<Static>::generate(&ECDH_P256).unwrap();
+ let prv_key = key_pair.private_key;
+ let extracted_pub_key = prv_key.compute_public_key().unwrap();
+ let ec_key = prv_key.export().unwrap();
+ let prv_key_reconstructed = PrivateKey::<Static>::import(&ec_key).unwrap();
+ let extracted_pub_key_reconstructed = prv_key.compute_public_key().unwrap();
+ let ec_key_reconstructed = prv_key_reconstructed.export().unwrap();
+ assert_eq!(ec_key.curve(), ec_key_reconstructed.curve());
+ assert_eq!(ec_key.public_key(), ec_key_reconstructed.public_key());
+ assert_eq!(ec_key.private_key(), ec_key_reconstructed.private_key());
+ assert_eq!(
+ extracted_pub_key.to_bytes().unwrap(),
+ extracted_pub_key_reconstructed.to_bytes().unwrap()
+ );
+ }
+
+ #[test]
+ fn test_agreement_rejects_invalid_pubkeys() {
+ ensure_initialized();
+ let prv_key = load_priv_key_2();
+
+ let mut invalid_pub_key = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap();
+ invalid_pub_key[0] = invalid_pub_key[0].wrapping_add(1);
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+
+ let mut invalid_pub_key = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap();
+ invalid_pub_key[0] = 0x02;
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+
+ let mut invalid_pub_key = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap();
+ invalid_pub_key[64] = invalid_pub_key[0].wrapping_add(1);
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+
+ let mut invalid_pub_key = [0u8; 65];
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+ invalid_pub_key[0] = 0x04;
+
+ let mut invalid_pub_key = URL_SAFE_NO_PAD.decode(PUB_KEY_1_B64).unwrap().to_vec();
+ invalid_pub_key = invalid_pub_key[0..64].to_vec();
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+
+ // From FxA tests at https://github.com/mozilla/fxa-crypto-relier/blob/04f61dc/test/deriver/DeriverUtils.js#L78
+ // We trust that NSS will do the right thing here, but it seems worthwhile to confirm for completeness.
+ let invalid_pub_key_b64 = "BEogZ-rnm44oJkKsOE6Tc7NwFMgmntf7Btm_Rc4atxcqq99Xq1RWNTFpk99pdQOSjUvwELss51PkmAGCXhLfMV0";
+ let invalid_pub_key = URL_SAFE_NO_PAD.decode(invalid_pub_key_b64).unwrap();
+ assert!(prv_key
+ .agree_static(&UnparsedPublicKey::new(&ECDH_P256, &invalid_pub_key))
+ .is_err());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/constant_time.rs b/third_party/rust/rc_crypto/src/constant_time.rs
@@ -0,0 +1,48 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::error::*;
+
+/// Returns `Ok(())` if `a == b` and `Error` otherwise.
+/// The comparison of `a` and `b` is done in constant time with respect to the
+/// contents of each, but NOT in constant time with respect to the lengths of
+/// `a` and `b`.
+pub fn verify_slices_are_equal(a: &[u8], b: &[u8]) -> Result<()> {
+ if nss::secport::secure_memcmp(a, b)? {
+ Ok(())
+ } else {
+ Err(ErrorKind::InternalError.into())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn does_compare() {
+ ensure_initialized();
+ assert!(verify_slices_are_equal(b"bobo", b"bobo").is_ok());
+ assert!(verify_slices_are_equal(b"bobo", b"obob").is_err());
+ assert!(verify_slices_are_equal(b"bobo", b"notbobo").is_err());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/contentsignature.rs b/third_party/rust/rc_crypto/src/contentsignature.rs
@@ -0,0 +1,430 @@
+/* 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::str;
+
+use base64::{
+ engine::general_purpose::{STANDARD, URL_SAFE},
+ Engine,
+};
+
+use crate::error::*;
+use crate::signature;
+
+/// Verify content signatures, with the ECDSA P384 curve and SHA-384 hashing (NIST384p / secp384r1).
+///
+/// These signatures are typically used to guarantee integrity of data between our servers and clients.
+/// This is a critical part of systems like Remote Settings or the experiment platform.
+///
+/// The equivalent implementation for Gecko is ``security/manager/ssl/nsIContentSignatureVerifier.idl``.
+///
+/// Decode a string with colon separated hexadecimal pairs into an array of bytes
+/// (eg. "3C:01:44" -> [60, 1, 68]).
+fn decode_root_hash(input: &str) -> Result<Vec<u8>> {
+ let bytes_hex = input.split(':');
+
+ let mut result: Vec<u8> = vec![];
+ for byte_hex in bytes_hex {
+ let byte = match hex::decode(byte_hex) {
+ Ok(v) => v,
+ Err(_) => return Err(ErrorKind::RootHashFormatError(input.to_string()).into()),
+ };
+ result.extend(byte);
+ }
+
+ Ok(result)
+}
+
+/// Split a certificate chain in PEM format into a list of certificates bytes,
+/// decoded from base64.
+fn split_pem(pem_content: &[u8]) -> Result<Vec<Vec<u8>>> {
+ let pem_str = match str::from_utf8(pem_content) {
+ Ok(v) => v,
+ Err(e) => {
+ return Err(ErrorKind::PEMFormatError(e.to_string()).into());
+ }
+ };
+
+ let pem_lines = pem_str.split('\n');
+
+ let mut blocks: Vec<Vec<u8>> = vec![];
+ let mut block: Vec<u8> = vec![];
+ let mut read = false;
+ for line in pem_lines {
+ if line.contains("-----BEGIN CERTIFICATE") {
+ read = true;
+ } else if line.contains("-----END CERTIFICATE") {
+ read = false;
+ let decoded = match STANDARD.decode(&block) {
+ Ok(v) => v,
+ Err(e) => return Err(ErrorKind::PEMFormatError(e.to_string()).into()),
+ };
+ blocks.push(decoded);
+ block.clear();
+ } else if read {
+ block.extend_from_slice(line.as_bytes());
+ }
+ }
+ if read {
+ return Err(ErrorKind::PEMFormatError("Missing end header".into()).into());
+ }
+ if blocks.is_empty() {
+ return Err(ErrorKind::PEMFormatError("Missing PEM data".into()).into());
+ }
+
+ Ok(blocks)
+}
+
+/// Verify that the signature matches the input data.
+///
+/// The data must be prefixed with ``Content-Signature:\u{0}``.
+/// The signature must be provided as base 64 url-safe encoded.
+/// The certificate chain, provided as PEM, must be valid at the provided current time.
+/// The root certificate content must match the provided root hash, and the leaf
+/// subject name must match the provided hostname.
+pub fn verify(
+ input: &[u8],
+ signature: &[u8],
+ pem_bytes: &[u8],
+ seconds_since_epoch: u64,
+ root_sha256_hash: &str,
+ hostname: &str,
+) -> Result<()> {
+ let certificates = split_pem(pem_bytes)?;
+
+ let mut certificates_slices: Vec<&[u8]> = vec![];
+ for certificate in &certificates {
+ certificates_slices.push(certificate);
+ }
+
+ let root_hash_bytes = decode_root_hash(root_sha256_hash)?;
+
+ nss::pkixc::verify_code_signing_certificate_chain(
+ certificates_slices,
+ seconds_since_epoch,
+ &root_hash_bytes,
+ hostname,
+ )
+ .map_err(|err| match err.kind() {
+ nss::ErrorKind::CertificateIssuerError => ErrorKind::CertificateIssuerError,
+ nss::ErrorKind::CertificateValidityError => ErrorKind::CertificateValidityError,
+ nss::ErrorKind::CertificateSubjectError => ErrorKind::CertificateSubjectError,
+ _ => ErrorKind::CertificateChainError(err.to_string()),
+ })?;
+
+ let leaf_cert = certificates.first().unwrap(); // PEM parse fails if len == 0.
+
+ let public_key_bytes = match nss::cert::extract_ec_public_key(leaf_cert) {
+ Ok(bytes) => bytes,
+ Err(err) => return Err(ErrorKind::CertificateContentError(err.to_string()).into()),
+ };
+
+ let signature_bytes = match URL_SAFE.decode(signature) {
+ Ok(b) => b,
+ Err(err) => return Err(ErrorKind::SignatureContentError(err.to_string()).into()),
+ };
+
+ // Since signature is NIST384p / secp384r1, we can perform a few safety checks.
+ if signature_bytes.len() != 96 {
+ return Err(ErrorKind::SignatureContentError(format!(
+ "signature contains {} bytes instead of {}",
+ signature_bytes.len(),
+ 96
+ ))
+ .into());
+ }
+ if public_key_bytes.len() != 96 + 1 {
+ // coordinates with x04 prefix.
+ return Err(ErrorKind::CertificateContentError(format!(
+ "public key contains {} bytes instead of {}",
+ public_key_bytes.len(),
+ 97
+ ))
+ .into());
+ }
+
+ let signature_alg = &signature::ECDSA_P384_SHA384;
+ let public_key = signature::UnparsedPublicKey::new(signature_alg, &public_key_bytes);
+ // Note that if the provided key type or curve is incorrect here, the signature will
+ // be considered as invalid.
+ match public_key.verify(input, &signature_bytes) {
+ Ok(_) => Ok(()),
+ Err(err) => Err(ErrorKind::SignatureMismatchError(err.to_string()).into()),
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ const ROOT_HASH: &str = "3C:01:44:6A:BE:90:36:CE:A9:A0:9A:CA:A3:A5:20:AC:62:8F:20:A7:AE:32:CE:86:1C:B2:EF:B7:0F:A0:C7:45";
+ const VALID_CERT_CHAIN: &[u8] = b"\
+-----BEGIN CERTIFICATE-----
+MIIDBjCCAougAwIBAgIIFml6g0ldRGowCgYIKoZIzj0EAwMwgaMxCzAJBgNVBAYT
+AlVTMRwwGgYDVQQKExNNb3ppbGxhIENvcnBvcmF0aW9uMS8wLQYDVQQLEyZNb3pp
+bGxhIEFNTyBQcm9kdWN0aW9uIFNpZ25pbmcgU2VydmljZTFFMEMGA1UEAww8Q29u
+dGVudCBTaWduaW5nIEludGVybWVkaWF0ZS9lbWFpbEFkZHJlc3M9Zm94c2VjQG1v
+emlsbGEuY29tMB4XDTIxMDIwMzE1MDQwNVoXDTIxMDQyNDE1MDQwNVowgakxCzAJ
+BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFp
+biBWaWV3MRwwGgYDVQQKExNNb3ppbGxhIENvcnBvcmF0aW9uMRcwFQYDVQQLEw5D
+bG91ZCBTZXJ2aWNlczE2MDQGA1UEAxMtcmVtb3RlLXNldHRpbmdzLmNvbnRlbnQt
+c2lnbmF0dXJlLm1vemlsbGEub3JnMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8pKb
+HX4IiD0SCy+NO7gwKqRRZ8IhGd8PTaIHIBgM6RDLRyDeswXgV+2kGUoHyzkbNKZt
+zlrS3AhqeUCtl1g6ECqSmZBbRTjCpn/UCpCnMLL0T0goxtAB8Rmi3CdM0cBUo4GD
+MIGAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAfBgNVHSME
+GDAWgBQlZawrqt0eUz/t6OdN45oKfmzy6DA4BgNVHREEMTAvgi1yZW1vdGUtc2V0
+dGluZ3MuY29udGVudC1zaWduYXR1cmUubW96aWxsYS5vcmcwCgYIKoZIzj0EAwMD
+aQAwZgIxAPh43Bxl4MxPT6Ra1XvboN5O2OvIn2r8rHvZPWR/jJ9vcTwH9X3F0aLJ
+9FiresnsLAIxAOoAcREYB24gFBeWxbiiXaG7TR/yM1/MXw4qxbN965FFUaoB+5Bc
+fS8//SQGTlCqKQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIEAQAAADANBgkqhkiG9w0BAQsFADCBqTELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRwwGgYDVQQK
+ExNBZGRvbnMgVGVzdCBTaWduaW5nMSQwIgYDVQQDExt0ZXN0LmFkZG9ucy5zaWdu
+aW5nLnJvb3QuY2ExMTAvBgkqhkiG9w0BCQEWInNlY29wcytzdGFnZXJvb3RhZGRv
+bnNAbW96aWxsYS5jb20wHhcNMjEwMTExMDAwMDAwWhcNMjQxMTE0MjA0ODU5WjCB
+ozELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xLzAt
+BgNVBAsTJk1vemlsbGEgQU1PIFByb2R1Y3Rpb24gU2lnbmluZyBTZXJ2aWNlMUUw
+QwYDVQQDDDxDb250ZW50IFNpZ25pbmcgSW50ZXJtZWRpYXRlL2VtYWlsQWRkcmVz
+cz1mb3hzZWNAbW96aWxsYS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARw1dyE
+xV5aNiHJPa/fVHO6kxJn3oZLVotJ0DzFZA9r1sQf8i0+v78Pg0/c3nTAyZWfkULz
+vOpKYK/GEGBtisxCkDJ+F3NuLPpSIg3fX25pH0LE15fvASBVcr8tKLVHeOmjggG6
+MIIBtjAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSUBAf8EDDAK
+BggrBgEFBQcDAzAdBgNVHQ4EFgQUJWWsK6rdHlM/7ejnTeOaCn5s8ugwgdkGA1Ud
+IwSB0TCBzoAUhtg0HE5Y0RNcmV/YQpjtFA8Z8l2hga+kgawwgakxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEcMBoGA1UE
+ChMTQWRkb25zIFRlc3QgU2lnbmluZzEkMCIGA1UEAxMbdGVzdC5hZGRvbnMuc2ln
+bmluZy5yb290LmNhMTEwLwYJKoZIhvcNAQkBFiJzZWNvcHMrc3RhZ2Vyb290YWRk
+b25zQG1vemlsbGEuY29tggRgJZg7MDMGCWCGSAGG+EIBBAQmFiRodHRwOi8vYWRk
+b25zLmFsbGl6b20ub3JnL2NhL2NybC5wZW0wTgYDVR0eBEcwRaBDMCCCHi5jb250
+ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzAfgh1jb250ZW50LXNpZ25hdHVyZS5t
+b3ppbGxhLm9yZzANBgkqhkiG9w0BAQsFAAOCAgEAtGTTzcPzpcdf07kIeRs9vPMx
+qiF8ylW5L/IQ2NzT3sFFAvPW1vW1wZC0xAHMsuVyo+BTGrv+4mlD0AUR9acRfiTZ
+9qyZ3sJbyhQwJAXLKU4YpnzuFOf58T/yOnOdwpH2ky/0FuHskMyfXaAz2Az4JXJH
+TCgggqfdZNvsZ5eOnQlKoC5NadMa8oTI5sd4SyR5ANUPAtYok931MvVSz3IMbwTr
+v4PPWXdl9SGXuOknSqdY6/bS1LGvC2KprsT+PBlvVtS6YgZOH0uCgTTLpnrco87O
+ErzC2PJBA1Ftn3Mbaou6xy7O+YX+reJ6soNUV+0JHOuKj0aTXv0c+lXEAh4Y8nea
+UGhW6+MRGYMOP2NuKv8s2+CtNH7asPq3KuTQpM5RerjdouHMIedX7wpNlNk0CYbg
+VMJLxZfAdwcingLWda/H3j7PxMoAm0N+eA24TGDQPC652ZakYk4MQL/45lm0A5f0
+xLGKEe6JMZcTBQyO7ANWcrpVjKMiwot6bY6S2xU17mf/h7J32JXZJ23OPOKpMS8d
+mljj4nkdoYDT35zFuS1z+5q6R5flLca35vRHzC3XA0H/XJvgOKUNLEW/IiJIqLNi
+ab3Ao0RubuX+CAdFML5HaJmkyuJvL3YtwIOwe93RGcGRZSKZsnMS+uY5QN8+qKQz
+LC4GzWQGSCGDyD+JCVw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHbDCCBVSgAwIBAgIEYCWYOzANBgkqhkiG9w0BAQwFADCBqTELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRwwGgYDVQQK
+ExNBZGRvbnMgVGVzdCBTaWduaW5nMSQwIgYDVQQDExt0ZXN0LmFkZG9ucy5zaWdu
+aW5nLnJvb3QuY2ExMTAvBgkqhkiG9w0BCQEWInNlY29wcytzdGFnZXJvb3RhZGRv
+bnNAbW96aWxsYS5jb20wHhcNMjEwMjExMjA0ODU5WhcNMjQxMTE0MjA0ODU5WjCB
+qTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBW
+aWV3MRwwGgYDVQQKExNBZGRvbnMgVGVzdCBTaWduaW5nMSQwIgYDVQQDExt0ZXN0
+LmFkZG9ucy5zaWduaW5nLnJvb3QuY2ExMTAvBgkqhkiG9w0BCQEWInNlY29wcytz
+dGFnZXJvb3RhZGRvbnNAbW96aWxsYS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQDKRVty/FRsO4Ech6EYleyaKgAueaLYfMSsAIyPC/N8n/P8QcH8
+rjoiMJrKHRlqiJmMBSmjUZVzZAP0XJku0orLKWPKq7cATt+xhGY/RJtOzenMMsr5
+eN02V3GzUd1jOShUpERjzXdaO3pnfZqhdqNYqP9ocqQpyno7bZ3FZQ2vei+bF52k
+51uPioTZo+1zduoR/rT01twGtZm3QpcwU4mO74ysyxxgqEy3kpojq8Nt6haDwzrj
+khV9M6DGPLHZD71QaUiz5lOhD9CS8x0uqXhBhwMUBBkHsUDSxbN4ZhjDDWpCmwaD
+OtbJMUJxDGPCr9qj49QESccb367OeXLrfZ2Ntu/US2Bw9EDfhyNsXr9dg9NHj5yf
+4sDUqBHG0W8zaUvJx5T2Ivwtno1YZLyJwQW5pWeWn8bEmpQKD2KS/3y2UjlDg+YM
+NdNASjFe0fh6I5NCFYmFWA73DpDGlUx0BtQQU/eZQJ+oLOTLzp8d3dvenTBVnKF+
+uwEmoNfZwc4TTWJOhLgwxA4uK+Paaqo4Ap2RGS2ZmVkPxmroB3gL5n3k3QEXvULh
+7v8Psk4+MuNWnxudrPkN38MGJo7ju7gDOO8h1jLD4tdfuAqbtQLduLXzT4DJPA4y
+JBTFIRMIpMqP9CovaS8VPtMFLTrYlFh9UnEGpCeLPanJr+VEj7ae5sc8YwIDAQAB
+o4IBmDCCAZQwDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0lAQH/
+BAwwCgYIKwYBBQUHAwMwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMDMGCWCGSAGG+EIBBAQmFiRodHRwOi8vYWRkb25zLm1vemls
+bGEub3JnL2NhL2NybC5wZW0wHQYDVR0OBBYEFIbYNBxOWNETXJlf2EKY7RQPGfJd
+MIHZBgNVHSMEgdEwgc6AFIbYNBxOWNETXJlf2EKY7RQPGfJdoYGvpIGsMIGpMQsw
+CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcx
+HDAaBgNVBAoTE0FkZG9ucyBUZXN0IFNpZ25pbmcxJDAiBgNVBAMTG3Rlc3QuYWRk
+b25zLnNpZ25pbmcucm9vdC5jYTExMC8GCSqGSIb3DQEJARYic2Vjb3BzK3N0YWdl
+cm9vdGFkZG9uc0Btb3ppbGxhLmNvbYIEYCWYOzANBgkqhkiG9w0BAQwFAAOCAgEA
+nowyJv8UaIV7NA0B3wkWratq6FgA1s/PzetG/ZKZDIW5YtfUvvyy72HDAwgKbtap
+Eog6zGI4L86K0UGUAC32fBjE5lWYEgsxNM5VWlQjbgTG0dc3dYiufxfDFeMbAPmD
+DzpIgN3jHW2uRqa/MJ+egHhv7kGFL68uVLboqk/qHr+SOCc1LNeSMCuQqvHwwM0+
+AU1GxhzBWDkealTS34FpVxF4sT5sKLODdIS5HXJr2COHHfYkw2SW/Sfpt6fsOwaF
+2iiDaK4LPWHWhhIYa6yaynJ+6O6KPlpvKYCChaTOVdc+ikyeiSO6AakJykr5Gy7d
+PkkK7MDCxuY6psHj7iJQ59YK7ujQB8QYdzuXBuLLo5hc5gBcq3PJs0fLT2YFcQHA
+dj+olGaDn38T0WI8ycWaFhQfKwATeLWfiQepr8JfoNlC2vvSDzGUGfdAfZfsJJZ8
+5xZxahHoTFGS0mDRfXqzKH5uD578GgjOZp0fULmzkcjWsgzdpDhadGjExRZFKlAy
+iKv8cXTONrGY0fyBDKennuX0uAca3V0Qm6v2VRp+7wG/pywWwc5n+04qgxTQPxgO
+6pPB9UUsNbaLMDR5QPYAWrNhqJ7B07XqIYJZSwGP5xB9NqUZLF4z+AOMYgWtDpmg
+IKdcFKAt3fFrpyMhlfIKkLfmm0iDjmfmIXbDGBJw9SE=
+-----END CERTIFICATE-----";
+ const VALID_INPUT: &[u8] =
+ b"Content-Signature:\x00{\"data\":[],\"last_modified\":\"1603992731957\"}";
+ const VALID_SIGNATURE: &[u8] = b"fJJcOpwdnkjEWFeHXfdOJN6GaGLuDTPGzQOxA2jn6ldIleIk6KqMhZcy2GZv2uYiGwl6DERWwpaoUfQFLyCAOcVjck1qlaaEFZGY1BQba9p99xEc9FNQ3YPPfvSSZqsw";
+ const VALID_HOSTNAME: &str = "remote-settings.content-signature.mozilla.org";
+
+ const INVALID_CERTIFICATE: &[u8] = b"\
+ -----BEGIN CERTIFICATE-----
+ invalidCertificategIFiJLFfdxFlYwCgYIKoZIzj0EAwMwgaMxCzAJBgNVBAYT
+ AlVTMRwwGgYDVQQKExNNb3ppbGxhIENvcnBvcmF0aW9uMS8wLQYDVQQLEyZNb3pp
+ bGxhIEFNTyBQcm9kdWN0aW9uIFNpZ25pbmcgU2VydmljZTFFMEMGA1UEAww8Q29u
+ dGVudCBTaWduaW5nIEludGVybWVkaWF0ZS9lbWFpbEFkZHJlc3M9Zm94c2VjQG1v
+ emlsbGEuY29tMB4XDTIwMDYxNjE3MTYxNVoXDTIwMDkwNDE3MTYxNVowgakxCzAJ
+ BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFp
+ biBWaWV3MRwwGgYDVQQKExNNb3ppbGxhIENvcnBvcmF0aW9uMRcwFQYDVQQLEw5D
+ bG91ZCBTZXJ2aWNlczE2MDQGA1UEAxMtcmVtb3RlLXNldHRpbmdzLmNvbnRlbnQt
+ c2lnbmF0dXJlLm1vemlsbGEub3JnMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEDmOX
+ N5IGlUqCvu6xkOKr020Eo3kY2uPdJO0ZihVUoglk1ktQPss184OajFOMKm/BJX4W
+ IsZUzQoRL8NgGfZDwBjT95Q87lhOWEWs5AU/nMXIYwDp7rpUPaUqw0QLMikdo4GD
+ MIGAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAfBgNVHSME
+ GDAWgBSgHUoXT4zCKzVF8WPx2nBwp8744TA4BgNVHREEMTAvgi1yZW1vdGUtc2V0
+ dGluZ3MuY29udGVudC1zaWduYXR1cmUubW96aWxsYS5vcmcwCgYIKoZIzj0EAwMD
+ aQAwZgIxAJvyynyPqRmRMqf95FPH5xfcoT3jb/2LOkUifGDtjtZ338ScpT2glUK8
+ HszKVANqXQIxAIygMaeTiD9figEusmHMthBdFoIoHk31x4MHukAy+TWZ863X6/V2
+ 6/ZrZMpinvalid==
+ -----END CERTIFICATE-----";
+
+ #[test]
+ fn test_decode_root_hash() {
+ nss::ensure_initialized();
+ assert!(decode_root_hash("meh!").is_err());
+ assert!(decode_root_hash("3C:rr:44").is_err());
+
+ let result = decode_root_hash(ROOT_HASH).unwrap();
+ assert_eq!(
+ result,
+ vec![
+ 60, 1, 68, 106, 190, 144, 54, 206, 169, 160, 154, 202, 163, 165, 32, 172, 98, 143,
+ 32, 167, 174, 50, 206, 134, 28, 178, 239, 183, 15, 160, 199, 69
+ ]
+ );
+ }
+
+ #[test]
+ fn test_split_pem() {
+ assert!(split_pem(b"meh!").is_err());
+
+ assert!(split_pem(
+ b"-----BEGIN CERTIFICATE-----
+invalidCertificate
+-----END CERTIFICATE-----"
+ )
+ .is_err());
+
+ assert!(split_pem(
+ b"-----BEGIN CERTIFICATE-----
+bGxhIEFNTyBQcm9kdWN0aW9uIFNp
+-----BEGIN CERTIFICATE-----"
+ )
+ .is_err());
+
+ let result = split_pem(
+ b"-----BEGIN CERTIFICATE-----
+AQID
+BAUG
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+/f7/
+-----END CERTIFICATE-----",
+ )
+ .unwrap();
+ assert_eq!(result, vec![vec![1, 2, 3, 4, 5, 6], vec![253, 254, 255]]);
+ }
+
+ #[test]
+ fn test_verify_fails_if_invalid() {
+ nss::ensure_initialized();
+ assert!(verify(
+ b"msg",
+ b"sig",
+ b"-----BEGIN CERTIFICATE-----
+fdfeff
+-----END CERTIFICATE-----",
+ 42,
+ ROOT_HASH,
+ "remotesettings.firefox.com",
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_fails_if_cert_has_expired() {
+ nss::ensure_initialized();
+ assert!(verify(
+ VALID_INPUT,
+ VALID_SIGNATURE,
+ VALID_CERT_CHAIN,
+ 1215559719, // July 9, 2008
+ ROOT_HASH,
+ VALID_HOSTNAME,
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_fails_if_bad_certificate_chain() {
+ nss::ensure_initialized();
+ assert!(verify(
+ VALID_INPUT,
+ VALID_SIGNATURE,
+ INVALID_CERTIFICATE,
+ 1615559719, // March 12, 2021
+ ROOT_HASH,
+ VALID_HOSTNAME,
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_fails_if_mismatch() {
+ nss::ensure_initialized();
+ assert!(verify(
+ b"msg",
+ VALID_SIGNATURE,
+ VALID_CERT_CHAIN,
+ 1615559719, // March 12, 2021
+ ROOT_HASH,
+ VALID_HOSTNAME,
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_fails_if_bad_hostname() {
+ nss::ensure_initialized();
+ assert!(verify(
+ VALID_INPUT,
+ VALID_SIGNATURE,
+ VALID_CERT_CHAIN,
+ 1615559719, // March 12, 2021
+ ROOT_HASH,
+ "some.hostname.org",
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_fails_if_bad_root_hash() {
+ nss::ensure_initialized();
+ assert!(verify(
+ VALID_INPUT,
+ VALID_SIGNATURE,
+ VALID_CERT_CHAIN,
+ 1615559719, // March 12, 2021
+ "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
+ VALID_HOSTNAME,
+ )
+ .is_err());
+ }
+
+ #[test]
+ fn test_verify_succeeds_if_valid() {
+ nss::ensure_initialized();
+ verify(
+ VALID_INPUT,
+ VALID_SIGNATURE,
+ VALID_CERT_CHAIN,
+ 1615559719, // March 12, 2021
+ ROOT_HASH,
+ VALID_HOSTNAME,
+ )
+ .unwrap();
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/digest.rs b/third_party/rust/rc_crypto/src/digest.rs
@@ -0,0 +1,77 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::error::*;
+
+pub use nss::pk11::context::HashAlgorithm::{self as Algorithm, *};
+
+/// A calculated digest value.
+#[derive(Clone)]
+pub struct Digest {
+ pub(crate) value: Vec<u8>,
+ pub(crate) algorithm: Algorithm,
+}
+
+impl Digest {
+ pub fn algorithm(&self) -> &Algorithm {
+ &self.algorithm
+ }
+}
+
+impl AsRef<[u8]> for Digest {
+ fn as_ref(&self) -> &[u8] {
+ self.value.as_ref()
+ }
+}
+
+/// Returns the digest of data using the given digest algorithm.
+pub fn digest(algorithm: &Algorithm, data: &[u8]) -> Result<Digest> {
+ let value = nss::pk11::context::hash_buf(algorithm, data)?;
+ Ok(Digest {
+ value,
+ algorithm: *algorithm,
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ const MESSAGE: &[u8] = b"bobo";
+ const DIGEST_HEX: &str = "bf0c97708b849de696e7373508b13c5ea92bafa972fc941d694443e494a4b84d";
+
+ #[test]
+ fn sha256_digest() {
+ nss::ensure_initialized();
+ assert_eq!(hex::encode(digest(&SHA256, MESSAGE).unwrap()), DIGEST_HEX);
+ assert_ne!(
+ hex::encode(digest(&SHA256, b"notbobo").unwrap()),
+ DIGEST_HEX
+ );
+ }
+
+ #[test]
+ fn digest_cleanly_rejects_gigantic_messages() {
+ nss::ensure_initialized();
+ let message = vec![0; (i32::MAX as usize) + 1];
+ assert!(digest(&SHA256, &message).is_err());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/ece_crypto.rs b/third_party/rust/rc_crypto/src/ece_crypto.rs
@@ -0,0 +1,188 @@
+/* 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 crate::{
+ aead,
+ agreement::{self, Curve, EcKey, UnparsedPublicKey},
+ digest, hkdf, hmac, rand,
+};
+use ece::crypto::{Cryptographer, EcKeyComponents, LocalKeyPair, RemotePublicKey};
+
+impl From<crate::Error> for ece::Error {
+ fn from(_: crate::Error) -> Self {
+ ece::Error::CryptoError
+ }
+}
+
+pub struct RcCryptoLocalKeyPair {
+ wrapped: agreement::KeyPair<agreement::Static>,
+}
+// SECKEYPrivateKeyStr and SECKEYPublicKeyStr are Sync.
+unsafe impl Sync for RcCryptoLocalKeyPair {}
+
+impl RcCryptoLocalKeyPair {
+ pub fn from_raw_components(components: &EcKeyComponents) -> Result<Self, ece::Error> {
+ let ec_key = EcKey::new(
+ Curve::P256,
+ components.private_key(),
+ components.public_key(),
+ );
+ let priv_key = agreement::PrivateKey::<agreement::Static>::import(&ec_key)?;
+ let wrapped = agreement::KeyPair::<agreement::Static>::from_private_key(priv_key)?;
+ Ok(RcCryptoLocalKeyPair { wrapped })
+ }
+
+ pub fn generate_random() -> Result<Self, ece::Error> {
+ let wrapped = agreement::KeyPair::<agreement::Static>::generate(&agreement::ECDH_P256)?;
+ Ok(RcCryptoLocalKeyPair { wrapped })
+ }
+
+ fn agree(&self, peer: &RcCryptoRemotePublicKey) -> Result<Vec<u8>, ece::Error> {
+ let peer_public_key_raw_bytes = &peer.as_raw()?;
+ let peer_public_key =
+ UnparsedPublicKey::new(&agreement::ECDH_P256, peer_public_key_raw_bytes);
+ self.wrapped
+ .private_key()
+ .agree_static(&peer_public_key)?
+ .derive(|z| Ok(z.to_vec()))
+ }
+}
+
+impl LocalKeyPair for RcCryptoLocalKeyPair {
+ fn raw_components(&self) -> Result<EcKeyComponents, ece::Error> {
+ let ec_key = self.wrapped.private_key().export()?;
+ Ok(EcKeyComponents::new(
+ ec_key.private_key(),
+ ec_key.public_key(),
+ ))
+ }
+
+ fn pub_as_raw(&self) -> Result<Vec<u8>, ece::Error> {
+ let bytes = self.wrapped.public_key().to_bytes()?;
+ Ok(bytes.to_vec())
+ }
+
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+}
+pub struct RcCryptoRemotePublicKey {
+ raw: Vec<u8>,
+}
+
+impl RcCryptoRemotePublicKey {
+ pub fn from_raw(bytes: &[u8]) -> Result<RcCryptoRemotePublicKey, ece::Error> {
+ Ok(RcCryptoRemotePublicKey {
+ raw: bytes.to_owned(),
+ })
+ }
+}
+
+impl RemotePublicKey for RcCryptoRemotePublicKey {
+ fn as_raw(&self) -> Result<Vec<u8>, ece::Error> {
+ Ok(self.raw.to_vec())
+ }
+
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+}
+
+pub(crate) struct RcCryptoCryptographer;
+
+impl Cryptographer for RcCryptoCryptographer {
+ fn generate_ephemeral_keypair(&self) -> Result<Box<dyn LocalKeyPair>, ece::Error> {
+ Ok(Box::new(RcCryptoLocalKeyPair::generate_random()?))
+ }
+
+ fn import_key_pair(
+ &self,
+ components: &EcKeyComponents,
+ ) -> Result<Box<dyn LocalKeyPair>, ece::Error> {
+ Ok(Box::new(RcCryptoLocalKeyPair::from_raw_components(
+ components,
+ )?))
+ }
+
+ fn import_public_key(&self, raw: &[u8]) -> Result<Box<dyn RemotePublicKey>, ece::Error> {
+ Ok(Box::new(RcCryptoRemotePublicKey::from_raw(raw)?))
+ }
+
+ fn compute_ecdh_secret(
+ &self,
+ remote: &dyn RemotePublicKey,
+ local: &dyn LocalKeyPair,
+ ) -> Result<Vec<u8>, ece::Error> {
+ let local_any = local.as_any();
+ let local = local_any.downcast_ref::<RcCryptoLocalKeyPair>().unwrap();
+ let remote_any = remote.as_any();
+ let remote = remote_any
+ .downcast_ref::<RcCryptoRemotePublicKey>()
+ .unwrap();
+ local.agree(remote)
+ }
+
+ fn hkdf_sha256(
+ &self,
+ salt: &[u8],
+ secret: &[u8],
+ info: &[u8],
+ len: usize,
+ ) -> Result<Vec<u8>, ece::Error> {
+ let salt = hmac::SigningKey::new(&digest::SHA256, salt);
+ let mut out = vec![0u8; len];
+ hkdf::extract_and_expand(&salt, secret, info, &mut out)?;
+ Ok(out)
+ }
+
+ fn aes_gcm_128_encrypt(
+ &self,
+ key: &[u8],
+ iv: &[u8],
+ data: &[u8],
+ ) -> Result<Vec<u8>, ece::Error> {
+ let key = aead::SealingKey::new(&aead::AES_128_GCM, key)?;
+ let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_128_GCM, iv)?;
+ Ok(aead::seal(&key, nonce, aead::Aad::empty(), data)?)
+ }
+
+ fn aes_gcm_128_decrypt(
+ &self,
+ key: &[u8],
+ iv: &[u8],
+ ciphertext_and_tag: &[u8],
+ ) -> Result<Vec<u8>, ece::Error> {
+ let key = aead::OpeningKey::new(&aead::AES_128_GCM, key)?;
+ let nonce = aead::Nonce::try_assume_unique_for_key(&aead::AES_128_GCM, iv)?;
+ Ok(aead::open(
+ &key,
+ nonce,
+ aead::Aad::empty(),
+ ciphertext_and_tag,
+ )?)
+ }
+
+ fn random_bytes(&self, dest: &mut [u8]) -> Result<(), ece::Error> {
+ Ok(rand::fill(dest)?)
+ }
+}
+
+// Please call `rc_crypto::ensure_initialized()` instead of calling
+// this function directly.
+pub(crate) fn init() {
+ ece::crypto::set_cryptographer(&crate::ece_crypto::RcCryptoCryptographer)
+ .expect("Failed to initialize `ece` cryptographer!")
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_cryptographer_backend() {
+ nss::ensure_initialized();
+ crate::ensure_initialized();
+ ece::crypto::test_cryptographer(RcCryptoCryptographer);
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/error.rs b/third_party/rust/rc_crypto/src/error.rs
@@ -0,0 +1,38 @@
+/* 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/. */
+
+#[derive(Debug, thiserror::Error)]
+pub enum ErrorKind {
+ #[error("NSS error: {0}")]
+ NSSError(#[from] nss::Error),
+ #[error("Internal crypto error")]
+ InternalError,
+ #[error("Conversion error: {0}")]
+ ConversionError(#[from] std::num::TryFromIntError),
+ #[error("Root hash format error: {0}")]
+ RootHashFormatError(String),
+ #[error("PEM content format error: {0}")]
+ PEMFormatError(String),
+ #[error("Certificate content error: {0}")]
+ CertificateContentError(String),
+ #[error("Certificate not yet valid or expired")]
+ CertificateValidityError,
+ #[error("Certificate subject mismatch")]
+ CertificateSubjectError,
+ #[error("Certificate issuer mismatch")]
+ CertificateIssuerError,
+ #[error("Certificate chain of trust error: {0}")]
+ CertificateChainError(String),
+ #[error("Signature content error: {0}")]
+ SignatureContentError(String),
+ #[error("Content signature mismatch error: {0}")]
+ SignatureMismatchError(String),
+}
+
+error_support::define_error! {
+ ErrorKind {
+ (ConversionError, std::num::TryFromIntError),
+ (NSSError, nss::Error),
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/hawk_crypto.rs b/third_party/rust/rc_crypto/src/hawk_crypto.rs
@@ -0,0 +1,161 @@
+/* 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 crate::{digest, hmac, rand};
+use hawk::crypto as hc;
+
+impl From<crate::Error> for hc::CryptoError {
+ // Our errors impl `Fail`, so we can do this.
+ fn from(e: crate::Error) -> Self {
+ hc::CryptoError::Other(e.into())
+ }
+}
+
+pub(crate) struct RcCryptoCryptographer;
+
+impl hc::HmacKey for crate::hmac::SigningKey {
+ fn sign(&self, data: &[u8]) -> Result<Vec<u8>, hc::CryptoError> {
+ let digest = hmac::sign(self, data)?;
+ Ok(digest.as_ref().into())
+ }
+}
+
+// I don't really see a reason to bother doing incremental hashing here. A
+// one-shot is going to be faster in many cases anyway, and the higher memory
+// usage probably doesn't matter given our usage.
+struct NssHasher {
+ buffer: Vec<u8>,
+ algorithm: &'static digest::Algorithm,
+}
+
+impl hc::Hasher for NssHasher {
+ fn update(&mut self, data: &[u8]) -> Result<(), hc::CryptoError> {
+ self.buffer.extend_from_slice(data);
+ Ok(())
+ }
+
+ fn finish(&mut self) -> Result<Vec<u8>, hc::CryptoError> {
+ let digest = digest::digest(self.algorithm, &self.buffer)?;
+ let bytes: &[u8] = digest.as_ref();
+ Ok(bytes.to_owned())
+ }
+}
+
+impl hc::Cryptographer for RcCryptoCryptographer {
+ fn rand_bytes(&self, output: &mut [u8]) -> Result<(), hc::CryptoError> {
+ rand::fill(output)?;
+ Ok(())
+ }
+
+ fn new_key(
+ &self,
+ algorithm: hawk::DigestAlgorithm,
+ key: &[u8],
+ ) -> Result<Box<dyn hc::HmacKey>, hc::CryptoError> {
+ let k = hmac::SigningKey::new(to_rc_crypto_algorithm(algorithm)?, key);
+ Ok(Box::new(k))
+ }
+
+ fn constant_time_compare(&self, a: &[u8], b: &[u8]) -> bool {
+ crate::constant_time::verify_slices_are_equal(a, b).is_ok()
+ }
+
+ fn new_hasher(
+ &self,
+ algorithm: hawk::DigestAlgorithm,
+ ) -> Result<Box<dyn hc::Hasher>, hc::CryptoError> {
+ Ok(Box::new(NssHasher {
+ algorithm: to_rc_crypto_algorithm(algorithm)?,
+ buffer: vec![],
+ }))
+ }
+}
+
+fn to_rc_crypto_algorithm(
+ algorithm: hawk::DigestAlgorithm,
+) -> Result<&'static digest::Algorithm, hc::CryptoError> {
+ match algorithm {
+ hawk::DigestAlgorithm::Sha256 => Ok(&digest::SHA256),
+ algo => Err(hc::CryptoError::UnsupportedDigest(algo)),
+ }
+}
+
+// Note: this doesn't initialize NSS!
+pub(crate) fn init() {
+ hawk::crypto::set_cryptographer(&crate::hawk_crypto::RcCryptoCryptographer)
+ .expect("Failed to initialize `hawk` cryptographer!")
+}
+
+#[cfg(test)]
+mod test {
+
+ // Based on rust-hawk's hash_consistency. This fails if we've messed up the hashing.
+ #[test]
+ fn test_hawk_hashing() {
+ nss::ensure_initialized();
+ crate::ensure_initialized();
+
+ let mut hasher1 = hawk::PayloadHasher::new("text/plain", hawk::SHA256).unwrap();
+ hasher1.update("pày").unwrap();
+ hasher1.update("load").unwrap();
+ let hash1 = hasher1.finish().unwrap();
+
+ let mut hasher2 = hawk::PayloadHasher::new("text/plain", hawk::SHA256).unwrap();
+ hasher2.update("pàyload").unwrap();
+ let hash2 = hasher2.finish().unwrap();
+
+ let hash3 = hawk::PayloadHasher::hash("text/plain", hawk::SHA256, "pàyload").unwrap();
+
+ let hash4 = // "pàyload" as utf-8 bytes
+ hawk::PayloadHasher::hash("text/plain", hawk::SHA256, [112, 195, 160, 121, 108, 111, 97, 100]).unwrap();
+
+ assert_eq!(
+ hash1,
+ &[
+ 228, 238, 241, 224, 235, 114, 158, 112, 211, 254, 118, 89, 25, 236, 87, 176, 181,
+ 54, 61, 135, 42, 223, 188, 103, 194, 59, 83, 36, 136, 31, 198, 50
+ ]
+ );
+ assert_eq!(hash2, hash1);
+ assert_eq!(hash3, hash1);
+ assert_eq!(hash4, hash1);
+ }
+
+ // Based on rust-hawk's test_make_mac. This fails if we've messed up the signing.
+ #[test]
+ fn test_hawk_signing() {
+ nss::ensure_initialized();
+ crate::ensure_initialized();
+
+ let key = hawk::Key::new(
+ [
+ 11u8, 19, 228, 209, 79, 189, 200, 59, 166, 47, 86, 254, 235, 184, 120, 197, 75,
+ 152, 201, 79, 115, 61, 111, 242, 219, 187, 173, 14, 227, 108, 60, 232,
+ ],
+ hawk::SHA256,
+ )
+ .unwrap();
+
+ let mac = hawk::mac::Mac::new(
+ hawk::mac::MacType::Header,
+ &key,
+ std::time::UNIX_EPOCH + std::time::Duration::new(1000, 100),
+ "nonny",
+ "POST",
+ "mysite.com",
+ 443,
+ "/v1/api",
+ None,
+ None,
+ )
+ .unwrap();
+ assert_eq!(
+ mac.as_ref(),
+ &[
+ 192, 227, 235, 121, 157, 185, 197, 79, 189, 214, 235, 139, 9, 232, 99, 55, 67, 30,
+ 68, 0, 150, 187, 192, 238, 21, 200, 209, 107, 245, 159, 243, 178
+ ]
+ );
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/hkdf.rs b/third_party/rust/rc_crypto/src/hkdf.rs
@@ -0,0 +1,136 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::{error::*, hmac};
+
+pub fn extract_and_expand(
+ salt: &hmac::SigningKey,
+ secret: &[u8],
+ info: &[u8],
+ out: &mut [u8],
+) -> Result<()> {
+ let prk = extract(salt, secret)?;
+ expand(&prk, info, out)?;
+ Ok(())
+}
+
+pub fn extract(salt: &hmac::SigningKey, secret: &[u8]) -> Result<hmac::SigningKey> {
+ let prk = hmac::sign(salt, secret)?;
+ Ok(hmac::SigningKey::new(salt.digest_algorithm(), prk.as_ref()))
+}
+
+pub fn expand(prk: &hmac::SigningKey, info: &[u8], out: &mut [u8]) -> Result<()> {
+ let mut derived =
+ nss::pk11::sym_key::hkdf_expand(prk.digest_alg, &prk.key_value, info, out.len())?;
+ out.swap_with_slice(&mut derived[0..out.len()]);
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::digest;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn hkdf_produces_correct_result() {
+ ensure_initialized();
+ let secret = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+ let salt = hex::decode("000102030405060708090a0b0c").unwrap();
+ let info = hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap();
+ let expected_out = hex::decode(
+ "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+ )
+ .unwrap();
+ let salt = hmac::SigningKey::new(&digest::SHA256, &salt);
+ let mut out = vec![0u8; expected_out.len()];
+ extract_and_expand(&salt, &secret, &info, &mut out).unwrap();
+ assert_eq!(out, expected_out);
+ }
+
+ #[test]
+ fn hkdf_rejects_gigantic_salt() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let salt_bytes = vec![0; (u32::MAX as usize) + 1];
+ let salt = hmac::SigningKey {
+ digest_alg: &digest::SHA256,
+ key_value: salt_bytes,
+ };
+ let mut out = vec![0u8; 8];
+ assert!(extract_and_expand(&salt, b"secret", b"info", &mut out).is_err());
+ }
+ }
+
+ #[test]
+ fn hkdf_rejects_gigantic_secret() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let salt = hmac::SigningKey::new(&digest::SHA256, b"salt");
+ let secret = vec![0; (u32::MAX as usize) + 1];
+ let mut out = vec![0u8; 8];
+ assert!(extract_and_expand(&salt, secret.as_slice(), b"info", &mut out).is_err());
+ }
+ }
+
+ // N.B. the `info `parameter is a `c_ulong`, and I can't figure out how to check whether
+ // `c_ulong` is smaller than `usize` in order to write a `hkdf_rejects_gigantic_info` test.
+
+ #[test]
+ fn hkdf_rejects_gigantic_output_buffers() {
+ ensure_initialized();
+ let salt = hmac::SigningKey::new(&digest::SHA256, b"salt");
+ let mut out = vec![0u8; 8160 + 1]; // RFC maximum (hashlen * 255) + 1
+ assert!(extract_and_expand(&salt, b"secret", b"info", &mut out).is_err());
+ }
+
+ #[test]
+ fn hkdf_rejects_zero_length_output_buffer() {
+ ensure_initialized();
+ let salt = hmac::SigningKey::new(&digest::SHA256, b"salt");
+ let mut out = vec![0u8; 0];
+ assert!(extract_and_expand(&salt, b"secret", b"info", &mut out).is_err());
+ }
+
+ #[test]
+ fn hkdf_can_produce_small_output() {
+ ensure_initialized();
+ let salt = hmac::SigningKey::new(&digest::SHA256, b"salt");
+ let mut out = vec![0u8; 1];
+ assert!(extract_and_expand(&salt, b"secret", b"info", &mut out).is_ok());
+ }
+
+ #[test]
+ fn hkdf_accepts_zero_length_info() {
+ ensure_initialized();
+ let salt = hmac::SigningKey::new(&digest::SHA256, b"salt");
+ let mut out = vec![0u8; 32];
+ assert!(extract_and_expand(&salt, b"secret", b"", &mut out).is_ok());
+ }
+
+ #[test]
+ fn hkdf_expand_rejects_short_prk() {
+ ensure_initialized();
+ let prk = hmac::SigningKey::new(&digest::SHA256, b"too short"); // must be >= HashLen
+ let mut out = vec![0u8; 8];
+ assert!(expand(&prk, b"info", &mut out).is_ok());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/hmac.rs b/third_party/rust/rc_crypto/src/hmac.rs
@@ -0,0 +1,210 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::{constant_time, digest, error::*};
+
+/// A calculated signature value.
+/// This is a type-safe wrappper that discourages attempts at comparing signatures
+/// for equality, which might naively be done using a non-constant-time comparison.
+#[derive(Clone)]
+pub struct Signature(pub(crate) digest::Digest);
+
+impl AsRef<[u8]> for Signature {
+ #[inline]
+ fn as_ref(&self) -> &[u8] {
+ self.0.as_ref()
+ }
+}
+
+/// A key to use for HMAC signing.
+pub struct SigningKey {
+ pub(crate) digest_alg: &'static digest::Algorithm,
+ pub(crate) key_value: Vec<u8>,
+}
+
+impl SigningKey {
+ pub fn new(digest_alg: &'static digest::Algorithm, key_value: &[u8]) -> Self {
+ SigningKey {
+ digest_alg,
+ key_value: key_value.to_vec(),
+ }
+ }
+
+ #[inline]
+ pub fn digest_algorithm(&self) -> &'static digest::Algorithm {
+ self.digest_alg
+ }
+}
+
+/// A key to use for HMAC authentication.
+pub struct VerificationKey {
+ wrapped: SigningKey,
+}
+
+impl VerificationKey {
+ pub fn new(digest_alg: &'static digest::Algorithm, key_value: &[u8]) -> Self {
+ VerificationKey {
+ wrapped: SigningKey::new(digest_alg, key_value),
+ }
+ }
+
+ #[inline]
+ pub fn digest_algorithm(&self) -> &'static digest::Algorithm {
+ self.wrapped.digest_algorithm()
+ }
+}
+
+/// Calculate the HMAC of `data` using `key` and verify it corresponds to the provided signature.
+pub fn verify(key: &VerificationKey, data: &[u8], signature: &[u8]) -> Result<()> {
+ verify_with_own_key(&key.wrapped, data, signature)
+}
+
+/// Equivalent to `verify` but allows the consumer to pass a `SigningKey`.
+pub fn verify_with_own_key(key: &SigningKey, data: &[u8], signature: &[u8]) -> Result<()> {
+ constant_time::verify_slices_are_equal(sign(key, data)?.as_ref(), signature)
+}
+
+/// Calculate the HMAC of `data` using `key`.
+pub fn sign(key: &SigningKey, data: &[u8]) -> Result<Signature> {
+ let value = nss::pk11::context::hmac_sign(key.digest_alg, &key.key_value, data)?;
+ Ok(Signature(digest::Digest {
+ value,
+ algorithm: *key.digest_alg,
+ }))
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use nss::ensure_initialized;
+
+ const KEY: &[u8] = b"key";
+ const MESSAGE: &[u8] = b"The quick brown fox jumps over the lazy dog";
+ const SIGNATURE_HEX: &str = "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8";
+
+ #[test]
+ fn hmac_sign() {
+ ensure_initialized();
+ let key = SigningKey::new(&digest::SHA256, KEY);
+ let signature = sign(&key, MESSAGE).unwrap();
+ let expected_signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert_eq!(signature.as_ref(), expected_signature.as_slice());
+ assert!(verify_with_own_key(&key, MESSAGE, &expected_signature).is_ok());
+ }
+
+ #[test]
+ fn hmac_sign_gives_different_signatures_for_different_keys() {
+ ensure_initialized();
+ let key = SigningKey::new(&digest::SHA256, b"another key");
+ let signature = sign(&key, MESSAGE).unwrap();
+ let expected_signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert_ne!(signature.as_ref(), expected_signature.as_slice());
+ }
+
+ #[test]
+ fn hmac_sign_gives_different_signatures_for_different_messages() {
+ ensure_initialized();
+ let key = SigningKey::new(&digest::SHA256, KEY);
+ let signature = sign(&key, b"a different message").unwrap();
+ let expected_signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert_ne!(signature.as_ref(), expected_signature.as_slice());
+ }
+
+ #[test]
+ fn hmac_verify() {
+ ensure_initialized();
+ let key = VerificationKey::new(&digest::SHA256, KEY);
+ let expected_signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert!(verify(&key, MESSAGE, &expected_signature).is_ok());
+ }
+
+ #[test]
+ fn hmac_verify_fails_with_incorrect_signature() {
+ ensure_initialized();
+ let key = VerificationKey::new(&digest::SHA256, KEY);
+ let signature = hex::decode(SIGNATURE_HEX).unwrap();
+ for i in 0..signature.len() {
+ let mut wrong_signature = signature.clone();
+ wrong_signature[i] = wrong_signature[i].wrapping_add(1);
+ assert!(verify(&key, MESSAGE, &wrong_signature).is_err());
+ }
+ }
+
+ #[test]
+ fn hmac_verify_fails_with_incorrect_key() {
+ ensure_initialized();
+ let key = VerificationKey::new(&digest::SHA256, b"wrong key");
+ let signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert!(verify(&key, MESSAGE, &signature).is_err());
+ }
+
+ #[test]
+ fn hmac_sign_cleanly_rejects_gigantic_keys() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let key_bytes = vec![0; (u32::MAX as usize) + 1];
+ // Direct construction of SigningKey to avoid instantiating the array.
+ let key = SigningKey {
+ digest_alg: &digest::SHA256,
+ key_value: key_bytes,
+ };
+ assert!(sign(&key, MESSAGE).is_err());
+ }
+ }
+
+ #[test]
+ fn hmac_verify_cleanly_rejects_gigantic_keys() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let key_bytes = vec![0; (u32::MAX as usize) + 1];
+ // Direct construction of VerificationKey to avoid instantiating the array.
+ let key = VerificationKey {
+ wrapped: SigningKey {
+ digest_alg: &digest::SHA256,
+ key_value: key_bytes,
+ },
+ };
+ let signature = hex::decode(SIGNATURE_HEX).unwrap();
+ assert!(verify(&key, MESSAGE, &signature).is_err());
+ }
+ }
+
+ #[test]
+ fn hmac_sign_cleanly_rejects_gigantic_messages() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let key = SigningKey::new(&digest::SHA256, KEY);
+ let message = vec![0; (u32::MAX as usize) + 1];
+ assert!(sign(&key, &message).is_err());
+ }
+ }
+
+ #[test]
+ fn hmac_verify_cleanly_rejects_gigantic_messages() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let key = VerificationKey::new(&digest::SHA256, KEY);
+ let signature = hex::decode(SIGNATURE_HEX).unwrap();
+ let message = vec![0; (u32::MAX as usize) + 1];
+ assert!(verify(&key, &message, &signature).is_err());
+ }
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/lib.rs b/third_party/rust/rc_crypto/src/lib.rs
@@ -0,0 +1,70 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#![allow(unknown_lints)]
+#![warn(rust_2018_idioms)]
+/// This crate provides all the cryptographic primitives required by
+/// this workspace, backed by the NSS library.
+/// The exposed API is pretty much the same as the `ring` crate.
+pub mod aead;
+pub mod agreement;
+pub mod constant_time;
+pub mod contentsignature;
+pub mod digest;
+#[cfg(feature = "ece")]
+pub mod ece_crypto;
+mod error;
+#[cfg(feature = "hawk")]
+mod hawk_crypto;
+pub mod hkdf;
+pub mod hmac;
+pub mod pbkdf2;
+pub mod rand;
+pub mod signature;
+
+// Expose `hawk` if the hawk feature is on. This avoids consumers needing to
+// configure this separately, which is more or less trivial to do incorrectly.
+#[cfg(feature = "hawk")]
+pub use hawk;
+
+// Expose `ece` if the ece feature is on. This avoids consumers needing to
+// configure this separately, which is more or less trivial to do incorrectly.
+#[cfg(feature = "ece")]
+pub use ece;
+
+pub use crate::error::{Error, ErrorKind, Result};
+
+/// Only required to be called if you intend to use this library in conjunction
+/// with the `hawk` or the `ece` crate.
+pub fn ensure_initialized() {
+ nss::assert_initialized();
+
+ #[cfg(any(feature = "hawk", feature = "ece"))]
+ {
+ static INIT_ONCE: std::sync::Once = std::sync::Once::new();
+ INIT_ONCE.call_once(|| {
+ #[cfg(feature = "hawk")]
+ crate::hawk_crypto::init();
+ #[cfg(feature = "ece")]
+ crate::ece_crypto::init();
+ });
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/pbkdf2.rs b/third_party/rust/rc_crypto/src/pbkdf2.rs
@@ -0,0 +1,208 @@
+/* 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 crate::error::*;
+use nss::pbkdf2::pbkdf2_key_derive;
+pub use nss::pbkdf2::HashAlgorithm;
+/// Extend passwords using pbkdf2, based on the following [rfc](https://www.ietf.org/rfc/rfc2898.txt) it runs the NSS implementation
+/// # Arguments
+///
+/// * `passphrase` - The password to stretch
+/// * `salt` - A salt to use in the generation process
+/// * `iterations` - The number of iterations the hashing algorithm will run on each section of the key
+/// * `hash_algorithm` - The hash algorithm to use
+/// * `out` - The slice the algorithm will populate
+///
+/// # Examples
+///
+/// ```
+/// use rc_crypto::pbkdf2;
+/// use nss::ensure_initialized;
+/// ensure_initialized();
+/// let password = b"password";
+/// let salt = b"salt";
+/// let mut out = vec![0u8; 32];
+/// let iterations = 2; // Real code should have a MUCH higher number of iterations (Think 1000+)
+/// pbkdf2::derive(password, salt, iterations, pbkdf2::HashAlgorithm::SHA256, &mut out).unwrap(); // Oh oh should handle the error!
+/// assert_eq!(hex::encode(out), "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43");
+//
+///```
+///
+/// # Errors
+///
+/// Could possibly return an error if the HMAC algorithm fails, or if the NSS algorithm returns an error
+pub fn derive(
+ passphrase: &[u8],
+ salt: &[u8],
+ iterations: u32,
+ hash_algorithm: HashAlgorithm,
+ out: &mut [u8],
+) -> Result<()> {
+ pbkdf2_key_derive(passphrase, salt, iterations, hash_algorithm, out)?;
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn test_generate_correct_out() {
+ ensure_initialized();
+ let expected = "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b";
+ let mut out = vec![0u8; 32];
+ let password = b"password";
+ let salt = b"salt";
+ derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_longer_key() {
+ ensure_initialized();
+ let expected = "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b4dbf3a2f3dad3377264bb7b8e8330d4efc7451418617dabef683735361cdc18c";
+ let password = b"password";
+ let salt = b"salt";
+ let mut out = vec![0u8; 64];
+ derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_more_iterations() {
+ ensure_initialized();
+ let expected = "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43";
+ let password = b"password";
+ let salt = b"salt";
+ let mut out = vec![0u8; 32];
+ derive(password, salt, 2, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_odd_length() {
+ ensure_initialized();
+ let expected = "ad35240ac683febfaf3cd49d845473fbbbaa2437f5f82d5a415ae00ac76c6bfccf";
+ let password = b"password";
+ let salt = b"salt";
+ let mut out = vec![0u8; 33];
+ derive(password, salt, 3, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_nulls() {
+ ensure_initialized();
+ let expected = "e25d526987819f966e324faa4a";
+ let password = b"passw\x00rd";
+ let salt = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+ let mut out = vec![0u8; 13];
+ derive(password, salt, 5, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_password_null() {
+ ensure_initialized();
+ let expected = "62384466264daadc4144018c6bd864648272b34da8980d31521ffcce92ae003b";
+ let password = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+ let salt = b"salt";
+ let mut out = vec![0u8; 32];
+ derive(password, salt, 2, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_empty_password() {
+ ensure_initialized();
+ let expected = "f135c27993baf98773c5cdb40a5706ce6a345cde61b000a67858650cd6a324d7";
+ let mut out = vec![0u8; 32];
+ let password = b"";
+ let salt = b"salt";
+ derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_empty_salt() {
+ ensure_initialized();
+ let expected = "c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab";
+ let mut out = vec![0u8; 32];
+ let password = b"password";
+ let salt = b"";
+ derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_tiny_out() {
+ ensure_initialized();
+ let expected = "12";
+ let mut out = vec![0u8; 1];
+ let password = b"password";
+ let salt = b"salt";
+ derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
+ assert_eq!(expected, hex::encode(out));
+ }
+
+ #[test]
+ fn test_rejects_zero_iterations() {
+ ensure_initialized();
+ let mut out = vec![0u8; 32];
+ let password = b"password";
+ let salt = b"salt";
+ assert!(derive(password, salt, 0, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+
+ #[test]
+ fn test_rejects_empty_out() {
+ ensure_initialized();
+ let mut out = vec![0u8; 0];
+ let password = b"password";
+ let salt = b"salt";
+ assert!(derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+
+ #[test]
+ fn test_rejects_gaigantic_salt() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let salt = vec![0; (u32::MAX as usize) + 1];
+ let mut out = vec![0u8; 1];
+ let password = b"password";
+ assert!(derive(password, &salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+ }
+ #[test]
+ fn test_rejects_gaigantic_password() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let password = vec![0; (u32::MAX as usize) + 1];
+ let mut out = vec![0u8; 1];
+ let salt = b"salt";
+ assert!(derive(&password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+ }
+
+ #[test]
+ fn test_rejects_gaigantic_out() {
+ ensure_initialized();
+ if (u32::MAX as usize) < usize::MAX {
+ let password = b"password";
+ let mut out = vec![0; (u32::MAX as usize) + 1];
+ let salt = b"salt";
+ assert!(derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+ }
+
+ #[test]
+ fn test_rejects_gaigantic_iterations() {
+ ensure_initialized();
+ let password = b"password";
+ let mut out = vec![0; 32];
+ let salt = b"salt";
+ assert!(derive(password, salt, u32::MAX, HashAlgorithm::SHA256, &mut out).is_err());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/rand.rs b/third_party/rust/rc_crypto/src/rand.rs
@@ -0,0 +1,79 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::error::*;
+
+/// Fill a buffer with cryptographically secure pseudo-random data.
+pub fn fill(dest: &mut [u8]) -> Result<()> {
+ Ok(nss::pk11::slot::generate_random(dest)?)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use nss::ensure_initialized;
+
+ #[test]
+ fn random_fill() {
+ ensure_initialized();
+
+ let mut out = vec![0u8; 64];
+ assert!(fill(&mut out).is_ok());
+ // This check could *in theory* fail if we randomly generate all zeroes
+ // but we're treating that probability as negligible in practice.
+ assert_ne!(out, vec![0u8; 64]);
+
+ let mut out2 = vec![0u8; 64];
+ assert!(fill(&mut out2).is_ok());
+ assert_ne!(out, vec![0u8; 64]);
+ assert_ne!(out2, out);
+ }
+
+ #[test]
+ fn random_fill_empty() {
+ ensure_initialized();
+
+ let mut out = vec![0u8; 0];
+ assert!(fill(&mut out).is_ok());
+ assert_eq!(out, vec![0u8; 0]);
+ }
+
+ #[test]
+ fn random_fill_oddly_sized_arrays() {
+ ensure_initialized();
+
+ let sizes: [usize; 4] = [61, 63, 65, 67];
+ for size in &sizes {
+ let mut out = vec![0u8; *size];
+ assert!(fill(&mut out).is_ok());
+ assert_ne!(out, vec![0u8; *size]);
+ }
+ }
+
+ #[test]
+ fn random_fill_rejects_attempts_to_fill_gigantic_arrays() {
+ ensure_initialized();
+
+ let max_size: usize = i32::MAX as usize;
+ let mut out = vec![0u8; max_size + 1];
+ assert!(fill(&mut out).is_err());
+ }
+}
diff --git a/third_party/rust/rc_crypto/src/signature.rs b/third_party/rust/rc_crypto/src/signature.rs
@@ -0,0 +1,111 @@
+/* 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/. */
+
+// This file contains code that was copied from the ring crate which is under
+// the ISC license, reproduced below:
+
+// Copyright 2015-2017 Brian Smith.
+
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use crate::Result;
+use nss::{ec::Curve, ec::PublicKey, pbkdf2::HashAlgorithm};
+
+/// A signature verification algorithm.
+pub struct VerificationAlgorithm {
+ curve: Curve,
+ digest_alg: HashAlgorithm,
+}
+
+pub static ECDSA_P256_SHA256: VerificationAlgorithm = VerificationAlgorithm {
+ curve: Curve::P256,
+ digest_alg: HashAlgorithm::SHA256,
+};
+
+pub static ECDSA_P384_SHA384: VerificationAlgorithm = VerificationAlgorithm {
+ curve: Curve::P384,
+ digest_alg: HashAlgorithm::SHA384,
+};
+
+/// An unparsed public key for signature operations.
+pub struct UnparsedPublicKey<'a> {
+ alg: &'static VerificationAlgorithm,
+ bytes: &'a [u8],
+}
+
+impl<'a> UnparsedPublicKey<'a> {
+ pub fn new(algorithm: &'static VerificationAlgorithm, bytes: &'a [u8]) -> Self {
+ Self {
+ alg: algorithm,
+ bytes,
+ }
+ }
+
+ pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<()> {
+ let pub_key = PublicKey::from_bytes(self.alg.curve, self.bytes)?;
+ Ok(pub_key.verify(message, signature, self.alg.digest_alg)?)
+ }
+
+ pub fn algorithm(&self) -> &'static VerificationAlgorithm {
+ self.alg
+ }
+
+ pub fn bytes(&self) -> &'a [u8] {
+ self.bytes
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
+ use nss::ensure_initialized;
+
+ #[test]
+ fn test_ecdsa_p384_sha384_verify() {
+ ensure_initialized();
+ // Test generated with JS DOM's WebCrypto.
+ let pub_key_bytes = URL_SAFE_NO_PAD.decode(
+ "BMZj_xHOfLQn5DIEQcYUkyASDWo8O30gWdkWXHHHWN5owKhGWplYHEb4PLf3DkFTg_smprr-ApdULy3NV10x8IZ0EfVaUZdXvTquH1kiw2PxD7fhqiozMXUaSuZI5KBE6w",
+ ).unwrap();
+ let message = URL_SAFE_NO_PAD.decode(
+ "F9MQDmEEdvOfm-NkCRrXqG-aVA9kq0xqtjvtWLndmmt6bO2gfLE2CVDDLzJYds0n88uz27c5JkzdsLpm5HP3aLFgD8bgnGm-EgdBpm99CRiIm7mAMbb0-NRAyUxeoGmdgJPVQLWFNoHRwzKV2wZ0Bk-Bq7jkeDHmDfnx-CJKVMQ",
+ )
+ .unwrap();
+ let signature = URL_SAFE_NO_PAD.decode(
+ "XLZmtJweW4qx0u0l6EpfmB5z-S-CNj4mrl9d7U0MuftdNPhmlNacV4AKR-i4uNn0TUIycU7GsfIjIqxuiL9WdAnfq_KH_SJ95mduqXgWNKlyt8JgMLd4h-jKOllh4erh",
+ )
+ .unwrap();
+ let public_key =
+ crate::signature::UnparsedPublicKey::new(&ECDSA_P384_SHA384, &pub_key_bytes);
+
+ // Failure case: Wrong key algorithm.
+ let public_key_wrong_alg =
+ crate::signature::UnparsedPublicKey::new(&ECDSA_P256_SHA256, &pub_key_bytes);
+ assert!(public_key_wrong_alg.verify(&message, &signature).is_err());
+
+ // Failure case: Add garbage to signature.
+ let mut garbage_signature = signature.clone();
+ garbage_signature.push(42);
+ assert!(public_key.verify(&message, &garbage_signature).is_err());
+
+ // Failure case: Flip a bit in message.
+ let mut garbage_message = message.clone();
+ garbage_message[42] = 42;
+ assert!(public_key.verify(&garbage_message, &signature).is_err());
+
+ // Happy case.
+ assert!(public_key.verify(&message, &signature).is_ok());
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustInitRustComponents.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustInitRustComponents.sys.mjs
@@ -0,0 +1,63 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import {
+ ArrayBufferDataStream,
+ FfiConverter,
+ FfiConverterArrayBuffer,
+ FfiConverterInt8,
+ FfiConverterUInt8,
+ FfiConverterInt16,
+ FfiConverterUInt16,
+ FfiConverterInt32,
+ FfiConverterUInt32,
+ FfiConverterInt64,
+ FfiConverterUInt64,
+ FfiConverterFloat32,
+ FfiConverterFloat64,
+ FfiConverterBoolean,
+ FfiConverterBytes,
+ FfiConverterString,
+ UniFFICallbackHandler,
+ UniFFICallbackMethodHandler,
+ UniFFIError,
+ UniFFIInternalError,
+ UniFFITypeError,
+ constructUniffiObject,
+ handleRustResult,
+ uniffiObjectPtr,
+} from "moz-src:///toolkit/components/uniffi-js/js/UniFFI.sys.mjs";
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {
+ uniffiObjectPtr,
+};
+/**
+ * Global initialization routines for Rust components, when `logins/keydb` feature is activated. Must be
+ * called before any other calls to Rust components.
+ *
+ * Receives the path to the profile directory.
+ *
+ * For adding additional initialization code: Note that this function is called very early in the
+ * app lifetime and therefore affects the startup time. Only the most necessary things should be
+ * done here.
+ * @param {string} profilePath
+ */
+export async function initialize(
+ profilePath) {
+
+FfiConverterString.checkType(profilePath);
+const result = await UniFFIScaffolding.callAsyncWrapper(
+ 7, // uniffi_init_rust_components_fn_func_initialize
+ FfiConverterString.lower(profilePath),
+)
+return handleRustResult(
+ result,
+ (result) => undefined,
+ null,
+)
+}
+
+
+
+
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustLogins.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustLogins.sys.mjs
@@ -0,0 +1,3668 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import {
+ ArrayBufferDataStream,
+ FfiConverter,
+ FfiConverterArrayBuffer,
+ FfiConverterInt8,
+ FfiConverterUInt8,
+ FfiConverterInt16,
+ FfiConverterUInt16,
+ FfiConverterInt32,
+ FfiConverterUInt32,
+ FfiConverterInt64,
+ FfiConverterUInt64,
+ FfiConverterFloat32,
+ FfiConverterFloat64,
+ FfiConverterBoolean,
+ FfiConverterBytes,
+ FfiConverterString,
+ UniFFICallbackHandler,
+ UniFFICallbackMethodHandler,
+ UniFFIError,
+ UniFFIInternalError,
+ UniFFITypeError,
+ constructUniffiObject,
+ handleRustResult,
+ uniffiObjectPtr,
+} from "moz-src:///toolkit/components/uniffi-js/js/UniFFI.sys.mjs";
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {
+ uniffiObjectPtr,
+};
+/**
+ * Check that key is still valid using the output of `create_canary`.
+ * @param {string} canary
+ * @param {string} text
+ * @param {string} encryptionKey
+ * @returns {boolean}
+ */
+export function checkCanary(
+ canary,
+ text,
+ encryptionKey) {
+
+FfiConverterString.checkType(canary);
+FfiConverterString.checkType(text);
+FfiConverterString.checkType(encryptionKey);
+const result = UniFFIScaffolding.callSync(
+ 8, // uniffi_logins_fn_func_check_canary
+ FfiConverterString.lower(canary),
+ FfiConverterString.lower(text),
+ FfiConverterString.lower(encryptionKey),
+)
+return handleRustResult(
+ result,
+ FfiConverterBoolean.lift.bind(FfiConverterBoolean),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+)
+}
+
+/**
+ * Create a "canary" string, which can be used to test if the encryption
+ * @param {string} text
+ * @param {string} encryptionKey
+ * @returns {string}
+ */
+export function createCanary(
+ text,
+ encryptionKey) {
+
+FfiConverterString.checkType(text);
+FfiConverterString.checkType(encryptionKey);
+const result = UniFFIScaffolding.callSync(
+ 9, // uniffi_logins_fn_func_create_canary
+ FfiConverterString.lower(text),
+ FfiConverterString.lower(encryptionKey),
+)
+return handleRustResult(
+ result,
+ FfiConverterString.lift.bind(FfiConverterString),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+)
+}
+
+/**
+ * We expose the crypto primitives on the namespace
+ * Create a new, random, encryption key.
+ * @returns {string}
+ */
+export function createKey() {
+
+const result = UniFFIScaffolding.callSync(
+ 10, // uniffi_logins_fn_func_create_key
+)
+return handleRustResult(
+ result,
+ FfiConverterString.lift.bind(FfiConverterString),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+)
+}
+
+/**
+ * createLoginStoreWithNssKeymanager
+ * @param {string} path
+ * @param {PrimaryPasswordAuthenticator} primaryPasswordAuthenticator
+ * @returns {LoginStore}
+ */
+export function createLoginStoreWithNssKeymanager(
+ path,
+ primaryPasswordAuthenticator) {
+
+FfiConverterString.checkType(path);
+FfiConverterTypePrimaryPasswordAuthenticator.checkType(primaryPasswordAuthenticator);
+const result = UniFFIScaffolding.callSync(
+ 11, // uniffi_logins_fn_func_create_login_store_with_nss_keymanager
+ FfiConverterString.lower(path),
+ FfiConverterTypePrimaryPasswordAuthenticator.lower(primaryPasswordAuthenticator),
+)
+return handleRustResult(
+ result,
+ FfiConverterTypeLoginStore.lift.bind(FfiConverterTypeLoginStore),
+ null,
+)
+}
+
+/**
+ * Create a LoginStore with StaticKeyManager by passing in a db path and a
+ * static key
+ * @param {string} path
+ * @param {string} key
+ * @returns {LoginStore}
+ */
+export function createLoginStoreWithStaticKeyManager(
+ path,
+ key) {
+
+FfiConverterString.checkType(path);
+FfiConverterString.checkType(key);
+const result = UniFFIScaffolding.callSync(
+ 12, // uniffi_logins_fn_func_create_login_store_with_static_key_manager
+ FfiConverterString.lower(path),
+ FfiConverterString.lower(key),
+)
+return handleRustResult(
+ result,
+ FfiConverterTypeLoginStore.lift.bind(FfiConverterTypeLoginStore),
+ null,
+)
+}
+
+/**
+ * Similar to create_static_key_manager above, create a
+ * ManagedEncryptorDecryptor by passing in a KeyManager
+ * @param {KeyManager} keyManager
+ * @returns {EncryptorDecryptor}
+ */
+export function createManagedEncdec(
+ keyManager) {
+
+FfiConverterTypeKeyManager.checkType(keyManager);
+const result = UniFFIScaffolding.callSync(
+ 13, // uniffi_logins_fn_func_create_managed_encdec
+ FfiConverterTypeKeyManager.lower(keyManager),
+)
+return handleRustResult(
+ result,
+ FfiConverterTypeEncryptorDecryptor.lift.bind(FfiConverterTypeEncryptorDecryptor),
+ null,
+)
+}
+
+/**
+ * Utility function to create a StaticKeyManager to be used for the time
+ * being until support lands for [trait implementation of an UniFFI
+ * interface](https://mozilla.github.io/uniffi-rs/next/proc_macro/index.html#structs-implementing-traits)
+ * in UniFFI.
+ * @param {string} key
+ * @returns {KeyManager}
+ */
+export function createStaticKeyManager(
+ key) {
+
+FfiConverterString.checkType(key);
+const result = UniFFIScaffolding.callSync(
+ 14, // uniffi_logins_fn_func_create_static_key_manager
+ FfiConverterString.lower(key),
+)
+return handleRustResult(
+ result,
+ FfiConverterTypeKeyManager.lift.bind(FfiConverterTypeKeyManager),
+ null,
+)
+}
+
+
+
+
+
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalString extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterString.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterString.read(dataStream)
+ default:
+ throw new UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterString.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterString.computeSize(value)
+ }
+}
+/**
+ * A login stored in the database
+ */
+export class Login {
+ constructor(
+ {
+ id,
+ timesUsed,
+ timeCreated,
+ timeLastUsed,
+ timePasswordChanged,
+ origin,
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ password,
+ username
+ } = {
+ id: undefined,
+ timesUsed: undefined,
+ timeCreated: undefined,
+ timeLastUsed: undefined,
+ timePasswordChanged: undefined,
+ origin: undefined,
+ httpRealm: undefined,
+ formActionOrigin: undefined,
+ usernameField: undefined,
+ passwordField: undefined,
+ password: undefined,
+ username: undefined
+ }
+ ) {
+ try {
+ FfiConverterString.checkType(id)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("id");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timesUsed)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timesUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timeCreated)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timeCreated");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timeLastUsed)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timeLastUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timePasswordChanged)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timePasswordChanged");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(origin)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("origin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(httpRealm)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("httpRealm");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(formActionOrigin)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("formActionOrigin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(usernameField)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("usernameField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(passwordField)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("passwordField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(password)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("password");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(username)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("username");
+ }
+ throw e;
+ }
+ /**
+ * id
+ */
+ this.id = id;
+ /**
+ * timesUsed
+ */
+ this.timesUsed = timesUsed;
+ /**
+ * timeCreated
+ */
+ this.timeCreated = timeCreated;
+ /**
+ * timeLastUsed
+ */
+ this.timeLastUsed = timeLastUsed;
+ /**
+ * timePasswordChanged
+ */
+ this.timePasswordChanged = timePasswordChanged;
+ /**
+ * origin
+ */
+ this.origin = origin;
+ /**
+ * httpRealm
+ */
+ this.httpRealm = httpRealm;
+ /**
+ * formActionOrigin
+ */
+ this.formActionOrigin = formActionOrigin;
+ /**
+ * usernameField
+ */
+ this.usernameField = usernameField;
+ /**
+ * passwordField
+ */
+ this.passwordField = passwordField;
+ /**
+ * password
+ */
+ this.password = password;
+ /**
+ * username
+ */
+ this.username = username;
+ }
+
+ equals(other) {
+ return (
+ this.id == other.id
+ && this.timesUsed == other.timesUsed
+ && this.timeCreated == other.timeCreated
+ && this.timeLastUsed == other.timeLastUsed
+ && this.timePasswordChanged == other.timePasswordChanged
+ && this.origin == other.origin
+ && this.httpRealm == other.httpRealm
+ && this.formActionOrigin == other.formActionOrigin
+ && this.usernameField == other.usernameField
+ && this.passwordField == other.passwordField
+ && this.password == other.password
+ && this.username == other.username
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLogin extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Login({
+ id: FfiConverterString.read(dataStream),
+ timesUsed: FfiConverterInt64.read(dataStream),
+ timeCreated: FfiConverterInt64.read(dataStream),
+ timeLastUsed: FfiConverterInt64.read(dataStream),
+ timePasswordChanged: FfiConverterInt64.read(dataStream),
+ origin: FfiConverterString.read(dataStream),
+ httpRealm: FfiConverterOptionalString.read(dataStream),
+ formActionOrigin: FfiConverterOptionalString.read(dataStream),
+ usernameField: FfiConverterString.read(dataStream),
+ passwordField: FfiConverterString.read(dataStream),
+ password: FfiConverterString.read(dataStream),
+ username: FfiConverterString.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterString.write(dataStream, value.id);
+ FfiConverterInt64.write(dataStream, value.timesUsed);
+ FfiConverterInt64.write(dataStream, value.timeCreated);
+ FfiConverterInt64.write(dataStream, value.timeLastUsed);
+ FfiConverterInt64.write(dataStream, value.timePasswordChanged);
+ FfiConverterString.write(dataStream, value.origin);
+ FfiConverterOptionalString.write(dataStream, value.httpRealm);
+ FfiConverterOptionalString.write(dataStream, value.formActionOrigin);
+ FfiConverterString.write(dataStream, value.usernameField);
+ FfiConverterString.write(dataStream, value.passwordField);
+ FfiConverterString.write(dataStream, value.password);
+ FfiConverterString.write(dataStream, value.username);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterString.computeSize(value.id);
+ totalSize += FfiConverterInt64.computeSize(value.timesUsed);
+ totalSize += FfiConverterInt64.computeSize(value.timeCreated);
+ totalSize += FfiConverterInt64.computeSize(value.timeLastUsed);
+ totalSize += FfiConverterInt64.computeSize(value.timePasswordChanged);
+ totalSize += FfiConverterString.computeSize(value.origin);
+ totalSize += FfiConverterOptionalString.computeSize(value.httpRealm);
+ totalSize += FfiConverterOptionalString.computeSize(value.formActionOrigin);
+ totalSize += FfiConverterString.computeSize(value.usernameField);
+ totalSize += FfiConverterString.computeSize(value.passwordField);
+ totalSize += FfiConverterString.computeSize(value.password);
+ totalSize += FfiConverterString.computeSize(value.username);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Login)) {
+ throw new UniFFITypeError(`Expected 'Login', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterString.checkType(value.id);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".id");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timesUsed);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timesUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timeCreated);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timeCreated");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timeLastUsed);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timeLastUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timePasswordChanged);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timePasswordChanged");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.origin);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".origin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(value.httpRealm);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".httpRealm");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(value.formActionOrigin);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".formActionOrigin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.usernameField);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".usernameField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.passwordField);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".passwordField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.password);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".password");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.username);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".username");
+ }
+ throw e;
+ }
+ }
+}
+/**
+ * A login entry from the user, not linked to any database record.
+ * The add/update APIs input these.
+ */
+export class LoginEntry {
+ constructor(
+ {
+ origin,
+ httpRealm,
+ formActionOrigin,
+ usernameField,
+ passwordField,
+ password,
+ username
+ } = {
+ origin: undefined,
+ httpRealm: undefined,
+ formActionOrigin: undefined,
+ usernameField: undefined,
+ passwordField: undefined,
+ password: undefined,
+ username: undefined
+ }
+ ) {
+ try {
+ FfiConverterString.checkType(origin)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("origin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(httpRealm)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("httpRealm");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(formActionOrigin)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("formActionOrigin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(usernameField)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("usernameField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(passwordField)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("passwordField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(password)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("password");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(username)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("username");
+ }
+ throw e;
+ }
+ /**
+ * origin
+ */
+ this.origin = origin;
+ /**
+ * httpRealm
+ */
+ this.httpRealm = httpRealm;
+ /**
+ * formActionOrigin
+ */
+ this.formActionOrigin = formActionOrigin;
+ /**
+ * usernameField
+ */
+ this.usernameField = usernameField;
+ /**
+ * passwordField
+ */
+ this.passwordField = passwordField;
+ /**
+ * password
+ */
+ this.password = password;
+ /**
+ * username
+ */
+ this.username = username;
+ }
+
+ equals(other) {
+ return (
+ this.origin == other.origin
+ && this.httpRealm == other.httpRealm
+ && this.formActionOrigin == other.formActionOrigin
+ && this.usernameField == other.usernameField
+ && this.passwordField == other.passwordField
+ && this.password == other.password
+ && this.username == other.username
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new LoginEntry({
+ origin: FfiConverterString.read(dataStream),
+ httpRealm: FfiConverterOptionalString.read(dataStream),
+ formActionOrigin: FfiConverterOptionalString.read(dataStream),
+ usernameField: FfiConverterString.read(dataStream),
+ passwordField: FfiConverterString.read(dataStream),
+ password: FfiConverterString.read(dataStream),
+ username: FfiConverterString.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterString.write(dataStream, value.origin);
+ FfiConverterOptionalString.write(dataStream, value.httpRealm);
+ FfiConverterOptionalString.write(dataStream, value.formActionOrigin);
+ FfiConverterString.write(dataStream, value.usernameField);
+ FfiConverterString.write(dataStream, value.passwordField);
+ FfiConverterString.write(dataStream, value.password);
+ FfiConverterString.write(dataStream, value.username);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterString.computeSize(value.origin);
+ totalSize += FfiConverterOptionalString.computeSize(value.httpRealm);
+ totalSize += FfiConverterOptionalString.computeSize(value.formActionOrigin);
+ totalSize += FfiConverterString.computeSize(value.usernameField);
+ totalSize += FfiConverterString.computeSize(value.passwordField);
+ totalSize += FfiConverterString.computeSize(value.password);
+ totalSize += FfiConverterString.computeSize(value.username);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof LoginEntry)) {
+ throw new UniFFITypeError(`Expected 'LoginEntry', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterString.checkType(value.origin);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".origin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(value.httpRealm);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".httpRealm");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalString.checkType(value.formActionOrigin);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".formActionOrigin");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.usernameField);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".usernameField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.passwordField);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".passwordField");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.password);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".password");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.username);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".username");
+ }
+ throw e;
+ }
+ }
+}
+/**
+ * Login data specific to database records.
+ * The add_with_record API inputs this.
+ */
+export class LoginMeta {
+ constructor(
+ {
+ id,
+ timesUsed,
+ timeCreated,
+ timeLastUsed,
+ timePasswordChanged
+ } = {
+ id: undefined,
+ timesUsed: undefined,
+ timeCreated: undefined,
+ timeLastUsed: undefined,
+ timePasswordChanged: undefined
+ }
+ ) {
+ try {
+ FfiConverterString.checkType(id)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("id");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timesUsed)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timesUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timeCreated)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timeCreated");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timeLastUsed)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timeLastUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(timePasswordChanged)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("timePasswordChanged");
+ }
+ throw e;
+ }
+ /**
+ * id
+ */
+ this.id = id;
+ /**
+ * timesUsed
+ */
+ this.timesUsed = timesUsed;
+ /**
+ * timeCreated
+ */
+ this.timeCreated = timeCreated;
+ /**
+ * timeLastUsed
+ */
+ this.timeLastUsed = timeLastUsed;
+ /**
+ * timePasswordChanged
+ */
+ this.timePasswordChanged = timePasswordChanged;
+ }
+
+ equals(other) {
+ return (
+ this.id == other.id
+ && this.timesUsed == other.timesUsed
+ && this.timeCreated == other.timeCreated
+ && this.timeLastUsed == other.timeLastUsed
+ && this.timePasswordChanged == other.timePasswordChanged
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginMeta extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new LoginMeta({
+ id: FfiConverterString.read(dataStream),
+ timesUsed: FfiConverterInt64.read(dataStream),
+ timeCreated: FfiConverterInt64.read(dataStream),
+ timeLastUsed: FfiConverterInt64.read(dataStream),
+ timePasswordChanged: FfiConverterInt64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterString.write(dataStream, value.id);
+ FfiConverterInt64.write(dataStream, value.timesUsed);
+ FfiConverterInt64.write(dataStream, value.timeCreated);
+ FfiConverterInt64.write(dataStream, value.timeLastUsed);
+ FfiConverterInt64.write(dataStream, value.timePasswordChanged);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterString.computeSize(value.id);
+ totalSize += FfiConverterInt64.computeSize(value.timesUsed);
+ totalSize += FfiConverterInt64.computeSize(value.timeCreated);
+ totalSize += FfiConverterInt64.computeSize(value.timeLastUsed);
+ totalSize += FfiConverterInt64.computeSize(value.timePasswordChanged);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof LoginMeta)) {
+ throw new UniFFITypeError(`Expected 'LoginMeta', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterString.checkType(value.id);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".id");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timesUsed);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timesUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timeCreated);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timeCreated");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timeLastUsed);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timeLastUsed");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterInt64.checkType(value.timePasswordChanged);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".timePasswordChanged");
+ }
+ throw e;
+ }
+ }
+}
+/**
+ * A login together with record fields, handed over to the store API; ie a login persisted
+ * elsewhere, useful for migrations
+ */
+export class LoginEntryWithMeta {
+ constructor(
+ {
+ entry,
+ meta
+ } = {
+ entry: undefined,
+ meta: undefined
+ }
+ ) {
+ try {
+ FfiConverterTypeLoginEntry.checkType(entry)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("entry");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeLoginMeta.checkType(meta)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("meta");
+ }
+ throw e;
+ }
+ /**
+ * entry
+ */
+ this.entry = entry;
+ /**
+ * meta
+ */
+ this.meta = meta;
+ }
+
+ equals(other) {
+ return (
+ this.entry.equals(other.entry)
+ && this.meta.equals(other.meta)
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginEntryWithMeta extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new LoginEntryWithMeta({
+ entry: FfiConverterTypeLoginEntry.read(dataStream),
+ meta: FfiConverterTypeLoginMeta.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterTypeLoginEntry.write(dataStream, value.entry);
+ FfiConverterTypeLoginMeta.write(dataStream, value.meta);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterTypeLoginEntry.computeSize(value.entry);
+ totalSize += FfiConverterTypeLoginMeta.computeSize(value.meta);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof LoginEntryWithMeta)) {
+ throw new UniFFITypeError(`Expected 'LoginEntryWithMeta', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterTypeLoginEntry.checkType(value.entry);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".entry");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeLoginMeta.checkType(value.meta);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".meta");
+ }
+ throw e;
+ }
+ }
+}
+
+
+/**
+ * Metrics tracking deletion of logins that cannot be decrypted, see `delete_undecryptable_records_for_remote_replacement`
+ * for more details
+ */
+export class LoginsDeletionMetrics {
+ constructor(
+ {
+ localDeleted,
+ mirrorDeleted
+ } = {
+ localDeleted: undefined,
+ mirrorDeleted: undefined
+ }
+ ) {
+ try {
+ FfiConverterUInt64.checkType(localDeleted)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("localDeleted");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterUInt64.checkType(mirrorDeleted)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("mirrorDeleted");
+ }
+ throw e;
+ }
+ /**
+ * localDeleted
+ */
+ this.localDeleted = localDeleted;
+ /**
+ * mirrorDeleted
+ */
+ this.mirrorDeleted = mirrorDeleted;
+ }
+
+ equals(other) {
+ return (
+ this.localDeleted == other.localDeleted
+ && this.mirrorDeleted == other.mirrorDeleted
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginsDeletionMetrics extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new LoginsDeletionMetrics({
+ localDeleted: FfiConverterUInt64.read(dataStream),
+ mirrorDeleted: FfiConverterUInt64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterUInt64.write(dataStream, value.localDeleted);
+ FfiConverterUInt64.write(dataStream, value.mirrorDeleted);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterUInt64.computeSize(value.localDeleted);
+ totalSize += FfiConverterUInt64.computeSize(value.mirrorDeleted);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof LoginsDeletionMetrics)) {
+ throw new UniFFITypeError(`Expected 'LoginsDeletionMetrics', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterUInt64.checkType(value.localDeleted);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".localDeleted");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterUInt64.checkType(value.mirrorDeleted);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".mirrorDeleted");
+ }
+ throw e;
+ }
+ }
+}
+
+/**
+ * A bulk insert result entry, returned by `add_many` and `add_many_with_meta`
+ */
+export class BulkResultEntry {}
+/**
+ * Success
+ */
+BulkResultEntry.Success = class extends BulkResultEntry{
+ constructor({login = undefined } = {}) {
+ super();
+ try {
+ FfiConverterTypeLogin.checkType(login);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("login");
+ }
+ throw e;
+ }
+ this.login = login;
+ }
+}
+/**
+ * Error
+ */
+BulkResultEntry.Error = class extends BulkResultEntry{
+ constructor({message = undefined } = {}) {
+ super();
+ try {
+ FfiConverterString.checkType(message);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("message");
+ }
+ throw e;
+ }
+ this.message = message;
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeBulkResultEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ // Use sequential indices (1-based) for the wire format to match the Rust scaffolding
+ switch (dataStream.readInt32()) {
+ case 1:
+ return new BulkResultEntry.Success({
+ login: FfiConverterTypeLogin.read(dataStream)
+ });
+ case 2:
+ return new BulkResultEntry.Error({
+ message: FfiConverterString.read(dataStream)
+ });
+ default:
+ throw new UniFFITypeError("Unknown BulkResultEntry variant");
+ }
+ }
+
+ static write(dataStream, value) {
+ // Use sequential indices (1-based) for the wire format to match the Rust scaffolding
+ if (value instanceof BulkResultEntry.Success) {
+ dataStream.writeInt32(1);
+ FfiConverterTypeLogin.write(dataStream, value.login);
+ return;
+ }
+ if (value instanceof BulkResultEntry.Error) {
+ dataStream.writeInt32(2);
+ FfiConverterString.write(dataStream, value.message);
+ return;
+ }
+ throw new UniFFITypeError("Unknown BulkResultEntry variant");
+ }
+
+ static computeSize(value) {
+ // Size of the Int indicating the variant
+ let totalSize = 4;
+ if (value instanceof BulkResultEntry.Success) {
+ totalSize += FfiConverterTypeLogin.computeSize(value.login);
+ return totalSize;
+ }
+ if (value instanceof BulkResultEntry.Error) {
+ totalSize += FfiConverterString.computeSize(value.message);
+ return totalSize;
+ }
+ throw new UniFFITypeError("Unknown BulkResultEntry variant");
+ }
+
+ static checkType(value) {
+ if (!(value instanceof BulkResultEntry)) {
+ throw new UniFFITypeError(`${value} is not a subclass instance of BulkResultEntry`);
+ }
+ }
+}
+
+/**
+ * LoginOrErrorMessage
+ */
+export const LoginOrErrorMessage = {
+ /**
+ * LOGIN
+ */
+ LOGIN: 0,
+ /**
+ * STRING
+ */
+ STRING: 1,
+};
+Object.freeze(LoginOrErrorMessage);
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginOrErrorMessage extends FfiConverterArrayBuffer {
+ static #validValues = Object.values(LoginOrErrorMessage)
+
+ static read(dataStream) {
+ // Use sequential indices (1-based) for the wire format to match the Rust scaffolding
+ switch (dataStream.readInt32()) {
+ case 1:
+ return LoginOrErrorMessage.LOGIN
+ case 2:
+ return LoginOrErrorMessage.STRING
+ default:
+ throw new UniFFITypeError("Unknown LoginOrErrorMessage variant");
+ }
+ }
+
+ static write(dataStream, value) {
+ // Use sequential indices (1-based) for the wire format to match the Rust scaffolding
+ if (value === LoginOrErrorMessage.LOGIN) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ if (value === LoginOrErrorMessage.STRING) {
+ dataStream.writeInt32(2);
+ return;
+ }
+ throw new UniFFITypeError("Unknown LoginOrErrorMessage variant");
+ }
+
+ static computeSize(value) {
+ return 4;
+ }
+
+ static checkType(value) {
+ // Check that the value is a valid enum variant
+ if (!this.#validValues.includes(value)) {
+ throw new UniFFITypeError(`${value} is not a valid value for LoginOrErrorMessage`);
+ }
+ }
+}
+
+/**
+ * These are the errors returned by our public API.
+ */
+export class LoginsApiError extends Error {}
+
+
+/**
+ * NSS not initialized.
+ */
+export class NssUninitialized extends LoginsApiError {
+
+ constructor(
+ ...params
+ ) {
+ super(...params);
+ }
+ toString() {
+ return `NssUninitialized: ${super.toString()}`
+ }
+}
+
+/**
+ * NSS error during authentication
+ */
+export class NssAuthenticationError extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `NssAuthenticationError: ${super.toString()}`
+ }
+}
+
+/**
+ * error during authentication (in PrimaryPasswordAuthenticator)
+ */
+export class AuthenticationError extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `AuthenticationError: ${super.toString()}`
+ }
+}
+
+/**
+ * authentication has been cancelled.
+ */
+export class AuthenticationCanceled extends LoginsApiError {
+
+ constructor(
+ ...params
+ ) {
+ super(...params);
+ }
+ toString() {
+ return `AuthenticationCanceled: ${super.toString()}`
+ }
+}
+
+/**
+ * The login data supplied is invalid. The reason will indicate what's wrong with it.
+ */
+export class InvalidRecord extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `InvalidRecord: ${super.toString()}`
+ }
+}
+
+/**
+ * Asking to do something with a guid which doesn't exist.
+ */
+export class NoSuchRecord extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `NoSuchRecord: ${super.toString()}`
+ }
+}
+
+/**
+ * Encryption key is missing.
+ */
+export class MissingKey extends LoginsApiError {
+
+ constructor(
+ ...params
+ ) {
+ super(...params);
+ }
+ toString() {
+ return `MissingKey: ${super.toString()}`
+ }
+}
+
+/**
+ * Encryption key is not valid.
+ */
+export class InvalidKey extends LoginsApiError {
+
+ constructor(
+ ...params
+ ) {
+ super(...params);
+ }
+ toString() {
+ return `InvalidKey: ${super.toString()}`
+ }
+}
+
+/**
+ * encryption failed
+ */
+export class EncryptionFailed extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `EncryptionFailed: ${super.toString()}`
+ }
+}
+
+/**
+ * decryption failed
+ */
+export class DecryptionFailed extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `DecryptionFailed: ${super.toString()}`
+ }
+}
+
+/**
+ * An operation was interrupted at the request of the consuming app.
+ */
+export class Interrupted extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `Interrupted: ${super.toString()}`
+ }
+}
+
+/**
+ * Sync reported that authentication failed and the user should re-enter their FxA password.
+ */
+export class SyncAuthInvalid extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `SyncAuthInvalid: ${super.toString()}`
+ }
+}
+
+/**
+ * something internal went wrong which doesn't have a public error value
+ * because the consuming app can not reasonably take any action to resolve it.
+ * The underlying error will have been logged and reported.
+ * (ideally would just be `Unexpected`, but that would be a breaking change)
+ */
+export class UnexpectedLoginsApiError extends LoginsApiError {
+
+ constructor(
+ reason,
+ ...params
+ ) {
+ const message = `reason: ${ reason }`;
+ super(message, ...params);
+ this.reason = reason;
+ }
+ toString() {
+ return `UnexpectedLoginsApiError: ${super.toString()}`
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginsApiError extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return new NssUninitialized(
+ );
+ case 2:
+ return new NssAuthenticationError(
+ FfiConverterString.read(dataStream)
+ );
+ case 3:
+ return new AuthenticationError(
+ FfiConverterString.read(dataStream)
+ );
+ case 4:
+ return new AuthenticationCanceled(
+ );
+ case 5:
+ return new InvalidRecord(
+ FfiConverterString.read(dataStream)
+ );
+ case 6:
+ return new NoSuchRecord(
+ FfiConverterString.read(dataStream)
+ );
+ case 7:
+ return new MissingKey(
+ );
+ case 8:
+ return new InvalidKey(
+ );
+ case 9:
+ return new EncryptionFailed(
+ FfiConverterString.read(dataStream)
+ );
+ case 10:
+ return new DecryptionFailed(
+ FfiConverterString.read(dataStream)
+ );
+ case 11:
+ return new Interrupted(
+ FfiConverterString.read(dataStream)
+ );
+ case 12:
+ return new SyncAuthInvalid(
+ FfiConverterString.read(dataStream)
+ );
+ case 13:
+ return new UnexpectedLoginsApiError(
+ FfiConverterString.read(dataStream)
+ );
+ default:
+ throw new UniFFITypeError("Unknown LoginsApiError variant");
+ }
+ }
+ static computeSize(value) {
+ // Size of the Int indicating the variant
+ let totalSize = 4;
+ if (value instanceof NssUninitialized) {
+ return totalSize;
+ }
+ if (value instanceof NssAuthenticationError) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof AuthenticationError) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof AuthenticationCanceled) {
+ return totalSize;
+ }
+ if (value instanceof InvalidRecord) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof NoSuchRecord) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof MissingKey) {
+ return totalSize;
+ }
+ if (value instanceof InvalidKey) {
+ return totalSize;
+ }
+ if (value instanceof EncryptionFailed) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof DecryptionFailed) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof Interrupted) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof SyncAuthInvalid) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ if (value instanceof UnexpectedLoginsApiError) {
+ totalSize += FfiConverterString.computeSize(value.reason);
+ return totalSize;
+ }
+ throw new UniFFITypeError("Unknown LoginsApiError variant");
+ }
+ static write(dataStream, value) {
+ if (value instanceof NssUninitialized) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ if (value instanceof NssAuthenticationError) {
+ dataStream.writeInt32(2);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof AuthenticationError) {
+ dataStream.writeInt32(3);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof AuthenticationCanceled) {
+ dataStream.writeInt32(4);
+ return;
+ }
+ if (value instanceof InvalidRecord) {
+ dataStream.writeInt32(5);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof NoSuchRecord) {
+ dataStream.writeInt32(6);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof MissingKey) {
+ dataStream.writeInt32(7);
+ return;
+ }
+ if (value instanceof InvalidKey) {
+ dataStream.writeInt32(8);
+ return;
+ }
+ if (value instanceof EncryptionFailed) {
+ dataStream.writeInt32(9);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof DecryptionFailed) {
+ dataStream.writeInt32(10);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof Interrupted) {
+ dataStream.writeInt32(11);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof SyncAuthInvalid) {
+ dataStream.writeInt32(12);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ if (value instanceof UnexpectedLoginsApiError) {
+ dataStream.writeInt32(13);
+ FfiConverterString.write(dataStream, value.reason);
+ return;
+ }
+ throw new UniFFITypeError("Unknown LoginsApiError variant");
+ }
+
+ static errorClass = LoginsApiError;
+}
+
+
+
+/**
+ * EncryptorDecryptor
+ */
+export class EncryptorDecryptor {
+ /**
+ * decrypt
+ * @param {string} ciphertext
+ * @returns {string}
+ */
+ decrypt(
+ ciphertext) {
+ throw Error("decrypt not implemented");
+ }
+ /**
+ * encrypt
+ * @param {string} cleartext
+ * @returns {string}
+ */
+ encrypt(
+ cleartext) {
+ throw Error("encrypt not implemented");
+ }
+
+}
+
+/**
+ * EncryptorDecryptor
+ */
+export class EncryptorDecryptorImpl extends EncryptorDecryptor {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+
+ /**
+ * decrypt
+ * @param {string} ciphertext
+ * @returns {string}
+ */
+ decrypt(
+ ciphertext) {
+
+ FfiConverterBytes.checkType(ciphertext);
+ const result = UniFFIScaffolding.callSync(
+ 15, // uniffi_logins_fn_method_encryptordecryptor_decrypt
+ FfiConverterTypeEncryptorDecryptor.lowerReceiver(this),
+ FfiConverterBytes.lower(ciphertext),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBytes.lift.bind(FfiConverterBytes),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * encrypt
+ * @param {string} cleartext
+ * @returns {string}
+ */
+ encrypt(
+ cleartext) {
+
+ FfiConverterBytes.checkType(cleartext);
+ const result = UniFFIScaffolding.callSync(
+ 16, // uniffi_logins_fn_method_encryptordecryptor_encrypt
+ FfiConverterTypeEncryptorDecryptor.lowerReceiver(this),
+ FfiConverterBytes.lower(cleartext),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBytes.lift.bind(FfiConverterBytes),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+}
+
+// FfiConverter for a trait interface. This is a hybrid of the FFIConverter regular interfaces and
+// for callback interfaces.
+//
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeEncryptorDecryptor extends FfiConverter {
+ // lift works like a regular interface
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new EncryptorDecryptorImpl(opts);
+ }
+
+ // lower treats value like a callback interface
+ static lower(value) {
+ if (!(value instanceof EncryptorDecryptor)) {
+ throw new UniFFITypeError("expected 'EncryptorDecryptor' subclass");
+ }
+ return uniffiCallbackHandlerLoginsEncryptorDecryptor.storeCallbackObj(value)
+ }
+
+ // lowerReceiver is used when calling methods on an interface we got from Rust,
+ // it treats value like a regular interface.
+ static lowerReceiver(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'EncryptorDecryptorImpl' instance");
+ }
+ return ptr;
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(3));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(3, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+const uniffiCallbackHandlerLoginsEncryptorDecryptor = new UniFFICallbackHandler(
+ "EncryptorDecryptor",
+ 2,
+ [
+ new UniFFICallbackMethodHandler(
+ "decrypt",
+ [
+ FfiConverterBytes,
+ ],
+ FfiConverterBytes.lower.bind(FfiConverterBytes),
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ new UniFFICallbackMethodHandler(
+ "encrypt",
+ [
+ FfiConverterBytes,
+ ],
+ FfiConverterBytes.lower.bind(FfiConverterBytes),
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ ]
+);
+
+// Allow the shutdown-related functionality to be tested in the unit tests
+UnitTestObjs.uniffiCallbackHandlerLoginsEncryptorDecryptor = uniffiCallbackHandlerLoginsEncryptorDecryptor;
+
+/**
+ * KeyManager
+ */
+export class KeyManager {
+ /**
+ * getKey
+ * @returns {string}
+ */
+ getKey() {
+ throw Error("getKey not implemented");
+ }
+
+}
+
+/**
+ * KeyManager
+ */
+export class KeyManagerImpl extends KeyManager {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+
+ /**
+ * getKey
+ * @returns {string}
+ */
+ getKey() {
+
+ const result = UniFFIScaffolding.callSync(
+ 17, // uniffi_logins_fn_method_keymanager_get_key
+ FfiConverterTypeKeyManager.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBytes.lift.bind(FfiConverterBytes),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+}
+
+// FfiConverter for a trait interface. This is a hybrid of the FFIConverter regular interfaces and
+// for callback interfaces.
+//
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeKeyManager extends FfiConverter {
+ // lift works like a regular interface
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new KeyManagerImpl(opts);
+ }
+
+ // lower treats value like a callback interface
+ static lower(value) {
+ if (!(value instanceof KeyManager)) {
+ throw new UniFFITypeError("expected 'KeyManager' subclass");
+ }
+ return uniffiCallbackHandlerLoginsKeyManager.storeCallbackObj(value)
+ }
+
+ // lowerReceiver is used when calling methods on an interface we got from Rust,
+ // it treats value like a regular interface.
+ static lowerReceiver(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'KeyManagerImpl' instance");
+ }
+ return ptr;
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(4));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(4, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+const uniffiCallbackHandlerLoginsKeyManager = new UniFFICallbackHandler(
+ "KeyManager",
+ 3,
+ [
+ new UniFFICallbackMethodHandler(
+ "getKey",
+ [
+ ],
+ FfiConverterBytes.lower.bind(FfiConverterBytes),
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ ]
+);
+
+// Allow the shutdown-related functionality to be tested in the unit tests
+UnitTestObjs.uniffiCallbackHandlerLoginsKeyManager = uniffiCallbackHandlerLoginsKeyManager;
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeLoginEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeLoginEntry.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeLoginEntry.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeLoginEntry.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeLoginEntry.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeBulkResultEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeBulkResultEntry.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeBulkResultEntry.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeBulkResultEntry.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeBulkResultEntry.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeLoginEntryWithMeta extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeLoginEntryWithMeta.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeLoginEntryWithMeta.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeLoginEntryWithMeta.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeLoginEntryWithMeta.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceString extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterString.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterString.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterString.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterString.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceBoolean extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterBoolean.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterBoolean.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterBoolean.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterBoolean.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypeLogin extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypeLogin.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypeLogin.read(dataStream)
+ default:
+ throw new UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypeLogin.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypeLogin.computeSize(value)
+ }
+}
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeLogin extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeLogin.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeLogin.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeLogin.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeLogin.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+/**
+ * LoginStoreInterface
+ */
+export class LoginStoreInterface {
+ /**
+ * add
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ add(
+ login) {
+ throw Error("add not implemented");
+ }
+ /**
+ * addMany
+ * @param {Array.<LoginEntry>} logins
+ * @returns {Array.<BulkResultEntry>}
+ */
+ addMany(
+ logins) {
+ throw Error("addMany not implemented");
+ }
+ /**
+ * addManyWithMeta
+ * @param {Array.<LoginEntryWithMeta>} entriesWithMeta
+ * @returns {Array.<BulkResultEntry>}
+ */
+ addManyWithMeta(
+ entriesWithMeta) {
+ throw Error("addManyWithMeta not implemented");
+ }
+ /**
+ * addOrUpdate
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ addOrUpdate(
+ login) {
+ throw Error("addOrUpdate not implemented");
+ }
+ /**
+ * addWithMeta
+ * @param {LoginEntryWithMeta} entryWithMeta
+ * @returns {Login}
+ */
+ addWithMeta(
+ entryWithMeta) {
+ throw Error("addWithMeta not implemented");
+ }
+ /**
+ * count
+ * @returns {number}
+ */
+ count() {
+ throw Error("count not implemented");
+ }
+ /**
+ * countByFormActionOrigin
+ * @param {string} formActionOrigin
+ * @returns {number}
+ */
+ countByFormActionOrigin(
+ formActionOrigin) {
+ throw Error("countByFormActionOrigin not implemented");
+ }
+ /**
+ * countByOrigin
+ * @param {string} origin
+ * @returns {number}
+ */
+ countByOrigin(
+ origin) {
+ throw Error("countByOrigin not implemented");
+ }
+ /**
+ * delete
+ * @param {string} id
+ * @returns {boolean}
+ */
+ delete(
+ id) {
+ throw Error("delete not implemented");
+ }
+ /**
+ * deleteMany
+ * @param {Array.<string>} ids
+ * @returns {Array.<boolean>}
+ */
+ deleteMany(
+ ids) {
+ throw Error("deleteMany not implemented");
+ }
+ /**
+ * The `delete_undecryptable_records_for_remote_replacement` function locally deletes stored logins
+ * that cannot be decrypted and sets the last sync time to 0 so any existing server records can be downloaded
+ * and overwrite the locally deleted records.
+ *
+ * NB: This function was created to unblock iOS logins users who are unable to sync logins and should not be used
+ * outside of this use case.
+ * @returns {LoginsDeletionMetrics}
+ */
+ deleteUndecryptableRecordsForRemoteReplacement() {
+ throw Error("deleteUndecryptableRecordsForRemoteReplacement not implemented");
+ }
+ /**
+ * findLoginToUpdate
+ * @param {LoginEntry} look
+ * @returns {?Login}
+ */
+ findLoginToUpdate(
+ look) {
+ throw Error("findLoginToUpdate not implemented");
+ }
+ /**
+ * get
+ * @param {string} id
+ * @returns {?Login}
+ */
+ get(
+ id) {
+ throw Error("get not implemented");
+ }
+ /**
+ * getByBaseDomain
+ * @param {string} baseDomain
+ * @returns {Array.<Login>}
+ */
+ getByBaseDomain(
+ baseDomain) {
+ throw Error("getByBaseDomain not implemented");
+ }
+ /**
+ * getCheckpoint
+ * @returns {?string}
+ */
+ getCheckpoint() {
+ throw Error("getCheckpoint not implemented");
+ }
+ /**
+ * hasLoginsByBaseDomain
+ * @param {string} baseDomain
+ * @returns {boolean}
+ */
+ hasLoginsByBaseDomain(
+ baseDomain) {
+ throw Error("hasLoginsByBaseDomain not implemented");
+ }
+ /**
+ * isEmpty
+ * @returns {boolean}
+ */
+ isEmpty() {
+ throw Error("isEmpty not implemented");
+ }
+ /**
+ * list
+ * @returns {Array.<Login>}
+ */
+ list() {
+ throw Error("list not implemented");
+ }
+ /**
+ * registerWithSyncManager
+ */
+ registerWithSyncManager() {
+ throw Error("registerWithSyncManager not implemented");
+ }
+ /**
+ * reset
+ */
+ reset() {
+ throw Error("reset not implemented");
+ }
+ /**
+ * Run maintenance on the DB
+ *
+ * This is intended to be run during idle time and will take steps / to clean up / shrink the
+ * database.
+ */
+ async runMaintenance() {
+ throw Error("runMaintenance not implemented");
+ }
+ /**
+ * setCheckpoint
+ * @param {string} checkpoint
+ */
+ setCheckpoint(
+ checkpoint) {
+ throw Error("setCheckpoint not implemented");
+ }
+ /**
+ * shutdown
+ */
+ shutdown() {
+ throw Error("shutdown not implemented");
+ }
+ /**
+ * touch
+ * @param {string} id
+ */
+ touch(
+ id) {
+ throw Error("touch not implemented");
+ }
+ /**
+ * update
+ * @param {string} id
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ update(
+ id,
+ login) {
+ throw Error("update not implemented");
+ }
+ /**
+ * Clear out locally stored logins data
+ *
+ * If sync is enabled, then we will try to recover the data on the next sync.
+ *
+ * The main reason to call this is when regenerating a new encryption key.
+ * In that case, there's no reason to keep around the local data since it can't be decrypted.
+ * Calling `wipe_local` is better than keeping around these un-decryptable logins, since we
+ * might be able to recover the data via sync.
+ *
+ * This is a no-op for freshly created databases, so it's safe to call this whenever a key is
+ * generated.
+ */
+ wipeLocal() {
+ throw Error("wipeLocal not implemented");
+ }
+
+}
+
+/**
+ * LoginStore
+ */
+export class LoginStore extends LoginStoreInterface {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * init
+ * @param {string} path
+ * @param {EncryptorDecryptor} encdec
+ * @returns {LoginStore}
+ */
+ static init(
+ path,
+ encdec) {
+
+ FfiConverterString.checkType(path);
+ FfiConverterTypeEncryptorDecryptor.checkType(encdec);
+ const result = UniFFIScaffolding.callSync(
+ 18, // uniffi_logins_fn_constructor_loginstore_new
+ FfiConverterString.lower(path),
+ FfiConverterTypeEncryptorDecryptor.lower(encdec),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLoginStore.lift.bind(FfiConverterTypeLoginStore),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * add
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ add(
+ login) {
+
+ FfiConverterTypeLoginEntry.checkType(login);
+ const result = UniFFIScaffolding.callSync(
+ 19, // uniffi_logins_fn_method_loginstore_add
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterTypeLoginEntry.lower(login),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLogin.lift.bind(FfiConverterTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * addMany
+ * @param {Array.<LoginEntry>} logins
+ * @returns {Array.<BulkResultEntry>}
+ */
+ addMany(
+ logins) {
+
+ FfiConverterSequenceTypeLoginEntry.checkType(logins);
+ const result = UniFFIScaffolding.callSync(
+ 20, // uniffi_logins_fn_method_loginstore_add_many
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterSequenceTypeLoginEntry.lower(logins),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterSequenceTypeBulkResultEntry.lift.bind(FfiConverterSequenceTypeBulkResultEntry),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * addManyWithMeta
+ * @param {Array.<LoginEntryWithMeta>} entriesWithMeta
+ * @returns {Array.<BulkResultEntry>}
+ */
+ addManyWithMeta(
+ entriesWithMeta) {
+
+ FfiConverterSequenceTypeLoginEntryWithMeta.checkType(entriesWithMeta);
+ const result = UniFFIScaffolding.callSync(
+ 21, // uniffi_logins_fn_method_loginstore_add_many_with_meta
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterSequenceTypeLoginEntryWithMeta.lower(entriesWithMeta),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterSequenceTypeBulkResultEntry.lift.bind(FfiConverterSequenceTypeBulkResultEntry),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * addOrUpdate
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ addOrUpdate(
+ login) {
+
+ FfiConverterTypeLoginEntry.checkType(login);
+ const result = UniFFIScaffolding.callSync(
+ 22, // uniffi_logins_fn_method_loginstore_add_or_update
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterTypeLoginEntry.lower(login),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLogin.lift.bind(FfiConverterTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * addWithMeta
+ * @param {LoginEntryWithMeta} entryWithMeta
+ * @returns {Login}
+ */
+ addWithMeta(
+ entryWithMeta) {
+
+ FfiConverterTypeLoginEntryWithMeta.checkType(entryWithMeta);
+ const result = UniFFIScaffolding.callSync(
+ 23, // uniffi_logins_fn_method_loginstore_add_with_meta
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterTypeLoginEntryWithMeta.lower(entryWithMeta),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLogin.lift.bind(FfiConverterTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * count
+ * @returns {number}
+ */
+ count() {
+
+ const result = UniFFIScaffolding.callSync(
+ 24, // uniffi_logins_fn_method_loginstore_count
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterInt64.lift.bind(FfiConverterInt64),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * countByFormActionOrigin
+ * @param {string} formActionOrigin
+ * @returns {number}
+ */
+ countByFormActionOrigin(
+ formActionOrigin) {
+
+ FfiConverterString.checkType(formActionOrigin);
+ const result = UniFFIScaffolding.callSync(
+ 25, // uniffi_logins_fn_method_loginstore_count_by_form_action_origin
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(formActionOrigin),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterInt64.lift.bind(FfiConverterInt64),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * countByOrigin
+ * @param {string} origin
+ * @returns {number}
+ */
+ countByOrigin(
+ origin) {
+
+ FfiConverterString.checkType(origin);
+ const result = UniFFIScaffolding.callSync(
+ 26, // uniffi_logins_fn_method_loginstore_count_by_origin
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(origin),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterInt64.lift.bind(FfiConverterInt64),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * delete
+ * @param {string} id
+ * @returns {boolean}
+ */
+ delete(
+ id) {
+
+ FfiConverterString.checkType(id);
+ const result = UniFFIScaffolding.callSync(
+ 27, // uniffi_logins_fn_method_loginstore_delete
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(id),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBoolean.lift.bind(FfiConverterBoolean),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * deleteMany
+ * @param {Array.<string>} ids
+ * @returns {Array.<boolean>}
+ */
+ deleteMany(
+ ids) {
+
+ FfiConverterSequenceString.checkType(ids);
+ const result = UniFFIScaffolding.callSync(
+ 28, // uniffi_logins_fn_method_loginstore_delete_many
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterSequenceString.lower(ids),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterSequenceBoolean.lift.bind(FfiConverterSequenceBoolean),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * The `delete_undecryptable_records_for_remote_replacement` function locally deletes stored logins
+ * that cannot be decrypted and sets the last sync time to 0 so any existing server records can be downloaded
+ * and overwrite the locally deleted records.
+ *
+ * NB: This function was created to unblock iOS logins users who are unable to sync logins and should not be used
+ * outside of this use case.
+ * @returns {LoginsDeletionMetrics}
+ */
+ deleteUndecryptableRecordsForRemoteReplacement() {
+
+ const result = UniFFIScaffolding.callSync(
+ 29, // uniffi_logins_fn_method_loginstore_delete_undecryptable_records_for_remote_replacement
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLoginsDeletionMetrics.lift.bind(FfiConverterTypeLoginsDeletionMetrics),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * findLoginToUpdate
+ * @param {LoginEntry} look
+ * @returns {?Login}
+ */
+ findLoginToUpdate(
+ look) {
+
+ FfiConverterTypeLoginEntry.checkType(look);
+ const result = UniFFIScaffolding.callSync(
+ 30, // uniffi_logins_fn_method_loginstore_find_login_to_update
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterTypeLoginEntry.lower(look),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterOptionalTypeLogin.lift.bind(FfiConverterOptionalTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * get
+ * @param {string} id
+ * @returns {?Login}
+ */
+ get(
+ id) {
+
+ FfiConverterString.checkType(id);
+ const result = UniFFIScaffolding.callSync(
+ 31, // uniffi_logins_fn_method_loginstore_get
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(id),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterOptionalTypeLogin.lift.bind(FfiConverterOptionalTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * getByBaseDomain
+ * @param {string} baseDomain
+ * @returns {Array.<Login>}
+ */
+ getByBaseDomain(
+ baseDomain) {
+
+ FfiConverterString.checkType(baseDomain);
+ const result = UniFFIScaffolding.callSync(
+ 32, // uniffi_logins_fn_method_loginstore_get_by_base_domain
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(baseDomain),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterSequenceTypeLogin.lift.bind(FfiConverterSequenceTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * getCheckpoint
+ * @returns {?string}
+ */
+ getCheckpoint() {
+
+ const result = UniFFIScaffolding.callSync(
+ 33, // uniffi_logins_fn_method_loginstore_get_checkpoint
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterOptionalString.lift.bind(FfiConverterOptionalString),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * hasLoginsByBaseDomain
+ * @param {string} baseDomain
+ * @returns {boolean}
+ */
+ hasLoginsByBaseDomain(
+ baseDomain) {
+
+ FfiConverterString.checkType(baseDomain);
+ const result = UniFFIScaffolding.callSync(
+ 34, // uniffi_logins_fn_method_loginstore_has_logins_by_base_domain
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(baseDomain),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBoolean.lift.bind(FfiConverterBoolean),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * isEmpty
+ * @returns {boolean}
+ */
+ isEmpty() {
+
+ const result = UniFFIScaffolding.callSync(
+ 35, // uniffi_logins_fn_method_loginstore_is_empty
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterBoolean.lift.bind(FfiConverterBoolean),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * list
+ * @returns {Array.<Login>}
+ */
+ list() {
+
+ const result = UniFFIScaffolding.callSync(
+ 36, // uniffi_logins_fn_method_loginstore_list
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterSequenceTypeLogin.lift.bind(FfiConverterSequenceTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * registerWithSyncManager
+ */
+ registerWithSyncManager() {
+
+ const result = UniFFIScaffolding.callSync(
+ 37, // uniffi_logins_fn_method_loginstore_register_with_sync_manager
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ null,
+ )
+ }
+
+ /**
+ * reset
+ */
+ reset() {
+
+ const result = UniFFIScaffolding.callSync(
+ 38, // uniffi_logins_fn_method_loginstore_reset
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * Run maintenance on the DB
+ *
+ * This is intended to be run during idle time and will take steps / to clean up / shrink the
+ * database.
+ */
+ async runMaintenance() {
+
+ const result = await UniFFIScaffolding.callAsyncWrapper(
+ 39, // uniffi_logins_fn_method_loginstore_run_maintenance
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * setCheckpoint
+ * @param {string} checkpoint
+ */
+ setCheckpoint(
+ checkpoint) {
+
+ FfiConverterString.checkType(checkpoint);
+ const result = UniFFIScaffolding.callSync(
+ 40, // uniffi_logins_fn_method_loginstore_set_checkpoint
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(checkpoint),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * shutdown
+ */
+ shutdown() {
+
+ const result = UniFFIScaffolding.callSync(
+ 41, // uniffi_logins_fn_method_loginstore_shutdown
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ null,
+ )
+ }
+
+ /**
+ * touch
+ * @param {string} id
+ */
+ touch(
+ id) {
+
+ FfiConverterString.checkType(id);
+ const result = UniFFIScaffolding.callSync(
+ 42, // uniffi_logins_fn_method_loginstore_touch
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(id),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * update
+ * @param {string} id
+ * @param {LoginEntry} login
+ * @returns {Login}
+ */
+ update(
+ id,
+ login) {
+
+ FfiConverterString.checkType(id);
+ FfiConverterTypeLoginEntry.checkType(login);
+ const result = UniFFIScaffolding.callSync(
+ 43, // uniffi_logins_fn_method_loginstore_update
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ FfiConverterString.lower(id),
+ FfiConverterTypeLoginEntry.lower(login),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeLogin.lift.bind(FfiConverterTypeLogin),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * Clear out locally stored logins data
+ *
+ * If sync is enabled, then we will try to recover the data on the next sync.
+ *
+ * The main reason to call this is when regenerating a new encryption key.
+ * In that case, there's no reason to keep around the local data since it can't be decrypted.
+ * Calling `wipe_local` is better than keeping around these un-decryptable logins, since we
+ * might be able to recover the data via sync.
+ *
+ * This is a no-op for freshly created databases, so it's safe to call this whenever a key is
+ * generated.
+ */
+ wipeLocal() {
+
+ const result = UniFFIScaffolding.callSync(
+ 44, // uniffi_logins_fn_method_loginstore_wipe_local
+ FfiConverterTypeLoginStore.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLoginStore extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new LoginStore(opts);
+ }
+
+ static lower(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'LoginStore' instance");
+ }
+ return ptr;
+ }
+
+ static lowerReceiver(value) {
+ // This works exactly the same as lower for non-trait interfaces
+ return this.lower(value);
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(5));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(5, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+
+/**
+ * ManagedEncryptorDecryptorInterface
+ */
+export class ManagedEncryptorDecryptorInterface {
+
+}
+
+/**
+ * ManagedEncryptorDecryptor
+ */
+export class ManagedEncryptorDecryptor extends ManagedEncryptorDecryptorInterface {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * init
+ * @param {KeyManager} keyManager
+ * @returns {ManagedEncryptorDecryptor}
+ */
+ static init(
+ keyManager) {
+
+ FfiConverterTypeKeyManager.checkType(keyManager);
+ const result = UniFFIScaffolding.callSync(
+ 45, // uniffi_logins_fn_constructor_managedencryptordecryptor_new
+ FfiConverterTypeKeyManager.lower(keyManager),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeManagedEncryptorDecryptor.lift.bind(FfiConverterTypeManagedEncryptorDecryptor),
+ null,
+ )
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeManagedEncryptorDecryptor extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new ManagedEncryptorDecryptor(opts);
+ }
+
+ static lower(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'ManagedEncryptorDecryptor' instance");
+ }
+ return ptr;
+ }
+
+ static lowerReceiver(value) {
+ // This works exactly the same as lower for non-trait interfaces
+ return this.lower(value);
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(6));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(6, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+
+/**
+ * Use the `NSSKeyManager` to use NSS for key management.
+ *
+ * NSS stores keys in `key4.db` within the profile and wraps the key with a key derived from the
+ * primary password, if set. It defers to the provided `PrimaryPasswordAuthenticator`
+ * implementation to handle user authentication. Note that if no primary password is set, the
+ * wrapping key is deterministically derived from an empty string.
+ *
+ * Make sure to initialize NSS using `ensure_initialized_with_profile_dir` before creating a
+ * NSSKeyManager.
+ *
+ * # Examples
+ * ```no_run
+ * use async_trait::async_trait;
+ * use logins::encryption::KeyManager;
+ * use logins::{PrimaryPasswordAuthenticator, LoginsApiError, NSSKeyManager};
+ * use std::sync::Arc;
+ *
+ * struct MyPrimaryPasswordAuthenticator {}
+ *
+ * #[async_trait]
+ * impl PrimaryPasswordAuthenticator for MyPrimaryPasswordAuthenticator {
+ * async fn get_primary_password(&self) -> Result<String, LoginsApiError> {
+ * // Most likely, you would want to prompt for a password.
+ * // let password = prompt_string("primary password").unwrap_or_default();
+ * Ok("secret".to_string())
+ * }
+ *
+ * async fn on_authentication_success(&self) -> Result<(), LoginsApiError> {
+ * println!("success");
+ * Ok(())
+ * }
+ *
+ * async fn on_authentication_failure(&self) -> Result<(), LoginsApiError> {
+ * println!("this did not work, please try again:");
+ * Ok(())
+ * }
+ * }
+ * let key_manager = NSSKeyManager::new(Arc::new(MyPrimaryPasswordAuthenticator {}));
+ * assert_eq!(key_manager.get_key().unwrap().len(), 63);
+ * ```
+ */
+export class NssKeyManagerInterface {
+ /**
+ * intoDynKeyManager
+ * @returns {KeyManager}
+ */
+ intoDynKeyManager() {
+ throw Error("intoDynKeyManager not implemented");
+ }
+
+}
+
+/**
+ * Use the `NSSKeyManager` to use NSS for key management.
+ *
+ * NSS stores keys in `key4.db` within the profile and wraps the key with a key derived from the
+ * primary password, if set. It defers to the provided `PrimaryPasswordAuthenticator`
+ * implementation to handle user authentication. Note that if no primary password is set, the
+ * wrapping key is deterministically derived from an empty string.
+ *
+ * Make sure to initialize NSS using `ensure_initialized_with_profile_dir` before creating a
+ * NSSKeyManager.
+ *
+ * # Examples
+ * ```no_run
+ * use async_trait::async_trait;
+ * use logins::encryption::KeyManager;
+ * use logins::{PrimaryPasswordAuthenticator, LoginsApiError, NSSKeyManager};
+ * use std::sync::Arc;
+ *
+ * struct MyPrimaryPasswordAuthenticator {}
+ *
+ * #[async_trait]
+ * impl PrimaryPasswordAuthenticator for MyPrimaryPasswordAuthenticator {
+ * async fn get_primary_password(&self) -> Result<String, LoginsApiError> {
+ * // Most likely, you would want to prompt for a password.
+ * // let password = prompt_string("primary password").unwrap_or_default();
+ * Ok("secret".to_string())
+ * }
+ *
+ * async fn on_authentication_success(&self) -> Result<(), LoginsApiError> {
+ * println!("success");
+ * Ok(())
+ * }
+ *
+ * async fn on_authentication_failure(&self) -> Result<(), LoginsApiError> {
+ * println!("this did not work, please try again:");
+ * Ok(())
+ * }
+ * }
+ * let key_manager = NSSKeyManager::new(Arc::new(MyPrimaryPasswordAuthenticator {}));
+ * assert_eq!(key_manager.get_key().unwrap().len(), 63);
+ * ```
+ */
+export class NssKeyManager extends NssKeyManagerInterface {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * Initialize new `NSSKeyManager` with a given `PrimaryPasswordAuthenticator`.
+ * There must be a previous initializiation of NSS before initializing
+ * `NSSKeyManager`, otherwise this panics.
+ * @param {PrimaryPasswordAuthenticator} primaryPasswordAuthenticator
+ * @returns {NssKeyManager}
+ */
+ static init(
+ primaryPasswordAuthenticator) {
+
+ FfiConverterTypePrimaryPasswordAuthenticator.checkType(primaryPasswordAuthenticator);
+ const result = UniFFIScaffolding.callSync(
+ 46, // uniffi_logins_fn_constructor_nsskeymanager_new
+ FfiConverterTypePrimaryPasswordAuthenticator.lower(primaryPasswordAuthenticator),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeNSSKeyManager.lift.bind(FfiConverterTypeNSSKeyManager),
+ null,
+ )
+ }
+
+ /**
+ * intoDynKeyManager
+ * @returns {KeyManager}
+ */
+ intoDynKeyManager() {
+
+ const result = UniFFIScaffolding.callSync(
+ 47, // uniffi_logins_fn_method_nsskeymanager_into_dyn_key_manager
+ FfiConverterTypeNSSKeyManager.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeKeyManager.lift.bind(FfiConverterTypeKeyManager),
+ null,
+ )
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeNSSKeyManager extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new NssKeyManager(opts);
+ }
+
+ static lower(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'NssKeyManager' instance");
+ }
+ return ptr;
+ }
+
+ static lowerReceiver(value) {
+ // This works exactly the same as lower for non-trait interfaces
+ return this.lower(value);
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(7));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(7, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+
+/**
+ * `PrimaryPasswordAuthenticator` is used in conjunction with `NSSKeyManager` to provide the
+ * primary password and the success or failure actions of the authentication process.
+ */
+export class PrimaryPasswordAuthenticator {
+ /**
+ * Get a primary password for authentication, otherwise return the
+ * AuthenticationCancelled error to cancel the authentication process.
+ * @returns {Promise<string>}}
+ */
+ async getPrimaryPassword() {
+ throw Error("getPrimaryPassword not implemented");
+ }
+ /**
+ * onAuthenticationSuccess
+ */
+ async onAuthenticationSuccess() {
+ throw Error("onAuthenticationSuccess not implemented");
+ }
+ /**
+ * onAuthenticationFailure
+ */
+ async onAuthenticationFailure() {
+ throw Error("onAuthenticationFailure not implemented");
+ }
+
+}
+
+/**
+ * `PrimaryPasswordAuthenticator` is used in conjunction with `NSSKeyManager` to provide the
+ * primary password and the success or failure actions of the authentication process.
+ */
+export class PrimaryPasswordAuthenticatorImpl extends PrimaryPasswordAuthenticator {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+
+ /**
+ * Get a primary password for authentication, otherwise return the
+ * AuthenticationCancelled error to cancel the authentication process.
+ * @returns {Promise<string>}}
+ */
+ async getPrimaryPassword() {
+
+ const result = await UniFFIScaffolding.callAsync(
+ 48, // uniffi_logins_fn_method_primarypasswordauthenticator_get_primary_password
+ FfiConverterTypePrimaryPasswordAuthenticator.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterString.lift.bind(FfiConverterString),
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * onAuthenticationSuccess
+ */
+ async onAuthenticationSuccess() {
+
+ const result = await UniFFIScaffolding.callAsync(
+ 49, // uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_success
+ FfiConverterTypePrimaryPasswordAuthenticator.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+ /**
+ * onAuthenticationFailure
+ */
+ async onAuthenticationFailure() {
+
+ const result = await UniFFIScaffolding.callAsync(
+ 50, // uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_failure
+ FfiConverterTypePrimaryPasswordAuthenticator.lowerReceiver(this),
+ )
+ return handleRustResult(
+ result,
+ (result) => undefined,
+ FfiConverterTypeLoginsApiError.lift.bind(FfiConverterTypeLoginsApiError),
+ )
+ }
+
+}
+
+// FfiConverter for a trait interface. This is a hybrid of the FFIConverter regular interfaces and
+// for callback interfaces.
+//
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypePrimaryPasswordAuthenticator extends FfiConverter {
+ // lift works like a regular interface
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new PrimaryPasswordAuthenticatorImpl(opts);
+ }
+
+ // lower treats value like a callback interface
+ static lower(value) {
+ if (!(value instanceof PrimaryPasswordAuthenticator)) {
+ throw new UniFFITypeError("expected 'PrimaryPasswordAuthenticator' subclass");
+ }
+ return uniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator.storeCallbackObj(value)
+ }
+
+ // lowerReceiver is used when calling methods on an interface we got from Rust,
+ // it treats value like a regular interface.
+ static lowerReceiver(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'PrimaryPasswordAuthenticatorImpl' instance");
+ }
+ return ptr;
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(8));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(8, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+const uniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator = new UniFFICallbackHandler(
+ "PrimaryPasswordAuthenticator",
+ 4,
+ [
+ new UniFFICallbackMethodHandler(
+ "getPrimaryPassword",
+ [
+ ],
+ FfiConverterString.lower.bind(FfiConverterString),
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ new UniFFICallbackMethodHandler(
+ "onAuthenticationSuccess",
+ [
+ ],
+ (result) => undefined,
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ new UniFFICallbackMethodHandler(
+ "onAuthenticationFailure",
+ [
+ ],
+ (result) => undefined,
+ (e) => {
+ if (e instanceof LoginsApiError) {
+ return FfiConverterTypeLoginsApiError.lower(e);
+ }
+ throw e;
+ }
+ ),
+ ]
+);
+
+// Allow the shutdown-related functionality to be tested in the unit tests
+UnitTestObjs.uniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator = uniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator;
+
+/**
+ * StaticKeyManagerInterface
+ */
+export class StaticKeyManagerInterface {
+
+}
+
+/**
+ * StaticKeyManager
+ */
+export class StaticKeyManager extends StaticKeyManagerInterface {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ super();
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * init
+ * @param {string} key
+ * @returns {StaticKeyManager}
+ */
+ static init(
+ key) {
+
+ FfiConverterString.checkType(key);
+ const result = UniFFIScaffolding.callSync(
+ 51, // uniffi_logins_fn_constructor_statickeymanager_new
+ FfiConverterString.lower(key),
+ )
+ return handleRustResult(
+ result,
+ FfiConverterTypeStaticKeyManager.lift.bind(FfiConverterTypeStaticKeyManager),
+ null,
+ )
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeStaticKeyManager extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new StaticKeyManager(opts);
+ }
+
+ static lower(value) {
+ const ptr = value[uniffiObjectPtr];
+ if (!(ptr instanceof UniFFIPointer)) {
+ throw new UniFFITypeError("Object is not a 'StaticKeyManager' instance");
+ }
+ return ptr;
+ }
+
+ static lowerReceiver(value) {
+ // This works exactly the same as lower for non-trait interfaces
+ return this.lower(value);
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointer(9));
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointer(9, this.lower(value));
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+
+
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustRelevancy.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustRelevancy.sys.mjs
@@ -56,7 +56,7 @@ export function score(
FfiConverterTypeInterestVector.checkType(interestVector);
FfiConverterSequenceTypeInterest.checkType(contentCategories);
const result = UniFFIScaffolding.callSync(
- 7, // uniffi_relevancy_fn_func_score
+ 52, // uniffi_relevancy_fn_func_score
FfiConverterTypeInterestVector.lower(interestVector),
FfiConverterSequenceTypeInterest.lower(contentCategories),
)
@@ -1414,7 +1414,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterString.checkType(dbPath);
FfiConverterTypeRemoteSettingsService.checkType(remoteSettings);
const result = UniFFIScaffolding.callSync(
- 8, // uniffi_relevancy_fn_constructor_relevancystore_new
+ 53, // uniffi_relevancy_fn_constructor_relevancystore_new
FfiConverterString.lower(dbPath),
FfiConverterTypeRemoteSettingsService.lower(remoteSettings),
)
@@ -1442,7 +1442,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterString.checkType(bandit);
FfiConverterSequenceString.checkType(arms);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 9, // uniffi_relevancy_fn_method_relevancystore_bandit_init
+ 54, // uniffi_relevancy_fn_method_relevancystore_bandit_init
FfiConverterTypeRelevancyStore.lowerReceiver(this),
FfiConverterString.lower(bandit),
FfiConverterSequenceString.lower(arms),
@@ -1473,7 +1473,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterString.checkType(bandit);
FfiConverterSequenceString.checkType(arms);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 10, // uniffi_relevancy_fn_method_relevancystore_bandit_select
+ 55, // uniffi_relevancy_fn_method_relevancystore_bandit_select
FfiConverterTypeRelevancyStore.lowerReceiver(this),
FfiConverterString.lower(bandit),
FfiConverterSequenceString.lower(arms),
@@ -1506,7 +1506,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterString.checkType(arm);
FfiConverterBoolean.checkType(selected);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 11, // uniffi_relevancy_fn_method_relevancystore_bandit_update
+ 56, // uniffi_relevancy_fn_method_relevancystore_bandit_update
FfiConverterTypeRelevancyStore.lowerReceiver(this),
FfiConverterString.lower(bandit),
FfiConverterString.lower(arm),
@@ -1527,7 +1527,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
close() {
const result = UniFFIScaffolding.callSync(
- 12, // uniffi_relevancy_fn_method_relevancystore_close
+ 57, // uniffi_relevancy_fn_method_relevancystore_close
FfiConverterTypeRelevancyStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1543,7 +1543,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
async ensureInterestDataPopulated() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 13, // uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated
+ 58, // uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated
FfiConverterTypeRelevancyStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1566,7 +1566,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterString.checkType(bandit);
FfiConverterString.checkType(arm);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 14, // uniffi_relevancy_fn_method_relevancystore_get_bandit_data
+ 59, // uniffi_relevancy_fn_method_relevancystore_get_bandit_data
FfiConverterTypeRelevancyStore.lowerReceiver(this),
FfiConverterString.lower(bandit),
FfiConverterString.lower(arm),
@@ -1598,7 +1598,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
FfiConverterSequenceString.checkType(topUrlsByFrecency);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 15, // uniffi_relevancy_fn_method_relevancystore_ingest
+ 60, // uniffi_relevancy_fn_method_relevancystore_ingest
FfiConverterTypeRelevancyStore.lowerReceiver(this),
FfiConverterSequenceString.lower(topUrlsByFrecency),
)
@@ -1615,7 +1615,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
interrupt() {
const result = UniFFIScaffolding.callSync(
- 16, // uniffi_relevancy_fn_method_relevancystore_interrupt
+ 61, // uniffi_relevancy_fn_method_relevancystore_interrupt
FfiConverterTypeRelevancyStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1635,7 +1635,7 @@ export class RelevancyStore extends RelevancyStoreInterface {
async userInterestVector() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 17, // uniffi_relevancy_fn_method_relevancystore_user_interest_vector
+ 62, // uniffi_relevancy_fn_method_relevancystore_user_interest_vector
FfiConverterTypeRelevancyStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1669,11 +1669,11 @@ export class FfiConverterTypeRelevancyStore extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(3));
+ return this.lift(dataStream.readPointer(10));
}
static write(dataStream, value) {
- dataStream.writePointer(3, this.lower(value));
+ dataStream.writePointer(10, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustRemoteSettings.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustRemoteSettings.sys.mjs
@@ -1623,7 +1623,7 @@ export class RemoteSettings extends RemoteSettingsInterface {
FfiConverterTypeRemoteSettingsConfig.checkType(remoteSettingsConfig);
const result = UniFFIScaffolding.callSync(
- 18, // uniffi_remote_settings_fn_constructor_remotesettings_new
+ 63, // uniffi_remote_settings_fn_constructor_remotesettings_new
FfiConverterTypeRemoteSettingsConfig.lower(remoteSettingsConfig),
)
return handleRustResult(
@@ -1645,7 +1645,7 @@ export class RemoteSettings extends RemoteSettingsInterface {
FfiConverterString.checkType(attachmentId);
FfiConverterString.checkType(path);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 19, // uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path
+ 64, // uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path
FfiConverterTypeRemoteSettings.lowerReceiver(this),
FfiConverterString.lower(attachmentId),
FfiConverterString.lower(path),
@@ -1664,7 +1664,7 @@ export class RemoteSettings extends RemoteSettingsInterface {
async getRecords() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 20, // uniffi_remote_settings_fn_method_remotesettings_get_records
+ 65, // uniffi_remote_settings_fn_method_remotesettings_get_records
FfiConverterTypeRemoteSettings.lowerReceiver(this),
)
return handleRustResult(
@@ -1685,7 +1685,7 @@ export class RemoteSettings extends RemoteSettingsInterface {
FfiConverterUInt64.checkType(timestamp);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 21, // uniffi_remote_settings_fn_method_remotesettings_get_records_since
+ 66, // uniffi_remote_settings_fn_method_remotesettings_get_records_since
FfiConverterTypeRemoteSettings.lowerReceiver(this),
FfiConverterUInt64.lower(timestamp),
)
@@ -1720,11 +1720,11 @@ export class FfiConverterTypeRemoteSettings extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(4));
+ return this.lift(dataStream.readPointer(11));
}
static write(dataStream, value) {
- dataStream.writePointer(4, this.lower(value));
+ dataStream.writePointer(11, this.lower(value));
}
static computeSize(value) {
@@ -1969,7 +1969,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
async collectionName() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 22, // uniffi_remote_settings_fn_method_remotesettingsclient_collection_name
+ 67, // uniffi_remote_settings_fn_method_remotesettingsclient_collection_name
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
)
return handleRustResult(
@@ -1997,7 +1997,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
FfiConverterTypeRemoteSettingsRecord.checkType(record);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 23, // uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment
+ 68, // uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
FfiConverterTypeRemoteSettingsRecord.lower(record),
)
@@ -2033,7 +2033,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
FfiConverterBoolean.checkType(syncIfEmpty);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 24, // uniffi_remote_settings_fn_method_remotesettingsclient_get_records
+ 69, // uniffi_remote_settings_fn_method_remotesettingsclient_get_records
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
FfiConverterBoolean.lower(syncIfEmpty),
)
@@ -2057,7 +2057,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
FfiConverterBoolean.checkType(syncIfEmpty);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 25, // uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map
+ 70, // uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
FfiConverterBoolean.lower(syncIfEmpty),
)
@@ -2074,7 +2074,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
async shutdown() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 26, // uniffi_remote_settings_fn_method_remotesettingsclient_shutdown
+ 71, // uniffi_remote_settings_fn_method_remotesettingsclient_shutdown
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
)
return handleRustResult(
@@ -2090,7 +2090,7 @@ export class RemoteSettingsClient extends RemoteSettingsClientInterface {
async sync() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 27, // uniffi_remote_settings_fn_method_remotesettingsclient_sync
+ 72, // uniffi_remote_settings_fn_method_remotesettingsclient_sync
FfiConverterTypeRemoteSettingsClient.lowerReceiver(this),
)
return handleRustResult(
@@ -2124,11 +2124,11 @@ export class FfiConverterTypeRemoteSettingsClient extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(5));
+ return this.lift(dataStream.readPointer(12));
}
static write(dataStream, value) {
- dataStream.writePointer(5, this.lower(value));
+ dataStream.writePointer(12, this.lower(value));
}
static computeSize(value) {
@@ -2264,7 +2264,7 @@ export class RemoteSettingsService extends RemoteSettingsServiceInterface {
FfiConverterString.checkType(storageDir);
FfiConverterTypeRemoteSettingsConfig2.checkType(config);
const result = UniFFIScaffolding.callSync(
- 28, // uniffi_remote_settings_fn_constructor_remotesettingsservice_new
+ 73, // uniffi_remote_settings_fn_constructor_remotesettingsservice_new
FfiConverterString.lower(storageDir),
FfiConverterTypeRemoteSettingsConfig2.lower(config),
)
@@ -2287,7 +2287,7 @@ export class RemoteSettingsService extends RemoteSettingsServiceInterface {
FfiConverterString.checkType(collectionName);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 29, // uniffi_remote_settings_fn_method_remotesettingsservice_make_client
+ 74, // uniffi_remote_settings_fn_method_remotesettingsservice_make_client
FfiConverterTypeRemoteSettingsService.lowerReceiver(this),
FfiConverterString.lower(collectionName),
)
@@ -2305,7 +2305,7 @@ export class RemoteSettingsService extends RemoteSettingsServiceInterface {
async sync() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 30, // uniffi_remote_settings_fn_method_remotesettingsservice_sync
+ 75, // uniffi_remote_settings_fn_method_remotesettingsservice_sync
FfiConverterTypeRemoteSettingsService.lowerReceiver(this),
)
return handleRustResult(
@@ -2330,7 +2330,7 @@ export class RemoteSettingsService extends RemoteSettingsServiceInterface {
FfiConverterTypeRemoteSettingsConfig2.checkType(config);
const result = UniFFIScaffolding.callSync(
- 31, // uniffi_remote_settings_fn_method_remotesettingsservice_update_config
+ 76, // uniffi_remote_settings_fn_method_remotesettingsservice_update_config
FfiConverterTypeRemoteSettingsService.lowerReceiver(this),
FfiConverterTypeRemoteSettingsConfig2.lower(config),
)
@@ -2365,11 +2365,11 @@ export class FfiConverterTypeRemoteSettingsService extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(6));
+ return this.lift(dataStream.readPointer(13));
}
static write(dataStream, value) {
- dataStream.writePointer(6, this.lower(value));
+ dataStream.writePointer(13, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs
@@ -2782,7 +2782,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
static init() {
const result = UniFFIScaffolding.callSync(
- 32, // uniffi_search_fn_constructor_searchengineselector_new
+ 77, // uniffi_search_fn_constructor_searchengineselector_new
)
return handleRustResult(
result,
@@ -2799,7 +2799,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
clearSearchConfig() {
const result = UniFFIScaffolding.callSync(
- 33, // uniffi_search_fn_method_searchengineselector_clear_search_config
+ 78, // uniffi_search_fn_method_searchengineselector_clear_search_config
FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
)
return handleRustResult(
@@ -2821,7 +2821,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
FfiConverterTypeSearchUserEnvironment.checkType(userEnvironment);
const result = UniFFIScaffolding.callSync(
- 34, // uniffi_search_fn_method_searchengineselector_filter_engine_configuration
+ 79, // uniffi_search_fn_method_searchengineselector_filter_engine_configuration
FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
FfiConverterTypeSearchUserEnvironment.lower(userEnvironment),
)
@@ -2841,7 +2841,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
FfiConverterString.checkType(overrides);
const result = UniFFIScaffolding.callSync(
- 35, // uniffi_search_fn_method_searchengineselector_set_config_overrides
+ 80, // uniffi_search_fn_method_searchengineselector_set_config_overrides
FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
FfiConverterString.lower(overrides),
)
@@ -2865,7 +2865,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
FfiConverterString.checkType(configuration);
const result = UniFFIScaffolding.callSync(
- 36, // uniffi_search_fn_method_searchengineselector_set_search_config
+ 81, // uniffi_search_fn_method_searchengineselector_set_search_config
FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
FfiConverterString.lower(configuration),
)
@@ -2896,7 +2896,7 @@ export class SearchEngineSelector extends SearchEngineSelectorInterface {
FfiConverterTypeRemoteSettingsService.checkType(service);
FfiConverterBoolean.checkType(applyEngineOverrides);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 37, // uniffi_search_fn_method_searchengineselector_use_remote_settings_server
+ 82, // uniffi_search_fn_method_searchengineselector_use_remote_settings_server
FfiConverterTypeSearchEngineSelector.lowerReceiver(this),
FfiConverterTypeRemoteSettingsService.lower(service),
FfiConverterBoolean.lower(applyEngineOverrides),
@@ -2932,11 +2932,11 @@ export class FfiConverterTypeSearchEngineSelector extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(7));
+ return this.lift(dataStream.readPointer(14));
}
static write(dataStream, value) {
- dataStream.writePointer(7, this.lower(value));
+ dataStream.writePointer(14, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustSuggest.sys.mjs
@@ -47,7 +47,7 @@ export function rawSuggestionUrlMatches(
FfiConverterString.checkType(rawUrl);
FfiConverterString.checkType(cookedUrl);
const result = UniFFIScaffolding.callSync(
- 38, // uniffi_suggest_fn_func_raw_suggestion_url_matches
+ 83, // uniffi_suggest_fn_func_raw_suggestion_url_matches
FfiConverterString.lower(rawUrl),
FfiConverterString.lower(cookedUrl),
)
@@ -4255,7 +4255,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterString.checkType(path);
FfiConverterTypeRemoteSettingsService.checkType(remoteSettingsService);
const result = UniFFIScaffolding.callSync(
- 39, // uniffi_suggest_fn_constructor_suggeststore_new
+ 84, // uniffi_suggest_fn_constructor_suggeststore_new
FfiConverterString.lower(path),
FfiConverterTypeRemoteSettingsService.lower(remoteSettingsService),
)
@@ -4273,7 +4273,7 @@ export class SuggestStore extends SuggestStoreInterface {
async anyDismissedSuggestions() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 40, // uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions
+ 85, // uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions
FfiConverterTypeSuggestStore.lowerReceiver(this),
)
return handleRustResult(
@@ -4289,7 +4289,7 @@ export class SuggestStore extends SuggestStoreInterface {
async clear() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 41, // uniffi_suggest_fn_method_suggeststore_clear
+ 86, // uniffi_suggest_fn_method_suggeststore_clear
FfiConverterTypeSuggestStore.lowerReceiver(this),
)
return handleRustResult(
@@ -4305,7 +4305,7 @@ export class SuggestStore extends SuggestStoreInterface {
async clearDismissedSuggestions() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 42, // uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions
+ 87, // uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions
FfiConverterTypeSuggestStore.lowerReceiver(this),
)
return handleRustResult(
@@ -4330,7 +4330,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterString.checkType(key);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 43, // uniffi_suggest_fn_method_suggeststore_dismiss_by_key
+ 88, // uniffi_suggest_fn_method_suggeststore_dismiss_by_key
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterString.lower(key),
)
@@ -4352,7 +4352,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestion.checkType(suggestion);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 44, // uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion
+ 89, // uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestion.lower(suggestion),
)
@@ -4377,7 +4377,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterString.checkType(suggestionUrl);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 45, // uniffi_suggest_fn_method_suggeststore_dismiss_suggestion
+ 90, // uniffi_suggest_fn_method_suggeststore_dismiss_suggestion
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterString.lower(suggestionUrl),
)
@@ -4400,7 +4400,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeGeoname.checkType(geoname);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 46, // uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates
+ 91, // uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeGeoname.lower(geoname),
)
@@ -4430,7 +4430,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterBoolean.checkType(matchNamePrefix);
FfiConverterOptionalSequenceTypeGeoname.checkType(filter);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 47, // uniffi_suggest_fn_method_suggeststore_fetch_geonames
+ 92, // uniffi_suggest_fn_method_suggeststore_fetch_geonames
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterString.lower(query),
FfiConverterBoolean.lower(matchNamePrefix),
@@ -4450,7 +4450,7 @@ export class SuggestStore extends SuggestStoreInterface {
async fetchGlobalConfig() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 48, // uniffi_suggest_fn_method_suggeststore_fetch_global_config
+ 93, // uniffi_suggest_fn_method_suggeststore_fetch_global_config
FfiConverterTypeSuggestStore.lowerReceiver(this),
)
return handleRustResult(
@@ -4470,7 +4470,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestionProvider.checkType(provider);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 49, // uniffi_suggest_fn_method_suggeststore_fetch_provider_config
+ 94, // uniffi_suggest_fn_method_suggeststore_fetch_provider_config
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestionProvider.lower(provider),
)
@@ -4491,7 +4491,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestIngestionConstraints.checkType(constraints);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 50, // uniffi_suggest_fn_method_suggeststore_ingest
+ 95, // uniffi_suggest_fn_method_suggeststore_ingest
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestIngestionConstraints.lower(constraints),
)
@@ -4515,7 +4515,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterOptionalTypeInterruptKind.checkType(kind);
const result = UniFFIScaffolding.callSync(
- 51, // uniffi_suggest_fn_method_suggeststore_interrupt
+ 96, // uniffi_suggest_fn_method_suggeststore_interrupt
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterOptionalTypeInterruptKind.lower(kind),
)
@@ -4541,7 +4541,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterString.checkType(key);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 52, // uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key
+ 97, // uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterString.lower(key),
)
@@ -4566,7 +4566,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestion.checkType(suggestion);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 53, // uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion
+ 98, // uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestion.lower(suggestion),
)
@@ -4587,7 +4587,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestionQuery.checkType(query);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 54, // uniffi_suggest_fn_method_suggeststore_query
+ 99, // uniffi_suggest_fn_method_suggeststore_query
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestionQuery.lower(query),
)
@@ -4608,7 +4608,7 @@ export class SuggestStore extends SuggestStoreInterface {
FfiConverterTypeSuggestionQuery.checkType(query);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 55, // uniffi_suggest_fn_method_suggeststore_query_with_metrics
+ 100, // uniffi_suggest_fn_method_suggeststore_query_with_metrics
FfiConverterTypeSuggestStore.lowerReceiver(this),
FfiConverterTypeSuggestionQuery.lower(query),
)
@@ -4643,11 +4643,11 @@ export class FfiConverterTypeSuggestStore extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(8));
+ return this.lift(dataStream.readPointer(15));
}
static write(dataStream, value) {
- dataStream.writePointer(8, this.lower(value));
+ dataStream.writePointer(15, this.lower(value));
}
static computeSize(value) {
@@ -4772,7 +4772,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
static init() {
const result = UniFFIScaffolding.callSync(
- 56, // uniffi_suggest_fn_constructor_suggeststorebuilder_new
+ 101, // uniffi_suggest_fn_constructor_suggeststorebuilder_new
)
return handleRustResult(
result,
@@ -4788,7 +4788,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
build() {
const result = UniFFIScaffolding.callSync(
- 57, // uniffi_suggest_fn_method_suggeststorebuilder_build
+ 102, // uniffi_suggest_fn_method_suggeststorebuilder_build
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
)
return handleRustResult(
@@ -4808,7 +4808,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterString.checkType(path);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 58, // uniffi_suggest_fn_method_suggeststorebuilder_cache_path
+ 103, // uniffi_suggest_fn_method_suggeststorebuilder_cache_path
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterString.lower(path),
)
@@ -4829,7 +4829,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterString.checkType(path);
const result = UniFFIScaffolding.callSync(
- 59, // uniffi_suggest_fn_method_suggeststorebuilder_data_path
+ 104, // uniffi_suggest_fn_method_suggeststorebuilder_data_path
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterString.lower(path),
)
@@ -4857,7 +4857,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterString.checkType(library);
FfiConverterOptionalString.checkType(entryPoint);
const result = UniFFIScaffolding.callSync(
- 60, // uniffi_suggest_fn_method_suggeststorebuilder_load_extension
+ 105, // uniffi_suggest_fn_method_suggeststorebuilder_load_extension
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterString.lower(library),
FfiConverterOptionalString.lower(entryPoint),
@@ -4879,7 +4879,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterString.checkType(bucketName);
const result = UniFFIScaffolding.callSync(
- 61, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
+ 106, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterString.lower(bucketName),
)
@@ -4900,7 +4900,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterTypeRemoteSettingsServer.checkType(server);
const result = UniFFIScaffolding.callSync(
- 62, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
+ 107, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterTypeRemoteSettingsServer.lower(server),
)
@@ -4921,7 +4921,7 @@ export class SuggestStoreBuilder extends SuggestStoreBuilderInterface {
FfiConverterTypeRemoteSettingsService.checkType(rsService);
const result = UniFFIScaffolding.callSync(
- 63, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service
+ 108, // uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service
FfiConverterTypeSuggestStoreBuilder.lowerReceiver(this),
FfiConverterTypeRemoteSettingsService.lower(rsService),
)
@@ -4956,11 +4956,11 @@ export class FfiConverterTypeSuggestStoreBuilder extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(9));
+ return this.lift(dataStream.readPointer(16));
}
static write(dataStream, value) {
- dataStream.writePointer(9, this.lower(value));
+ dataStream.writePointer(16, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTabs.sys.mjs
@@ -1053,7 +1053,7 @@ export class RemoteCommandStore extends RemoteCommandStoreInterface {
FfiConverterString.checkType(deviceId);
FfiConverterTypeRemoteCommand.checkType(command);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 64, // uniffi_tabs_fn_method_remotecommandstore_add_remote_command
+ 109, // uniffi_tabs_fn_method_remotecommandstore_add_remote_command
FfiConverterTypeRemoteCommandStore.lowerReceiver(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -1081,7 +1081,7 @@ export class RemoteCommandStore extends RemoteCommandStoreInterface {
FfiConverterTypeRemoteCommand.checkType(command);
FfiConverterTypeTimestamp.checkType(when);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 65, // uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at
+ 110, // uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at
FfiConverterTypeRemoteCommandStore.lowerReceiver(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -1101,7 +1101,7 @@ export class RemoteCommandStore extends RemoteCommandStoreInterface {
async getUnsentCommands() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 66, // uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands
+ 111, // uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands
FfiConverterTypeRemoteCommandStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1125,7 +1125,7 @@ export class RemoteCommandStore extends RemoteCommandStoreInterface {
FfiConverterString.checkType(deviceId);
FfiConverterTypeRemoteCommand.checkType(command);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 67, // uniffi_tabs_fn_method_remotecommandstore_remove_remote_command
+ 112, // uniffi_tabs_fn_method_remotecommandstore_remove_remote_command
FfiConverterTypeRemoteCommandStore.lowerReceiver(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -1147,7 +1147,7 @@ export class RemoteCommandStore extends RemoteCommandStoreInterface {
FfiConverterTypePendingCommand.checkType(command);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 68, // uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent
+ 113, // uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent
FfiConverterTypeRemoteCommandStore.lowerReceiver(this),
FfiConverterTypePendingCommand.lower(command),
)
@@ -1182,11 +1182,11 @@ export class FfiConverterTypeRemoteCommandStore extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(10));
+ return this.lift(dataStream.readPointer(17));
}
static write(dataStream, value) {
- dataStream.writePointer(10, this.lower(value));
+ dataStream.writePointer(17, this.lower(value));
}
static computeSize(value) {
@@ -1369,7 +1369,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async apply() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 69, // uniffi_tabs_fn_method_tabsbridgedengine_apply
+ 114, // uniffi_tabs_fn_method_tabsbridgedengine_apply
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1389,7 +1389,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
FfiConverterString.checkType(newSyncId);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 70, // uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id
+ 115, // uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
FfiConverterString.lower(newSyncId),
)
@@ -1407,7 +1407,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async lastSync() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 71, // uniffi_tabs_fn_method_tabsbridgedengine_last_sync
+ 116, // uniffi_tabs_fn_method_tabsbridgedengine_last_sync
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1426,7 +1426,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
FfiConverterString.checkType(clientData);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 72, // uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync
+ 117, // uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
FfiConverterString.lower(clientData),
)
@@ -1443,7 +1443,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async reset() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 73, // uniffi_tabs_fn_method_tabsbridgedengine_reset
+ 118, // uniffi_tabs_fn_method_tabsbridgedengine_reset
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1460,7 +1460,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async resetSyncId() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 74, // uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id
+ 119, // uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1479,7 +1479,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
FfiConverterInt64.checkType(lastSync);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 75, // uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync
+ 120, // uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
FfiConverterInt64.lower(lastSync),
)
@@ -1502,7 +1502,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
FfiConverterInt64.checkType(newTimestamp);
FfiConverterSequenceTypeTabsGuid.checkType(uploadedIds);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 76, // uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded
+ 121, // uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
FfiConverterInt64.lower(newTimestamp),
FfiConverterSequenceTypeTabsGuid.lower(uploadedIds),
@@ -1523,7 +1523,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
FfiConverterSequenceString.checkType(incomingEnvelopesAsJson);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 77, // uniffi_tabs_fn_method_tabsbridgedengine_store_incoming
+ 122, // uniffi_tabs_fn_method_tabsbridgedengine_store_incoming
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
FfiConverterSequenceString.lower(incomingEnvelopesAsJson),
)
@@ -1540,7 +1540,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async syncFinished() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 78, // uniffi_tabs_fn_method_tabsbridgedengine_sync_finished
+ 123, // uniffi_tabs_fn_method_tabsbridgedengine_sync_finished
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1557,7 +1557,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async syncId() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 79, // uniffi_tabs_fn_method_tabsbridgedengine_sync_id
+ 124, // uniffi_tabs_fn_method_tabsbridgedengine_sync_id
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1573,7 +1573,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async syncStarted() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 80, // uniffi_tabs_fn_method_tabsbridgedengine_sync_started
+ 125, // uniffi_tabs_fn_method_tabsbridgedengine_sync_started
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1589,7 +1589,7 @@ export class TabsBridgedEngine extends TabsBridgedEngineInterface {
async wipe() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 81, // uniffi_tabs_fn_method_tabsbridgedengine_wipe
+ 126, // uniffi_tabs_fn_method_tabsbridgedengine_wipe
FfiConverterTypeTabsBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1623,11 +1623,11 @@ export class FfiConverterTypeTabsBridgedEngine extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(11));
+ return this.lift(dataStream.readPointer(18));
}
static write(dataStream, value) {
- dataStream.writePointer(11, this.lower(value));
+ dataStream.writePointer(18, this.lower(value));
}
static computeSize(value) {
@@ -1754,7 +1754,7 @@ export class TabsStore extends TabsStoreInterface {
FfiConverterString.checkType(path);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 82, // uniffi_tabs_fn_constructor_tabsstore_new
+ 127, // uniffi_tabs_fn_constructor_tabsstore_new
FfiConverterString.lower(path),
)
return handleRustResult(
@@ -1771,7 +1771,7 @@ export class TabsStore extends TabsStoreInterface {
async bridgedEngine() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 83, // uniffi_tabs_fn_method_tabsstore_bridged_engine
+ 128, // uniffi_tabs_fn_method_tabsstore_bridged_engine
FfiConverterTypeTabsStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1787,7 +1787,7 @@ export class TabsStore extends TabsStoreInterface {
async closeConnection() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 84, // uniffi_tabs_fn_method_tabsstore_close_connection
+ 129, // uniffi_tabs_fn_method_tabsstore_close_connection
FfiConverterTypeTabsStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1804,7 +1804,7 @@ export class TabsStore extends TabsStoreInterface {
async getAll() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 85, // uniffi_tabs_fn_method_tabsstore_get_all
+ 130, // uniffi_tabs_fn_method_tabsstore_get_all
FfiConverterTypeTabsStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1821,7 +1821,7 @@ export class TabsStore extends TabsStoreInterface {
async newRemoteCommandStore() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 86, // uniffi_tabs_fn_method_tabsstore_new_remote_command_store
+ 131, // uniffi_tabs_fn_method_tabsstore_new_remote_command_store
FfiConverterTypeTabsStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1837,7 +1837,7 @@ export class TabsStore extends TabsStoreInterface {
async registerWithSyncManager() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 87, // uniffi_tabs_fn_method_tabsstore_register_with_sync_manager
+ 132, // uniffi_tabs_fn_method_tabsstore_register_with_sync_manager
FfiConverterTypeTabsStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1856,7 +1856,7 @@ export class TabsStore extends TabsStoreInterface {
FfiConverterSequenceTypeRemoteTabRecord.checkType(remoteTabs);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 88, // uniffi_tabs_fn_method_tabsstore_set_local_tabs
+ 133, // uniffi_tabs_fn_method_tabsstore_set_local_tabs
FfiConverterTypeTabsStore.lowerReceiver(this),
FfiConverterSequenceTypeRemoteTabRecord.lower(remoteTabs),
)
@@ -1891,11 +1891,11 @@ export class FfiConverterTypeTabsStore extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(12));
+ return this.lift(dataStream.readPointer(19));
}
static write(dataStream, value) {
- dataStream.writePointer(12, this.lower(value));
+ dataStream.writePointer(19, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTracing.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustTracing.sys.mjs
@@ -47,7 +47,7 @@ FfiConverterString.checkType(target);
FfiConverterTypeTracingLevel.checkType(level);
FfiConverterTypeEventSink.checkType(sink);
const result = UniFFIScaffolding.callSync(
- 89, // uniffi_tracing_support_fn_func_register_event_sink
+ 134, // uniffi_tracing_support_fn_func_register_event_sink
FfiConverterString.lower(target),
FfiConverterTypeTracingLevel.lower(level),
FfiConverterTypeEventSink.lower(sink),
@@ -71,7 +71,7 @@ export function registerMinLevelEventSink(
FfiConverterTypeTracingLevel.checkType(level);
FfiConverterTypeEventSink.checkType(sink);
const result = UniFFIScaffolding.callSync(
- 90, // uniffi_tracing_support_fn_func_register_min_level_event_sink
+ 135, // uniffi_tracing_support_fn_func_register_min_level_event_sink
FfiConverterTypeTracingLevel.lower(level),
FfiConverterTypeEventSink.lower(sink),
)
@@ -91,7 +91,7 @@ export function unregisterEventSink(
FfiConverterString.checkType(target);
const result = UniFFIScaffolding.callSync(
- 91, // uniffi_tracing_support_fn_func_unregister_event_sink
+ 136, // uniffi_tracing_support_fn_func_unregister_event_sink
FfiConverterString.lower(target),
)
return handleRustResult(
@@ -107,7 +107,7 @@ return handleRustResult(
export function unregisterMinLevelEventSink() {
const result = UniFFIScaffolding.callSync(
- 92, // uniffi_tracing_support_fn_func_unregister_min_level_event_sink
+ 137, // uniffi_tracing_support_fn_func_unregister_min_level_event_sink
)
return handleRustResult(
result,
@@ -444,7 +444,7 @@ export class FfiConverterTypeEventSink extends FfiConverter {
}
const uniffiCallbackHandlerTracingEventSink = new UniFFICallbackHandler(
"EventSink",
- 2,
+ 5,
[
new UniFFICallbackMethodHandler(
"onEvent",
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustViaduct.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustViaduct.sys.mjs
@@ -38,7 +38,7 @@ export var UnitTestObjs = {
export function allowAndroidEmulatorLoopback() {
const result = UniFFIScaffolding.callSync(
- 93, // uniffi_viaduct_fn_func_allow_android_emulator_loopback
+ 138, // uniffi_viaduct_fn_func_allow_android_emulator_loopback
)
return handleRustResult(
result,
@@ -56,7 +56,7 @@ export function initBackend(
FfiConverterTypeBackend.checkType(backend);
const result = UniFFIScaffolding.callSync(
- 94, // uniffi_viaduct_fn_func_init_backend
+ 139, // uniffi_viaduct_fn_func_init_backend
FfiConverterTypeBackend.lower(backend),
)
return handleRustResult(
@@ -1050,7 +1050,7 @@ export class BackendImpl extends Backend {
FfiConverterTypeRequest.checkType(request);
FfiConverterTypeClientSettings.checkType(settings);
const result = await UniFFIScaffolding.callAsync(
- 95, // uniffi_viaduct_fn_method_backend_send_request
+ 140, // uniffi_viaduct_fn_method_backend_send_request
FfiConverterTypeBackend.lowerReceiver(this),
FfiConverterTypeRequest.lower(request),
FfiConverterTypeClientSettings.lower(settings),
@@ -1095,11 +1095,11 @@ export class FfiConverterTypeBackend extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(13));
+ return this.lift(dataStream.readPointer(20));
}
static write(dataStream, value) {
- dataStream.writePointer(13, this.lower(value));
+ dataStream.writePointer(20, this.lower(value));
}
static computeSize(value) {
@@ -1109,7 +1109,7 @@ export class FfiConverterTypeBackend extends FfiConverter {
const uniffiCallbackHandlerViaductBackend = new UniFFICallbackHandler(
"Backend",
- 3,
+ 6,
[
new UniFFICallbackMethodHandler(
"sendRequest",
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/components/generated/RustWebextstorage.sys.mjs
@@ -877,7 +877,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async apply() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 96, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply
+ 141, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -897,7 +897,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
FfiConverterString.checkType(newSyncId);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 97, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id
+ 142, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
FfiConverterString.lower(newSyncId),
)
@@ -915,7 +915,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async lastSync() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 98, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync
+ 143, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -934,7 +934,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
FfiConverterString.checkType(clientData);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 99, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync
+ 144, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
FfiConverterString.lower(clientData),
)
@@ -951,7 +951,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async reset() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 100, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset
+ 145, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -968,7 +968,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async resetSyncId() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 101, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id
+ 146, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -987,7 +987,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
FfiConverterInt64.checkType(lastSync);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 102, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync
+ 147, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
FfiConverterInt64.lower(lastSync),
)
@@ -1010,7 +1010,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
FfiConverterInt64.checkType(serverModifiedMillis);
FfiConverterSequenceTypeGuid.checkType(guids);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 103, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded
+ 148, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
FfiConverterInt64.lower(serverModifiedMillis),
FfiConverterSequenceTypeGuid.lower(guids),
@@ -1031,7 +1031,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
FfiConverterSequenceString.checkType(incoming);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 104, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming
+ 149, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
FfiConverterSequenceString.lower(incoming),
)
@@ -1048,7 +1048,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async syncFinished() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 105, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished
+ 150, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1065,7 +1065,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async syncId() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 106, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id
+ 151, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1081,7 +1081,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async syncStarted() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 107, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started
+ 152, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1097,7 +1097,7 @@ export class WebExtStorageBridgedEngine extends WebExtStorageBridgedEngineInterf
async wipe() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 108, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe
+ 153, // uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe
FfiConverterTypeWebExtStorageBridgedEngine.lowerReceiver(this),
)
return handleRustResult(
@@ -1131,11 +1131,11 @@ export class FfiConverterTypeWebExtStorageBridgedEngine extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(14));
+ return this.lift(dataStream.readPointer(21));
}
static write(dataStream, value) {
- dataStream.writePointer(14, this.lower(value));
+ dataStream.writePointer(21, this.lower(value));
}
static computeSize(value) {
@@ -1305,7 +1305,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(path);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 109, // uniffi_webext_storage_fn_constructor_webextstoragestore_new
+ 154, // uniffi_webext_storage_fn_constructor_webextstoragestore_new
FfiConverterString.lower(path),
)
return handleRustResult(
@@ -1322,7 +1322,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
async bridgedEngine() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 110, // uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine
+ 155, // uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1342,7 +1342,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 111, // uniffi_webext_storage_fn_method_webextstoragestore_clear
+ 156, // uniffi_webext_storage_fn_method_webextstoragestore_clear
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
)
@@ -1359,7 +1359,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
async close() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 112, // uniffi_webext_storage_fn_method_webextstoragestore_close
+ 157, // uniffi_webext_storage_fn_method_webextstoragestore_close
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1382,7 +1382,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
FfiConverterTypeJsonValue.checkType(keys);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 113, // uniffi_webext_storage_fn_method_webextstoragestore_get
+ 158, // uniffi_webext_storage_fn_method_webextstoragestore_get
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -1407,7 +1407,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
FfiConverterTypeJsonValue.checkType(keys);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 114, // uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use
+ 159, // uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -1429,7 +1429,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 115, // uniffi_webext_storage_fn_method_webextstoragestore_get_keys
+ 160, // uniffi_webext_storage_fn_method_webextstoragestore_get_keys
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
)
@@ -1447,7 +1447,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
async getSyncedChanges() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 116, // uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes
+ 161, // uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
)
return handleRustResult(
@@ -1470,7 +1470,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
FfiConverterTypeJsonValue.checkType(keys);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 117, // uniffi_webext_storage_fn_method_webextstoragestore_remove
+ 162, // uniffi_webext_storage_fn_method_webextstoragestore_remove
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -1495,7 +1495,7 @@ export class WebExtStorageStore extends WebExtStorageStoreInterface {
FfiConverterString.checkType(extId);
FfiConverterTypeJsonValue.checkType(val);
const result = await UniFFIScaffolding.callAsyncWrapper(
- 118, // uniffi_webext_storage_fn_method_webextstoragestore_set
+ 163, // uniffi_webext_storage_fn_method_webextstoragestore_set
FfiConverterTypeWebExtStorageStore.lowerReceiver(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(val),
@@ -1531,11 +1531,11 @@ export class FfiConverterTypeWebExtStorageStore extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(15));
+ return this.lift(dataStream.readPointer(22));
}
static write(dataStream, value) {
- dataStream.writePointer(15, this.lower(value));
+ dataStream.writePointer(22, this.lower(value));
}
static computeSize(value) {
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTests.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTests.sys.mjs
@@ -46,7 +46,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterFloat32.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 119, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f32
+ 164, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f32
FfiConverterFloat32.lower(v),
)
return handleRustResult(
@@ -70,7 +70,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterFloat64.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 120, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f64
+ 165, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f64
FfiConverterFloat64.lower(v),
)
return handleRustResult(
@@ -94,7 +94,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt16.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 121, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i16
+ 166, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i16
FfiConverterInt16.lower(v),
)
return handleRustResult(
@@ -118,7 +118,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt32.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 122, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i32
+ 167, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i32
FfiConverterInt32.lower(v),
)
return handleRustResult(
@@ -142,7 +142,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt64.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 123, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i64
+ 168, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i64
FfiConverterInt64.lower(v),
)
return handleRustResult(
@@ -166,7 +166,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt8.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 124, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i8
+ 169, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i8
FfiConverterInt8.lower(v),
)
return handleRustResult(
@@ -190,7 +190,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterMapStringString.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 125, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_map
+ 170, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_map
FfiConverterMapStringString.lower(v),
)
return handleRustResult(
@@ -214,7 +214,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeAsyncInterface.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 126, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_obj
+ 171, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_obj
FfiConverterTypeAsyncInterface.lower(v),
)
return handleRustResult(
@@ -238,7 +238,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterString.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 127, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_string
+ 172, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_string
FfiConverterString.lower(v),
)
return handleRustResult(
@@ -262,7 +262,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt16.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 128, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u16
+ 173, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u16
FfiConverterUInt16.lower(v),
)
return handleRustResult(
@@ -286,7 +286,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 129, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u32
+ 174, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u32
FfiConverterUInt32.lower(v),
)
return handleRustResult(
@@ -310,7 +310,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt64.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 130, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u64
+ 175, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u64
FfiConverterUInt64.lower(v),
)
return handleRustResult(
@@ -334,7 +334,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt8.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 131, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u8
+ 176, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u8
FfiConverterUInt8.lower(v),
)
return handleRustResult(
@@ -358,7 +358,7 @@ if (v instanceof UniffiSkipJsTypeCheck) {
FfiConverterSequenceUInt32.checkType(v);
}
const result = await UniFFIScaffolding.callAsync(
- 132, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_vec
+ 177, // uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_vec
FfiConverterSequenceUInt32.lower(v),
)
return handleRustResult(
@@ -374,7 +374,7 @@ return handleRustResult(
export async function asyncThrowError() {
const result = await UniFFIScaffolding.callAsync(
- 133, // uniffi_uniffi_bindings_tests_fn_func_async_throw_error
+ 178, // uniffi_uniffi_bindings_tests_fn_func_async_throw_error
)
return handleRustResult(
result,
@@ -397,7 +397,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestInterface.checkType(int);
}
const result = UniFFIScaffolding.callSync(
- 134, // uniffi_uniffi_bindings_tests_fn_func_clone_interface
+ 179, // uniffi_uniffi_bindings_tests_fn_func_clone_interface
FfiConverterTypeTestInterface.lower(int),
)
return handleRustResult(
@@ -421,7 +421,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 135, // uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface
+ 180, // uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface
FfiConverterUInt32.lower(value),
)
return handleRustResult(
@@ -445,7 +445,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = UniFFIScaffolding.callSync(
- 136, // uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface
+ 181, // uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface
FfiConverterUInt32.lower(value),
)
return handleRustResult(
@@ -469,7 +469,7 @@ if (arg instanceof UniffiSkipJsTypeCheck) {
FfiConverterString.checkType(arg);
}
const result = UniFFIScaffolding.callSync(
- 137, // uniffi_uniffi_bindings_tests_fn_func_func_with_default
+ 182, // uniffi_uniffi_bindings_tests_fn_func_func_with_default
FfiConverterString.lower(arg),
)
return handleRustResult(
@@ -492,7 +492,7 @@ if (input instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(input);
}
const result = UniFFIScaffolding.callSync(
- 138, // uniffi_uniffi_bindings_tests_fn_func_func_with_error
+ 183, // uniffi_uniffi_bindings_tests_fn_func_func_with_error
FfiConverterUInt32.lower(input),
)
return handleRustResult(
@@ -515,7 +515,7 @@ if (input instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(input);
}
const result = UniFFIScaffolding.callSync(
- 139, // uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error
+ 184, // uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error
FfiConverterUInt32.lower(input),
)
return handleRustResult(
@@ -540,7 +540,7 @@ if (theArgument instanceof UniffiSkipJsTypeCheck) {
FfiConverterString.checkType(theArgument);
}
const result = UniFFIScaffolding.callSync(
- 140, // uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg
+ 185, // uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg
FfiConverterString.lower(theArgument),
)
return handleRustResult(
@@ -557,7 +557,7 @@ return handleRustResult(
export async function getCustomTypesDemo() {
const result = await UniFFIScaffolding.callAsyncWrapper(
- 141, // uniffi_uniffi_bindings_tests_fn_func_get_custom_types_demo
+ 186, // uniffi_uniffi_bindings_tests_fn_func_get_custom_types_demo
)
return handleRustResult(
result,
@@ -580,7 +580,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeAsyncTestTraitInterface.checkType(int);
}
const result = await UniFFIScaffolding.callAsync(
- 142, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_get_value
+ 187, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_get_value
FfiConverterTypeAsyncTestTraitInterface.lower(int),
)
return handleRustResult(
@@ -603,7 +603,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeAsyncTestTraitInterface.checkType(int);
}
const result = await UniFFIScaffolding.callAsync(
- 143, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_noop
+ 188, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_noop
FfiConverterTypeAsyncTestTraitInterface.lower(int),
)
return handleRustResult(
@@ -633,7 +633,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = await UniFFIScaffolding.callAsync(
- 144, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_set_value
+ 189, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_set_value
FfiConverterTypeAsyncTestTraitInterface.lower(int),
FfiConverterUInt32.lower(value),
)
@@ -665,7 +665,7 @@ if (numbers instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = await UniFFIScaffolding.callAsync(
- 145, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_throw_if_equal
+ 190, // uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_throw_if_equal
FfiConverterTypeAsyncTestTraitInterface.lower(int),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -690,7 +690,7 @@ if (cbi instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestAsyncCallbackInterface.checkType(cbi);
}
const result = await UniFFIScaffolding.callAsync(
- 146, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_get_value
+ 191, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_get_value
FfiConverterTypeTestAsyncCallbackInterface.lower(cbi),
)
return handleRustResult(
@@ -713,7 +713,7 @@ if (cbi instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestAsyncCallbackInterface.checkType(cbi);
}
const result = await UniFFIScaffolding.callAsync(
- 147, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_noop
+ 192, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_noop
FfiConverterTypeTestAsyncCallbackInterface.lower(cbi),
)
return handleRustResult(
@@ -743,7 +743,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = await UniFFIScaffolding.callAsync(
- 148, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_set_value
+ 193, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_set_value
FfiConverterTypeTestAsyncCallbackInterface.lower(cbi),
FfiConverterUInt32.lower(value),
)
@@ -775,7 +775,7 @@ if (numbers instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = await UniFFIScaffolding.callAsync(
- 149, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_throw_if_equal
+ 194, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_throw_if_equal
FfiConverterTypeTestAsyncCallbackInterface.lower(cbi),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -800,7 +800,7 @@ if (cbi instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestCallbackInterface.checkType(cbi);
}
const result = UniFFIScaffolding.callSync(
- 150, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value
+ 195, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value
FfiConverterTypeTestCallbackInterface.lower(cbi),
)
return handleRustResult(
@@ -823,7 +823,7 @@ if (cbi instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestCallbackInterface.checkType(cbi);
}
const result = UniFFIScaffolding.callSync(
- 151, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop
+ 196, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop
FfiConverterTypeTestCallbackInterface.lower(cbi),
)
return handleRustResult(
@@ -853,7 +853,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = UniFFIScaffolding.callSync(
- 152, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value
+ 197, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value
FfiConverterTypeTestCallbackInterface.lower(cbi),
FfiConverterUInt32.lower(value),
)
@@ -885,7 +885,7 @@ if (numbers instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = UniFFIScaffolding.callSync(
- 153, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal
+ 198, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal
FfiConverterTypeTestCallbackInterface.lower(cbi),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -910,7 +910,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestTraitInterface.checkType(int);
}
const result = UniFFIScaffolding.callSync(
- 154, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value
+ 199, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value
FfiConverterTypeTestTraitInterface.lower(int),
)
return handleRustResult(
@@ -933,7 +933,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestTraitInterface.checkType(int);
}
const result = UniFFIScaffolding.callSync(
- 155, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop
+ 200, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop
FfiConverterTypeTestTraitInterface.lower(int),
)
return handleRustResult(
@@ -963,7 +963,7 @@ if (value instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(value);
}
const result = UniFFIScaffolding.callSync(
- 156, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value
+ 201, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value
FfiConverterTypeTestTraitInterface.lower(int),
FfiConverterUInt32.lower(value),
)
@@ -995,7 +995,7 @@ if (numbers instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = UniFFIScaffolding.callSync(
- 157, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal
+ 202, // uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal
FfiConverterTypeTestTraitInterface.lower(int),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -1020,7 +1020,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterBoolean.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 158, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool
+ 203, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool
FfiConverterBoolean.lower(a),
)
return handleRustResult(
@@ -1044,7 +1044,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterOptionalSequenceMapStringUInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 159, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound
+ 204, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound
FfiConverterOptionalSequenceMapStringUInt32.lower(a),
)
return handleRustResult(
@@ -1068,7 +1068,7 @@ if (en instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeComplexEnum.checkType(en);
}
const result = UniFFIScaffolding.callSync(
- 160, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum
+ 205, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum
FfiConverterTypeComplexEnum.lower(en),
)
return handleRustResult(
@@ -1092,7 +1092,7 @@ if (rec instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeComplexRec.checkType(rec);
}
const result = UniFFIScaffolding.callSync(
- 161, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec
+ 206, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec
FfiConverterTypeComplexRec.lower(rec),
)
return handleRustResult(
@@ -1116,7 +1116,7 @@ if (handle instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeHandle.checkType(handle);
}
const result = UniFFIScaffolding.callSync(
- 162, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type
+ 207, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type
FfiConverterTypeHandle.lower(handle),
)
return handleRustResult(
@@ -1140,7 +1140,7 @@ if (en instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeEnumNoData.checkType(en);
}
const result = UniFFIScaffolding.callSync(
- 163, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data
+ 208, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data
FfiConverterTypeEnumNoData.lower(en),
)
return handleRustResult(
@@ -1164,7 +1164,7 @@ if (en instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeEnumWithData.checkType(en);
}
const result = UniFFIScaffolding.callSync(
- 164, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data
+ 209, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data
FfiConverterTypeEnumWithData.lower(en),
)
return handleRustResult(
@@ -1188,7 +1188,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterFloat32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 165, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32
+ 210, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32
FfiConverterFloat32.lower(a),
)
return handleRustResult(
@@ -1212,7 +1212,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterFloat64.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 166, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64
+ 211, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64
FfiConverterFloat64.lower(a),
)
return handleRustResult(
@@ -1236,7 +1236,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterMapStringUInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 167, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map
+ 212, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map
FfiConverterMapStringUInt32.lower(a),
)
return handleRustResult(
@@ -1260,7 +1260,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt16.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 168, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16
+ 213, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16
FfiConverterInt16.lower(a),
)
return handleRustResult(
@@ -1284,7 +1284,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 169, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32
+ 214, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32
FfiConverterInt32.lower(a),
)
return handleRustResult(
@@ -1308,7 +1308,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt64.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 170, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64
+ 215, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64
FfiConverterInt64.lower(a),
)
return handleRustResult(
@@ -1332,7 +1332,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterInt8.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 171, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8
+ 216, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8
FfiConverterInt8.lower(a),
)
return handleRustResult(
@@ -1356,7 +1356,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterOptionalUInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 172, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_option
+ 217, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_option
FfiConverterOptionalUInt32.lower(a),
)
return handleRustResult(
@@ -1380,7 +1380,7 @@ if (rec instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeSimpleRec.checkType(rec);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 173, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec
+ 218, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec
FfiConverterTypeSimpleRec.lower(rec),
)
return handleRustResult(
@@ -1404,7 +1404,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterString.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 174, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_string
+ 219, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_string
FfiConverterString.lower(a),
)
return handleRustResult(
@@ -1428,7 +1428,7 @@ if (time instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTimeIntervalMs.checkType(time);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 175, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms
+ 220, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms
FfiConverterTypeTimeIntervalMs.lower(time),
)
return handleRustResult(
@@ -1452,7 +1452,7 @@ if (time instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTimeIntervalSecDbl.checkType(time);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 176, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl
+ 221, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl
FfiConverterTypeTimeIntervalSecDbl.lower(time),
)
return handleRustResult(
@@ -1476,7 +1476,7 @@ if (time instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTimeIntervalSecFlt.checkType(time);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 177, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt
+ 222, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt
FfiConverterTypeTimeIntervalSecFlt.lower(time),
)
return handleRustResult(
@@ -1500,7 +1500,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt16.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 178, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16
+ 223, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16
FfiConverterUInt16.lower(a),
)
return handleRustResult(
@@ -1524,7 +1524,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 179, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32
+ 224, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32
FfiConverterUInt32.lower(a),
)
return handleRustResult(
@@ -1548,7 +1548,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt64.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 180, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64
+ 225, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64
FfiConverterUInt64.lower(a),
)
return handleRustResult(
@@ -1572,7 +1572,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterUInt8.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 181, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8
+ 226, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8
FfiConverterUInt8.lower(a),
)
return handleRustResult(
@@ -1596,7 +1596,7 @@ if (url instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeUrl.checkType(url);
}
const result = await UniFFIScaffolding.callAsyncWrapper(
- 182, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_url
+ 227, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_url
FfiConverterTypeUrl.lower(url),
)
return handleRustResult(
@@ -1620,7 +1620,7 @@ if (a instanceof UniffiSkipJsTypeCheck) {
FfiConverterSequenceUInt32.checkType(a);
}
const result = UniFFIScaffolding.callSync(
- 183, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec
+ 228, // uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec
FfiConverterSequenceUInt32.lower(a),
)
return handleRustResult(
@@ -1714,7 +1714,7 @@ if (negate instanceof UniffiSkipJsTypeCheck) {
FfiConverterBoolean.checkType(negate);
}
const result = UniFFIScaffolding.callSync(
- 184, // uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types
+ 229, // uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types
FfiConverterUInt8.lower(a),
FfiConverterInt8.lower(b),
FfiConverterUInt16.lower(c),
@@ -1748,7 +1748,7 @@ if (interfaces instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTwoTestInterfaces.checkType(interfaces);
}
const result = UniFFIScaffolding.callSync(
- 185, // uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces
+ 230, // uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces
FfiConverterTypeTwoTestInterfaces.lower(interfaces),
)
return handleRustResult(
@@ -1764,7 +1764,7 @@ return handleRustResult(
export function testFunc() {
const result = UniFFIScaffolding.callSync(
- 186, // uniffi_uniffi_bindings_tests_fn_func_test_func
+ 231, // uniffi_uniffi_bindings_tests_fn_func_test_func
)
return handleRustResult(
result,
@@ -2748,7 +2748,7 @@ export class TestInterface extends TestInterfaceInterface {
FfiConverterUInt32.checkType(value);
}
const result = UniFFIScaffolding.callSync(
- 187, // uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new
+ 232, // uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new
FfiConverterUInt32.lower(value),
)
return handleRustResult(
@@ -2765,7 +2765,7 @@ export class TestInterface extends TestInterfaceInterface {
getValue() {
const result = UniFFIScaffolding.callSync(
- 188, // uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value
+ 233, // uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value
FfiConverterTypeTestInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -2784,7 +2784,7 @@ export class TestInterface extends TestInterfaceInterface {
refCount() {
const result = UniFFIScaffolding.callSync(
- 189, // uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count
+ 234, // uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count
FfiConverterTypeTestInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -2818,11 +2818,11 @@ export class FfiConverterTypeTestInterface extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(16));
+ return this.lift(dataStream.readPointer(23));
}
static write(dataStream, value) {
- dataStream.writePointer(16, this.lower(value));
+ dataStream.writePointer(23, this.lower(value));
}
static computeSize(value) {
@@ -3563,7 +3563,7 @@ export class AsyncInterface extends AsyncInterfaceInterface {
FfiConverterString.checkType(name);
}
const result = UniFFIScaffolding.callSync(
- 190, // uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new
+ 235, // uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new
FfiConverterString.lower(name),
)
return handleRustResult(
@@ -3580,7 +3580,7 @@ export class AsyncInterface extends AsyncInterfaceInterface {
async name() {
const result = await UniFFIScaffolding.callAsync(
- 191, // uniffi_uniffi_bindings_tests_fn_method_asyncinterface_name
+ 236, // uniffi_uniffi_bindings_tests_fn_method_asyncinterface_name
FfiConverterTypeAsyncInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -3614,11 +3614,11 @@ export class FfiConverterTypeAsyncInterface extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(17));
+ return this.lift(dataStream.readPointer(24));
}
static write(dataStream, value) {
- dataStream.writePointer(17, this.lower(value));
+ dataStream.writePointer(24, this.lower(value));
}
static computeSize(value) {
@@ -3691,7 +3691,7 @@ export class AsyncTestTraitInterfaceImpl extends AsyncTestTraitInterface {
async noop() {
const result = await UniFFIScaffolding.callAsync(
- 192, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_noop
+ 237, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_noop
FfiConverterTypeAsyncTestTraitInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -3708,7 +3708,7 @@ export class AsyncTestTraitInterfaceImpl extends AsyncTestTraitInterface {
async getValue() {
const result = await UniFFIScaffolding.callAsync(
- 193, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_get_value
+ 238, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_get_value
FfiConverterTypeAsyncTestTraitInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -3731,7 +3731,7 @@ export class AsyncTestTraitInterfaceImpl extends AsyncTestTraitInterface {
FfiConverterUInt32.checkType(value);
}
const result = await UniFFIScaffolding.callAsync(
- 194, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_set_value
+ 239, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_set_value
FfiConverterTypeAsyncTestTraitInterface.lowerReceiver(this),
FfiConverterUInt32.lower(value),
)
@@ -3759,7 +3759,7 @@ export class AsyncTestTraitInterfaceImpl extends AsyncTestTraitInterface {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = await UniFFIScaffolding.callAsync(
- 195, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_throw_if_equal
+ 240, // uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_throw_if_equal
FfiConverterTypeAsyncTestTraitInterface.lowerReceiver(this),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -3803,11 +3803,11 @@ export class FfiConverterTypeAsyncTestTraitInterface extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(18));
+ return this.lift(dataStream.readPointer(25));
}
static write(dataStream, value) {
- dataStream.writePointer(18, this.lower(value));
+ dataStream.writePointer(25, this.lower(value));
}
static computeSize(value) {
@@ -3817,7 +3817,7 @@ export class FfiConverterTypeAsyncTestTraitInterface extends FfiConverter {
const uniffiCallbackHandlerUniffiBindingsTestsAsyncTestTraitInterface = new UniFFICallbackHandler(
"AsyncTestTraitInterface",
- 6,
+ 9,
[
new UniFFICallbackMethodHandler(
"noop",
@@ -3915,7 +3915,7 @@ export class ComplexMethods extends ComplexMethodsInterface {
static init() {
const result = UniFFIScaffolding.callSync(
- 196, // uniffi_uniffi_bindings_tests_fn_constructor_complexmethods_new
+ 241, // uniffi_uniffi_bindings_tests_fn_constructor_complexmethods_new
)
return handleRustResult(
result,
@@ -3938,7 +3938,7 @@ export class ComplexMethods extends ComplexMethodsInterface {
FfiConverterString.checkType(arg);
}
const result = UniFFIScaffolding.callSync(
- 197, // uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default
+ 242, // uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default
FfiConverterTypeComplexMethods.lowerReceiver(this),
FfiConverterString.lower(arg),
)
@@ -3963,7 +3963,7 @@ export class ComplexMethods extends ComplexMethodsInterface {
FfiConverterString.checkType(theArgument);
}
const result = UniFFIScaffolding.callSync(
- 198, // uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg
+ 243, // uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg
FfiConverterTypeComplexMethods.lowerReceiver(this),
FfiConverterString.lower(theArgument),
)
@@ -3998,11 +3998,11 @@ export class FfiConverterTypeComplexMethods extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(19));
+ return this.lift(dataStream.readPointer(26));
}
static write(dataStream, value) {
- dataStream.writePointer(19, this.lower(value));
+ dataStream.writePointer(26, this.lower(value));
}
static computeSize(value) {
@@ -4075,7 +4075,7 @@ export class TestTraitInterfaceImpl extends TestTraitInterface {
noop() {
const result = UniFFIScaffolding.callSync(
- 199, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop
+ 244, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop
FfiConverterTypeTestTraitInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -4092,7 +4092,7 @@ export class TestTraitInterfaceImpl extends TestTraitInterface {
getValue() {
const result = UniFFIScaffolding.callSync(
- 200, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value
+ 245, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value
FfiConverterTypeTestTraitInterface.lowerReceiver(this),
)
return handleRustResult(
@@ -4115,7 +4115,7 @@ export class TestTraitInterfaceImpl extends TestTraitInterface {
FfiConverterUInt32.checkType(value);
}
const result = UniFFIScaffolding.callSync(
- 201, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value
+ 246, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value
FfiConverterTypeTestTraitInterface.lowerReceiver(this),
FfiConverterUInt32.lower(value),
)
@@ -4143,7 +4143,7 @@ export class TestTraitInterfaceImpl extends TestTraitInterface {
FfiConverterTypeCallbackInterfaceNumbers.checkType(numbers);
}
const result = UniFFIScaffolding.callSync(
- 202, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal
+ 247, // uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal
FfiConverterTypeTestTraitInterface.lowerReceiver(this),
FfiConverterTypeCallbackInterfaceNumbers.lower(numbers),
)
@@ -4187,11 +4187,11 @@ export class FfiConverterTypeTestTraitInterface extends FfiConverter {
}
static read(dataStream) {
- return this.lift(dataStream.readPointer(20));
+ return this.lift(dataStream.readPointer(27));
}
static write(dataStream, value) {
- dataStream.writePointer(20, this.lower(value));
+ dataStream.writePointer(27, this.lower(value));
}
static computeSize(value) {
@@ -4201,7 +4201,7 @@ export class FfiConverterTypeTestTraitInterface extends FfiConverter {
const uniffiCallbackHandlerUniffiBindingsTestsTestTraitInterface = new UniFFICallbackHandler(
"TestTraitInterface",
- 7,
+ 10,
[
new UniFFICallbackMethodHandler(
"noop",
@@ -4314,7 +4314,7 @@ export class FfiConverterTypeTestAsyncCallbackInterface extends FfiConverter {
}
const uniffiCallbackHandlerUniffiBindingsTestsTestAsyncCallbackInterface = new UniFFICallbackHandler(
"TestAsyncCallbackInterface",
- 4,
+ 7,
[
new UniFFICallbackMethodHandler(
"noop",
@@ -4427,7 +4427,7 @@ export class FfiConverterTypeTestCallbackInterface extends FfiConverter {
}
const uniffiCallbackHandlerUniffiBindingsTestsTestCallbackInterface = new UniFFICallbackHandler(
"TestCallbackInterface",
- 5,
+ 8,
[
new UniFFICallbackMethodHandler(
"noop",
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTestsCollision.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTestsCollision.sys.mjs
@@ -46,7 +46,7 @@ if (cb instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestCallbackInterface.checkType(cb);
}
const result = UniFFIScaffolding.callSync(
- 203, // uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback
+ 248, // uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback
FfiConverterTypeTestCallbackInterface.lower(cb),
)
return handleRustResult(
@@ -101,7 +101,7 @@ export class FfiConverterTypeTestCallbackInterface extends FfiConverter {
}
const uniffiCallbackHandlerUniffiBindingsTestsCollisionTestCallbackInterface = new UniFFICallbackHandler(
"TestCallbackInterface",
- 8,
+ 11,
[
new UniFFICallbackMethodHandler(
"getValue",
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTestsExternalTypes.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/tests/generated/RustUniffiBindingsTestsExternalTypes.sys.mjs
@@ -46,7 +46,7 @@ if (custom instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeHandle.checkType(custom);
}
const result = UniFFIScaffolding.callSync(
- 204, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type
+ 249, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type
FfiConverterTypeHandle.lower(custom),
)
return handleRustResult(
@@ -70,7 +70,7 @@ if (en instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeEnumWithData.checkType(en);
}
const result = UniFFIScaffolding.callSync(
- 205, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum
+ 250, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum
FfiConverterTypeEnumWithData.lower(en),
)
return handleRustResult(
@@ -94,7 +94,7 @@ if (int instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeTestInterface.checkType(int);
}
const result = UniFFIScaffolding.callSync(
- 206, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface
+ 251, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface
FfiConverterTypeTestInterface.lower(int),
)
return handleRustResult(
@@ -118,7 +118,7 @@ if (rec instanceof UniffiSkipJsTypeCheck) {
FfiConverterTypeSimpleRec.checkType(rec);
}
const result = UniFFIScaffolding.callSync(
- 207, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record
+ 252, // uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record
FfiConverterTypeSimpleRec.lower(rec),
)
return handleRustResult(
diff --git a/toolkit/components/uniffi-js/GeneratedScaffolding.cpp b/toolkit/components/uniffi-js/GeneratedScaffolding.cpp
@@ -244,6 +244,260 @@ extern "C" {
uint32_t ffi_filter_adult_uniffi_contract_version();
uint16_t uniffi_filter_adult_checksum_constructor_filteradultcomponent_new();
uint16_t uniffi_filter_adult_checksum_method_filteradultcomponent_contains();
+ RustBuffer ffi_init_rust_components_rustbuffer_alloc(uint64_t, RustCallStatus*);
+ RustBuffer ffi_init_rust_components_rustbuffer_from_bytes(ForeignBytes, RustCallStatus*);
+ void ffi_init_rust_components_rustbuffer_free(RustBuffer, RustCallStatus*);
+ RustBuffer ffi_init_rust_components_rustbuffer_reserve(RustBuffer, uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_poll_u8(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_u8(uint64_t);
+ uint8_t ffi_init_rust_components_rust_future_complete_u8(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_u8(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_i8(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_i8(uint64_t);
+ int8_t ffi_init_rust_components_rust_future_complete_i8(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_i8(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_u16(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_u16(uint64_t);
+ uint16_t ffi_init_rust_components_rust_future_complete_u16(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_u16(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_i16(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_i16(uint64_t);
+ int16_t ffi_init_rust_components_rust_future_complete_i16(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_i16(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_u32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_u32(uint64_t);
+ uint32_t ffi_init_rust_components_rust_future_complete_u32(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_u32(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_i32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_i32(uint64_t);
+ int32_t ffi_init_rust_components_rust_future_complete_i32(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_i32(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_u64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_u64(uint64_t);
+ uint64_t ffi_init_rust_components_rust_future_complete_u64(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_u64(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_i64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_i64(uint64_t);
+ int64_t ffi_init_rust_components_rust_future_complete_i64(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_i64(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_f32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_f32(uint64_t);
+ float ffi_init_rust_components_rust_future_complete_f32(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_f32(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_f64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_f64(uint64_t);
+ double ffi_init_rust_components_rust_future_complete_f64(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_f64(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_pointer(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_pointer(uint64_t);
+ void* ffi_init_rust_components_rust_future_complete_pointer(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_pointer(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_rust_buffer(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_rust_buffer(uint64_t);
+ RustBuffer ffi_init_rust_components_rust_future_complete_rust_buffer(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_rust_buffer(uint64_t);
+ void ffi_init_rust_components_rust_future_poll_void(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_init_rust_components_rust_future_cancel_void(uint64_t);
+ void ffi_init_rust_components_rust_future_complete_void(uint64_t, RustCallStatus*);
+ void ffi_init_rust_components_rust_future_free_void(uint64_t);
+ void uniffi_init_rust_components_fn_func_initialize(RustBuffer, RustCallStatus*);
+ uint32_t ffi_init_rust_components_uniffi_contract_version();
+ uint16_t uniffi_init_rust_components_checksum_func_initialize();
+ RustBuffer ffi_logins_rustbuffer_alloc(uint64_t, RustCallStatus*);
+ RustBuffer ffi_logins_rustbuffer_from_bytes(ForeignBytes, RustCallStatus*);
+ void ffi_logins_rustbuffer_free(RustBuffer, RustCallStatus*);
+ RustBuffer ffi_logins_rustbuffer_reserve(RustBuffer, uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_poll_u8(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_u8(uint64_t);
+ uint8_t ffi_logins_rust_future_complete_u8(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_u8(uint64_t);
+ void ffi_logins_rust_future_poll_i8(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_i8(uint64_t);
+ int8_t ffi_logins_rust_future_complete_i8(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_i8(uint64_t);
+ void ffi_logins_rust_future_poll_u16(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_u16(uint64_t);
+ uint16_t ffi_logins_rust_future_complete_u16(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_u16(uint64_t);
+ void ffi_logins_rust_future_poll_i16(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_i16(uint64_t);
+ int16_t ffi_logins_rust_future_complete_i16(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_i16(uint64_t);
+ void ffi_logins_rust_future_poll_u32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_u32(uint64_t);
+ uint32_t ffi_logins_rust_future_complete_u32(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_u32(uint64_t);
+ void ffi_logins_rust_future_poll_i32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_i32(uint64_t);
+ int32_t ffi_logins_rust_future_complete_i32(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_i32(uint64_t);
+ void ffi_logins_rust_future_poll_u64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_u64(uint64_t);
+ uint64_t ffi_logins_rust_future_complete_u64(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_u64(uint64_t);
+ void ffi_logins_rust_future_poll_i64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_i64(uint64_t);
+ int64_t ffi_logins_rust_future_complete_i64(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_i64(uint64_t);
+ void ffi_logins_rust_future_poll_f32(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_f32(uint64_t);
+ float ffi_logins_rust_future_complete_f32(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_f32(uint64_t);
+ void ffi_logins_rust_future_poll_f64(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_f64(uint64_t);
+ double ffi_logins_rust_future_complete_f64(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_f64(uint64_t);
+ void ffi_logins_rust_future_poll_pointer(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_pointer(uint64_t);
+ void* ffi_logins_rust_future_complete_pointer(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_pointer(uint64_t);
+ void ffi_logins_rust_future_poll_rust_buffer(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_rust_buffer(uint64_t);
+ RustBuffer ffi_logins_rust_future_complete_rust_buffer(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_rust_buffer(uint64_t);
+ void ffi_logins_rust_future_poll_void(uint64_t, RustFutureContinuationCallback, uint64_t);
+ void ffi_logins_rust_future_cancel_void(uint64_t);
+ void ffi_logins_rust_future_complete_void(uint64_t, RustCallStatus*);
+ void ffi_logins_rust_future_free_void(uint64_t);
+ void* uniffi_logins_fn_clone_encryptordecryptor(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_encryptordecryptor(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_keymanager(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_keymanager(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_loginstore(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_loginstore(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_managedencryptordecryptor(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_managedencryptordecryptor(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_nsskeymanager(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_nsskeymanager(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_primarypasswordauthenticator(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_primarypasswordauthenticator(void*, RustCallStatus*);
+ void* uniffi_logins_fn_clone_statickeymanager(void*, RustCallStatus*);
+ void uniffi_logins_fn_free_statickeymanager(void*, RustCallStatus*);
+ typedef void (*CallbackInterfaceLoginsEncryptorDecryptorMethod0)(uint64_t, RustBuffer, RustBuffer*, RustCallStatus*);
+ typedef void (*CallbackInterfaceLoginsEncryptorDecryptorMethod1)(uint64_t, RustBuffer, RustBuffer*, RustCallStatus*);
+ typedef void (*CallbackInterfaceFreeLogins_EncryptorDecryptor)(uint64_t);
+ struct VTableCallbackInterfaceLoginsEncryptorDecryptor {
+ CallbackInterfaceLoginsEncryptorDecryptorMethod0 decrypt;
+ CallbackInterfaceLoginsEncryptorDecryptorMethod1 encrypt;
+ CallbackInterfaceFreeLogins_EncryptorDecryptor uniffi_free;
+ };
+ void uniffi_logins_fn_init_callback_vtable_encryptordecryptor(VTableCallbackInterfaceLoginsEncryptorDecryptor*);
+ typedef void (*CallbackInterfaceLoginsKeyManagerMethod0)(uint64_t, RustBuffer*, RustCallStatus*);
+ typedef void (*CallbackInterfaceFreeLogins_KeyManager)(uint64_t);
+ struct VTableCallbackInterfaceLoginsKeyManager {
+ CallbackInterfaceLoginsKeyManagerMethod0 get_key;
+ CallbackInterfaceFreeLogins_KeyManager uniffi_free;
+ };
+ void uniffi_logins_fn_init_callback_vtable_keymanager(VTableCallbackInterfaceLoginsKeyManager*);
+ struct ForeignFutureResultRustBuffer {
+ RustBuffer return_value;
+ RustCallStatus call_status;
+ };
+ typedef void (*ForeignFutureCompleterust_buffer)(uint64_t, ForeignFutureResultRustBuffer);
+ typedef void (*CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod0)(uint64_t, ForeignFutureCompleterust_buffer, uint64_t, ForeignFuture*);
+ struct ForeignFutureResultVoid {
+ RustCallStatus call_status;
+ };
+ typedef void (*ForeignFutureCompletevoid)(uint64_t, ForeignFutureResultVoid);
+ typedef void (*CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod1)(uint64_t, ForeignFutureCompletevoid, uint64_t, ForeignFuture*);
+ typedef void (*CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod2)(uint64_t, ForeignFutureCompletevoid, uint64_t, ForeignFuture*);
+ typedef void (*CallbackInterfaceFreeLogins_PrimaryPasswordAuthenticator)(uint64_t);
+ struct VTableCallbackInterfaceLoginsPrimaryPasswordAuthenticator {
+ CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod0 get_primary_password;
+ CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod1 on_authentication_success;
+ CallbackInterfaceLoginsPrimaryPasswordAuthenticatorMethod2 on_authentication_failure;
+ CallbackInterfaceFreeLogins_PrimaryPasswordAuthenticator uniffi_free;
+ };
+ void uniffi_logins_fn_init_callback_vtable_primarypasswordauthenticator(VTableCallbackInterfaceLoginsPrimaryPasswordAuthenticator*);
+ int8_t uniffi_logins_fn_func_check_canary(RustBuffer, RustBuffer, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_func_create_canary(RustBuffer, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_func_create_key(RustCallStatus*);
+ void* uniffi_logins_fn_func_create_login_store_with_nss_keymanager(RustBuffer, void*, RustCallStatus*);
+ void* uniffi_logins_fn_func_create_login_store_with_static_key_manager(RustBuffer, RustBuffer, RustCallStatus*);
+ void* uniffi_logins_fn_func_create_managed_encdec(void*, RustCallStatus*);
+ void* uniffi_logins_fn_func_create_static_key_manager(RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_encryptordecryptor_decrypt(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_encryptordecryptor_encrypt(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_keymanager_get_key(void*, RustCallStatus*);
+ void* uniffi_logins_fn_constructor_loginstore_new(RustBuffer, void*, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_add(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_add_many(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_add_many_with_meta(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_add_or_update(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_add_with_meta(void*, RustBuffer, RustCallStatus*);
+ int64_t uniffi_logins_fn_method_loginstore_count(void*, RustCallStatus*);
+ int64_t uniffi_logins_fn_method_loginstore_count_by_form_action_origin(void*, RustBuffer, RustCallStatus*);
+ int64_t uniffi_logins_fn_method_loginstore_count_by_origin(void*, RustBuffer, RustCallStatus*);
+ int8_t uniffi_logins_fn_method_loginstore_delete(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_delete_many(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_delete_undecryptable_records_for_remote_replacement(void*, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_find_login_to_update(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_get(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_get_by_base_domain(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_get_checkpoint(void*, RustCallStatus*);
+ int8_t uniffi_logins_fn_method_loginstore_has_logins_by_base_domain(void*, RustBuffer, RustCallStatus*);
+ int8_t uniffi_logins_fn_method_loginstore_is_empty(void*, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_list(void*, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_register_with_sync_manager(void*, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_reset(void*, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_run_maintenance(void*, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_set_checkpoint(void*, RustBuffer, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_shutdown(void*, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_touch(void*, RustBuffer, RustCallStatus*);
+ RustBuffer uniffi_logins_fn_method_loginstore_update(void*, RustBuffer, RustBuffer, RustCallStatus*);
+ void uniffi_logins_fn_method_loginstore_wipe_local(void*, RustCallStatus*);
+ void* uniffi_logins_fn_constructor_managedencryptordecryptor_new(void*, RustCallStatus*);
+ void* uniffi_logins_fn_constructor_nsskeymanager_new(void*, RustCallStatus*);
+ void* uniffi_logins_fn_method_nsskeymanager_into_dyn_key_manager(void*, RustCallStatus*);
+ uint64_t uniffi_logins_fn_method_primarypasswordauthenticator_get_primary_password(void*);
+ uint64_t uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_success(void*);
+ uint64_t uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_failure(void*);
+ void* uniffi_logins_fn_constructor_statickeymanager_new(RustBuffer, RustCallStatus*);
+ uint32_t ffi_logins_uniffi_contract_version();
+ uint16_t uniffi_logins_checksum_func_check_canary();
+ uint16_t uniffi_logins_checksum_func_create_canary();
+ uint16_t uniffi_logins_checksum_func_create_key();
+ uint16_t uniffi_logins_checksum_func_create_login_store_with_nss_keymanager();
+ uint16_t uniffi_logins_checksum_func_create_login_store_with_static_key_manager();
+ uint16_t uniffi_logins_checksum_func_create_managed_encdec();
+ uint16_t uniffi_logins_checksum_func_create_static_key_manager();
+ uint16_t uniffi_logins_checksum_method_encryptordecryptor_decrypt();
+ uint16_t uniffi_logins_checksum_method_encryptordecryptor_encrypt();
+ uint16_t uniffi_logins_checksum_method_keymanager_get_key();
+ uint16_t uniffi_logins_checksum_constructor_loginstore_new();
+ uint16_t uniffi_logins_checksum_method_loginstore_add();
+ uint16_t uniffi_logins_checksum_method_loginstore_add_many();
+ uint16_t uniffi_logins_checksum_method_loginstore_add_many_with_meta();
+ uint16_t uniffi_logins_checksum_method_loginstore_add_or_update();
+ uint16_t uniffi_logins_checksum_method_loginstore_add_with_meta();
+ uint16_t uniffi_logins_checksum_method_loginstore_count();
+ uint16_t uniffi_logins_checksum_method_loginstore_count_by_form_action_origin();
+ uint16_t uniffi_logins_checksum_method_loginstore_count_by_origin();
+ uint16_t uniffi_logins_checksum_method_loginstore_delete();
+ uint16_t uniffi_logins_checksum_method_loginstore_delete_many();
+ uint16_t uniffi_logins_checksum_method_loginstore_delete_undecryptable_records_for_remote_replacement();
+ uint16_t uniffi_logins_checksum_method_loginstore_find_login_to_update();
+ uint16_t uniffi_logins_checksum_method_loginstore_get();
+ uint16_t uniffi_logins_checksum_method_loginstore_get_by_base_domain();
+ uint16_t uniffi_logins_checksum_method_loginstore_get_checkpoint();
+ uint16_t uniffi_logins_checksum_method_loginstore_has_logins_by_base_domain();
+ uint16_t uniffi_logins_checksum_method_loginstore_is_empty();
+ uint16_t uniffi_logins_checksum_method_loginstore_list();
+ uint16_t uniffi_logins_checksum_method_loginstore_register_with_sync_manager();
+ uint16_t uniffi_logins_checksum_method_loginstore_reset();
+ uint16_t uniffi_logins_checksum_method_loginstore_run_maintenance();
+ uint16_t uniffi_logins_checksum_method_loginstore_set_checkpoint();
+ uint16_t uniffi_logins_checksum_method_loginstore_shutdown();
+ uint16_t uniffi_logins_checksum_method_loginstore_touch();
+ uint16_t uniffi_logins_checksum_method_loginstore_update();
+ uint16_t uniffi_logins_checksum_method_loginstore_wipe_local();
+ uint16_t uniffi_logins_checksum_constructor_managedencryptordecryptor_new();
+ uint16_t uniffi_logins_checksum_constructor_nsskeymanager_new();
+ uint16_t uniffi_logins_checksum_method_nsskeymanager_into_dyn_key_manager();
+ uint16_t uniffi_logins_checksum_method_primarypasswordauthenticator_get_primary_password();
+ uint16_t uniffi_logins_checksum_method_primarypasswordauthenticator_on_authentication_success();
+ uint16_t uniffi_logins_checksum_method_primarypasswordauthenticator_on_authentication_failure();
+ uint16_t uniffi_logins_checksum_constructor_statickeymanager_new();
RustBuffer ffi_relevancy_rustbuffer_alloc(uint64_t, RustCallStatus*);
RustBuffer ffi_relevancy_rustbuffer_from_bytes(ForeignBytes, RustCallStatus*);
void ffi_relevancy_rustbuffer_free(RustBuffer, RustCallStatus*);
@@ -900,11 +1154,6 @@ extern "C" {
void ffi_viaduct_rust_future_free_void(uint64_t);
void* uniffi_viaduct_fn_clone_backend(void*, RustCallStatus*);
void uniffi_viaduct_fn_free_backend(void*, RustCallStatus*);
- struct ForeignFutureResultRustBuffer {
- RustBuffer return_value;
- RustCallStatus call_status;
- };
- typedef void (*ForeignFutureCompleterust_buffer)(uint64_t, ForeignFutureResultRustBuffer);
typedef void (*CallbackInterfaceViaductBackendMethod0)(uint64_t, RustBuffer, RustBuffer, ForeignFutureCompleterust_buffer, uint64_t, ForeignFuture*);
typedef void (*CallbackInterfaceFreeViaduct_Backend)(uint64_t);
struct VTableCallbackInterfaceViaductBackend {
@@ -1094,10 +1343,6 @@ extern "C" {
void uniffi_uniffi_bindings_tests_fn_free_testinterface(void*, RustCallStatus*);
void* uniffi_uniffi_bindings_tests_fn_clone_testtraitinterface(void*, RustCallStatus*);
void uniffi_uniffi_bindings_tests_fn_free_testtraitinterface(void*, RustCallStatus*);
- struct ForeignFutureResultVoid {
- RustCallStatus call_status;
- };
- typedef void (*ForeignFutureCompletevoid)(uint64_t, ForeignFutureResultVoid);
typedef void (*CallbackInterfaceUniffiBindingsTestsAsyncTestTraitInterfaceMethod0)(uint64_t, ForeignFutureCompletevoid, uint64_t, ForeignFuture*);
struct ForeignFutureResultU32 {
uint32_t return_value;
@@ -1623,182 +1868,262 @@ class FfiValueObjectHandleFilterAdultFilterAdultComponent {
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kRelevancyRelevancyStorePointerType {
- "relevancy::RelevancyStore"_ns,
- uniffi_relevancy_fn_clone_relevancystore,
- uniffi_relevancy_fn_free_relevancystore,
+const static mozilla::uniffi::UniFFIPointerType kLoginsEncryptorDecryptorPointerType {
+ "logins::EncryptorDecryptor"_ns,
+ uniffi_logins_fn_clone_encryptordecryptor,
+ uniffi_logins_fn_free_encryptordecryptor,
};
-class FfiValueObjectHandleRelevancyRelevancyStore {
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_logins_encryptor_decryptor(uint64_t uniffiHandle);
+
+// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
+// interface version
+class FfiValueObjectHandleLoginsEncryptorDecryptor {
private:
+ // Did we lower a callback interface, rather than lift an object interface?
+ // This is weird, but it's a needed work until something like
+ // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
+ bool mLoweredCallbackInterface = false;
+ // The raw FFI value is a pointer.
+ // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
+ // handles are incremented by one at a time, so even on a 32-bit system this
+ // shouldn't overflow.
void* mValue = nullptr;
public:
- FfiValueObjectHandleRelevancyRelevancyStore() = default;
- explicit FfiValueObjectHandleRelevancyRelevancyStore(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsEncryptorDecryptor() = default;
+ explicit FfiValueObjectHandleLoginsEncryptorDecryptor(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleRelevancyRelevancyStore(const FfiValueObjectHandleRelevancyRelevancyStore&) = delete;
- FfiValueObjectHandleRelevancyRelevancyStore& operator=(const FfiValueObjectHandleRelevancyRelevancyStore&) = delete;
+ FfiValueObjectHandleLoginsEncryptorDecryptor(const FfiValueObjectHandleLoginsEncryptorDecryptor&) = delete;
+ FfiValueObjectHandleLoginsEncryptorDecryptor& operator=(const FfiValueObjectHandleLoginsEncryptorDecryptor&) = delete;
- FfiValueObjectHandleRelevancyRelevancyStore& operator=(FfiValueObjectHandleRelevancyRelevancyStore&& aOther) {
+ FfiValueObjectHandleLoginsEncryptorDecryptor& operator=(FfiValueObjectHandleLoginsEncryptorDecryptor&& aOther) {
FreeHandle();
mValue = aOther.mValue;
+ mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
aOther.mValue = nullptr;
+ aOther.mLoweredCallbackInterface = false;
return *this;
}
+ // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
+ return;
+ }
+ double floatValue = aValue.GetAsDouble();
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
+ return;
+ }
+ FreeHandle();
+ mValue = reinterpret_cast<void *>(intValue);
+ mLoweredCallbackInterface = true;
+ }
+
+ // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
if (!aValue.IsUniFFIPointer()) {
aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kRelevancyRelevancyStorePointerType)) {
+ if (!value.IsSamePtrType(&kLoginsEncryptorDecryptorPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
FreeHandle();
mValue = value.ClonePtr();
+ mLoweredCallbackInterface = false;
}
- // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
- // same as `Lower`
- void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
- Lower(aValue, aError);
- }
-
+ // Lift treats `aDest` as a regular interface
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kRelevancyRelevancyStorePointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsEncryptorDecryptorPointerType);
mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
void* IntoRust() {
auto temp = mValue;
mValue = nullptr;
+ mLoweredCallbackInterface = false;
return temp;
}
- static FfiValueObjectHandleRelevancyRelevancyStore FromRust(void* aValue) {
- return FfiValueObjectHandleRelevancyRelevancyStore(aValue);
+ static FfiValueObjectHandleLoginsEncryptorDecryptor FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsEncryptorDecryptor(aValue);
}
void FreeHandle() {
- if (mValue) {
+ // This behavior depends on if we lowered a callback interface handle or lifted an interface
+ // pointer.
+ if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
+ printf("FREEING CB %p\n", mValue);
+ callback_free_logins_encryptor_decryptor(reinterpret_cast<uintptr_t>(mValue));
+ mValue = reinterpret_cast<void *>(0);
+ } else if (!mLoweredCallbackInterface && mValue != nullptr) {
+ printf("FREEING interface %p\n", mValue);
RustCallStatus callStatus{};
- (uniffi_relevancy_fn_free_relevancystore)(mValue, &callStatus);
+ (uniffi_logins_fn_free_encryptordecryptor)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleRelevancyRelevancyStore() {
+ ~FfiValueObjectHandleLoginsEncryptorDecryptor() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsPointerType {
- "remote_settings::RemoteSettings"_ns,
- uniffi_remote_settings_fn_clone_remotesettings,
- uniffi_remote_settings_fn_free_remotesettings,
+const static mozilla::uniffi::UniFFIPointerType kLoginsKeyManagerPointerType {
+ "logins::KeyManager"_ns,
+ uniffi_logins_fn_clone_keymanager,
+ uniffi_logins_fn_free_keymanager,
};
-class FfiValueObjectHandleRemoteSettingsRemoteSettings {
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_logins_key_manager(uint64_t uniffiHandle);
+
+// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
+// interface version
+class FfiValueObjectHandleLoginsKeyManager {
private:
+ // Did we lower a callback interface, rather than lift an object interface?
+ // This is weird, but it's a needed work until something like
+ // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
+ bool mLoweredCallbackInterface = false;
+ // The raw FFI value is a pointer.
+ // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
+ // handles are incremented by one at a time, so even on a 32-bit system this
+ // shouldn't overflow.
void* mValue = nullptr;
public:
- FfiValueObjectHandleRemoteSettingsRemoteSettings() = default;
- explicit FfiValueObjectHandleRemoteSettingsRemoteSettings(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsKeyManager() = default;
+ explicit FfiValueObjectHandleLoginsKeyManager(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleRemoteSettingsRemoteSettings(const FfiValueObjectHandleRemoteSettingsRemoteSettings&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettings& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettings&) = delete;
+ FfiValueObjectHandleLoginsKeyManager(const FfiValueObjectHandleLoginsKeyManager&) = delete;
+ FfiValueObjectHandleLoginsKeyManager& operator=(const FfiValueObjectHandleLoginsKeyManager&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettings& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettings&& aOther) {
+ FfiValueObjectHandleLoginsKeyManager& operator=(FfiValueObjectHandleLoginsKeyManager&& aOther) {
FreeHandle();
mValue = aOther.mValue;
+ mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
aOther.mValue = nullptr;
+ aOther.mLoweredCallbackInterface = false;
return *this;
}
+ // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
+ return;
+ }
+ double floatValue = aValue.GetAsDouble();
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
+ return;
+ }
+ FreeHandle();
+ mValue = reinterpret_cast<void *>(intValue);
+ mLoweredCallbackInterface = true;
+ }
+
+ // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
if (!aValue.IsUniFFIPointer()) {
aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsPointerType)) {
+ if (!value.IsSamePtrType(&kLoginsKeyManagerPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
FreeHandle();
mValue = value.ClonePtr();
+ mLoweredCallbackInterface = false;
}
- // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
- // same as `Lower`
- void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
- Lower(aValue, aError);
- }
-
+ // Lift treats `aDest` as a regular interface
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsPointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsKeyManagerPointerType);
mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
void* IntoRust() {
auto temp = mValue;
mValue = nullptr;
+ mLoweredCallbackInterface = false;
return temp;
}
- static FfiValueObjectHandleRemoteSettingsRemoteSettings FromRust(void* aValue) {
- return FfiValueObjectHandleRemoteSettingsRemoteSettings(aValue);
+ static FfiValueObjectHandleLoginsKeyManager FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsKeyManager(aValue);
}
void FreeHandle() {
- if (mValue) {
+ // This behavior depends on if we lowered a callback interface handle or lifted an interface
+ // pointer.
+ if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
+ printf("FREEING CB %p\n", mValue);
+ callback_free_logins_key_manager(reinterpret_cast<uintptr_t>(mValue));
+ mValue = reinterpret_cast<void *>(0);
+ } else if (!mLoweredCallbackInterface && mValue != nullptr) {
+ printf("FREEING interface %p\n", mValue);
RustCallStatus callStatus{};
- (uniffi_remote_settings_fn_free_remotesettings)(mValue, &callStatus);
+ (uniffi_logins_fn_free_keymanager)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleRemoteSettingsRemoteSettings() {
+ ~FfiValueObjectHandleLoginsKeyManager() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsClientPointerType {
- "remote_settings::RemoteSettingsClient"_ns,
- uniffi_remote_settings_fn_clone_remotesettingsclient,
- uniffi_remote_settings_fn_free_remotesettingsclient,
+const static mozilla::uniffi::UniFFIPointerType kLoginsLoginStorePointerType {
+ "logins::LoginStore"_ns,
+ uniffi_logins_fn_clone_loginstore,
+ uniffi_logins_fn_free_loginstore,
};
-class FfiValueObjectHandleRemoteSettingsRemoteSettingsClient {
+class FfiValueObjectHandleLoginsLoginStore {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient() = default;
- explicit FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsLoginStore() = default;
+ explicit FfiValueObjectHandleLoginsLoginStore(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(const FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&) = delete;
+ FfiValueObjectHandleLoginsLoginStore(const FfiValueObjectHandleLoginsLoginStore&) = delete;
+ FfiValueObjectHandleLoginsLoginStore& operator=(const FfiValueObjectHandleLoginsLoginStore&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&& aOther) {
+ FfiValueObjectHandleLoginsLoginStore& operator=(FfiValueObjectHandleLoginsLoginStore&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -1812,7 +2137,7 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsClient {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsClientPointerType)) {
+ if (!value.IsSamePtrType(&kLoginsLoginStorePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -1830,7 +2155,7 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsClient {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsClientPointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsLoginStorePointerType);
mValue = nullptr;
}
@@ -1840,44 +2165,44 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsClient {
return temp;
}
- static FfiValueObjectHandleRemoteSettingsRemoteSettingsClient FromRust(void* aValue) {
- return FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(aValue);
+ static FfiValueObjectHandleLoginsLoginStore FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsLoginStore(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_remote_settings_fn_free_remotesettingsclient)(mValue, &callStatus);
+ (uniffi_logins_fn_free_loginstore)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleRemoteSettingsRemoteSettingsClient() {
+ ~FfiValueObjectHandleLoginsLoginStore() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsServicePointerType {
- "remote_settings::RemoteSettingsService"_ns,
- uniffi_remote_settings_fn_clone_remotesettingsservice,
- uniffi_remote_settings_fn_free_remotesettingsservice,
+const static mozilla::uniffi::UniFFIPointerType kLoginsManagedEncryptorDecryptorPointerType {
+ "logins::ManagedEncryptorDecryptor"_ns,
+ uniffi_logins_fn_clone_managedencryptordecryptor,
+ uniffi_logins_fn_free_managedencryptordecryptor,
};
-class FfiValueObjectHandleRemoteSettingsRemoteSettingsService {
+class FfiValueObjectHandleLoginsManagedEncryptorDecryptor {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService() = default;
- explicit FfiValueObjectHandleRemoteSettingsRemoteSettingsService(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsManagedEncryptorDecryptor() = default;
+ explicit FfiValueObjectHandleLoginsManagedEncryptorDecryptor(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService(const FfiValueObjectHandleRemoteSettingsRemoteSettingsService&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettingsService&) = delete;
+ FfiValueObjectHandleLoginsManagedEncryptorDecryptor(const FfiValueObjectHandleLoginsManagedEncryptorDecryptor&) = delete;
+ FfiValueObjectHandleLoginsManagedEncryptorDecryptor& operator=(const FfiValueObjectHandleLoginsManagedEncryptorDecryptor&) = delete;
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettingsService&& aOther) {
+ FfiValueObjectHandleLoginsManagedEncryptorDecryptor& operator=(FfiValueObjectHandleLoginsManagedEncryptorDecryptor&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -1891,7 +2216,7 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsService {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsServicePointerType)) {
+ if (!value.IsSamePtrType(&kLoginsManagedEncryptorDecryptorPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -1909,7 +2234,7 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsService {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsServicePointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsManagedEncryptorDecryptorPointerType);
mValue = nullptr;
}
@@ -1919,44 +2244,44 @@ class FfiValueObjectHandleRemoteSettingsRemoteSettingsService {
return temp;
}
- static FfiValueObjectHandleRemoteSettingsRemoteSettingsService FromRust(void* aValue) {
- return FfiValueObjectHandleRemoteSettingsRemoteSettingsService(aValue);
+ static FfiValueObjectHandleLoginsManagedEncryptorDecryptor FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsManagedEncryptorDecryptor(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_remote_settings_fn_free_remotesettingsservice)(mValue, &callStatus);
+ (uniffi_logins_fn_free_managedencryptordecryptor)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleRemoteSettingsRemoteSettingsService() {
+ ~FfiValueObjectHandleLoginsManagedEncryptorDecryptor() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kSearchSearchEngineSelectorPointerType {
- "search::SearchEngineSelector"_ns,
- uniffi_search_fn_clone_searchengineselector,
- uniffi_search_fn_free_searchengineselector,
+const static mozilla::uniffi::UniFFIPointerType kLoginsNssKeyManagerPointerType {
+ "logins::NSSKeyManager"_ns,
+ uniffi_logins_fn_clone_nsskeymanager,
+ uniffi_logins_fn_free_nsskeymanager,
};
-class FfiValueObjectHandleSearchSearchEngineSelector {
+class FfiValueObjectHandleLoginsNssKeyManager {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleSearchSearchEngineSelector() = default;
- explicit FfiValueObjectHandleSearchSearchEngineSelector(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsNssKeyManager() = default;
+ explicit FfiValueObjectHandleLoginsNssKeyManager(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleSearchSearchEngineSelector(const FfiValueObjectHandleSearchSearchEngineSelector&) = delete;
- FfiValueObjectHandleSearchSearchEngineSelector& operator=(const FfiValueObjectHandleSearchSearchEngineSelector&) = delete;
+ FfiValueObjectHandleLoginsNssKeyManager(const FfiValueObjectHandleLoginsNssKeyManager&) = delete;
+ FfiValueObjectHandleLoginsNssKeyManager& operator=(const FfiValueObjectHandleLoginsNssKeyManager&) = delete;
- FfiValueObjectHandleSearchSearchEngineSelector& operator=(FfiValueObjectHandleSearchSearchEngineSelector&& aOther) {
+ FfiValueObjectHandleLoginsNssKeyManager& operator=(FfiValueObjectHandleLoginsNssKeyManager&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -1970,7 +2295,7 @@ class FfiValueObjectHandleSearchSearchEngineSelector {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kSearchSearchEngineSelectorPointerType)) {
+ if (!value.IsSamePtrType(&kLoginsNssKeyManagerPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -1988,7 +2313,7 @@ class FfiValueObjectHandleSearchSearchEngineSelector {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kSearchSearchEngineSelectorPointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsNssKeyManagerPointerType);
mValue = nullptr;
}
@@ -1998,123 +2323,163 @@ class FfiValueObjectHandleSearchSearchEngineSelector {
return temp;
}
- static FfiValueObjectHandleSearchSearchEngineSelector FromRust(void* aValue) {
- return FfiValueObjectHandleSearchSearchEngineSelector(aValue);
+ static FfiValueObjectHandleLoginsNssKeyManager FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsNssKeyManager(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_search_fn_free_searchengineselector)(mValue, &callStatus);
+ (uniffi_logins_fn_free_nsskeymanager)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleSearchSearchEngineSelector() {
+ ~FfiValueObjectHandleLoginsNssKeyManager() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kSuggestSuggestStorePointerType {
- "suggest::SuggestStore"_ns,
- uniffi_suggest_fn_clone_suggeststore,
- uniffi_suggest_fn_free_suggeststore,
+const static mozilla::uniffi::UniFFIPointerType kLoginsPrimaryPasswordAuthenticatorPointerType {
+ "logins::PrimaryPasswordAuthenticator"_ns,
+ uniffi_logins_fn_clone_primarypasswordauthenticator,
+ uniffi_logins_fn_free_primarypasswordauthenticator,
};
-class FfiValueObjectHandleSuggestSuggestStore {
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_logins_primary_password_authenticator(uint64_t uniffiHandle);
+
+// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
+// interface version
+class FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator {
private:
+ // Did we lower a callback interface, rather than lift an object interface?
+ // This is weird, but it's a needed work until something like
+ // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
+ bool mLoweredCallbackInterface = false;
+ // The raw FFI value is a pointer.
+ // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
+ // handles are incremented by one at a time, so even on a 32-bit system this
+ // shouldn't overflow.
void* mValue = nullptr;
public:
- FfiValueObjectHandleSuggestSuggestStore() = default;
- explicit FfiValueObjectHandleSuggestSuggestStore(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator() = default;
+ explicit FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleSuggestSuggestStore(const FfiValueObjectHandleSuggestSuggestStore&) = delete;
- FfiValueObjectHandleSuggestSuggestStore& operator=(const FfiValueObjectHandleSuggestSuggestStore&) = delete;
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator(const FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator&) = delete;
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator& operator=(const FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator&) = delete;
- FfiValueObjectHandleSuggestSuggestStore& operator=(FfiValueObjectHandleSuggestSuggestStore&& aOther) {
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator& operator=(FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator&& aOther) {
FreeHandle();
mValue = aOther.mValue;
+ mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
aOther.mValue = nullptr;
+ aOther.mLoweredCallbackInterface = false;
return *this;
}
+ // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
+ return;
+ }
+ double floatValue = aValue.GetAsDouble();
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
+ return;
+ }
+ FreeHandle();
+ mValue = reinterpret_cast<void *>(intValue);
+ mLoweredCallbackInterface = true;
+ }
+
+ // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
if (!aValue.IsUniFFIPointer()) {
aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kSuggestSuggestStorePointerType)) {
+ if (!value.IsSamePtrType(&kLoginsPrimaryPasswordAuthenticatorPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
FreeHandle();
mValue = value.ClonePtr();
+ mLoweredCallbackInterface = false;
}
- // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
- // same as `Lower`
- void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
- Lower(aValue, aError);
- }
-
+ // Lift treats `aDest` as a regular interface
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kSuggestSuggestStorePointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsPrimaryPasswordAuthenticatorPointerType);
mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
void* IntoRust() {
auto temp = mValue;
mValue = nullptr;
+ mLoweredCallbackInterface = false;
return temp;
}
- static FfiValueObjectHandleSuggestSuggestStore FromRust(void* aValue) {
- return FfiValueObjectHandleSuggestSuggestStore(aValue);
+ static FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator(aValue);
}
void FreeHandle() {
- if (mValue) {
+ // This behavior depends on if we lowered a callback interface handle or lifted an interface
+ // pointer.
+ if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
+ printf("FREEING CB %p\n", mValue);
+ callback_free_logins_primary_password_authenticator(reinterpret_cast<uintptr_t>(mValue));
+ mValue = reinterpret_cast<void *>(0);
+ } else if (!mLoweredCallbackInterface && mValue != nullptr) {
+ printf("FREEING interface %p\n", mValue);
RustCallStatus callStatus{};
- (uniffi_suggest_fn_free_suggeststore)(mValue, &callStatus);
+ (uniffi_logins_fn_free_primarypasswordauthenticator)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleSuggestSuggestStore() {
+ ~FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kSuggestSuggestStoreBuilderPointerType {
- "suggest::SuggestStoreBuilder"_ns,
- uniffi_suggest_fn_clone_suggeststorebuilder,
- uniffi_suggest_fn_free_suggeststorebuilder,
+const static mozilla::uniffi::UniFFIPointerType kLoginsStaticKeyManagerPointerType {
+ "logins::StaticKeyManager"_ns,
+ uniffi_logins_fn_clone_statickeymanager,
+ uniffi_logins_fn_free_statickeymanager,
};
-class FfiValueObjectHandleSuggestSuggestStoreBuilder {
+class FfiValueObjectHandleLoginsStaticKeyManager {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleSuggestSuggestStoreBuilder() = default;
- explicit FfiValueObjectHandleSuggestSuggestStoreBuilder(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleLoginsStaticKeyManager() = default;
+ explicit FfiValueObjectHandleLoginsStaticKeyManager(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleSuggestSuggestStoreBuilder(const FfiValueObjectHandleSuggestSuggestStoreBuilder&) = delete;
- FfiValueObjectHandleSuggestSuggestStoreBuilder& operator=(const FfiValueObjectHandleSuggestSuggestStoreBuilder&) = delete;
+ FfiValueObjectHandleLoginsStaticKeyManager(const FfiValueObjectHandleLoginsStaticKeyManager&) = delete;
+ FfiValueObjectHandleLoginsStaticKeyManager& operator=(const FfiValueObjectHandleLoginsStaticKeyManager&) = delete;
- FfiValueObjectHandleSuggestSuggestStoreBuilder& operator=(FfiValueObjectHandleSuggestSuggestStoreBuilder&& aOther) {
+ FfiValueObjectHandleLoginsStaticKeyManager& operator=(FfiValueObjectHandleLoginsStaticKeyManager&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2128,7 +2493,7 @@ class FfiValueObjectHandleSuggestSuggestStoreBuilder {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kSuggestSuggestStoreBuilderPointerType)) {
+ if (!value.IsSamePtrType(&kLoginsStaticKeyManagerPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2146,7 +2511,7 @@ class FfiValueObjectHandleSuggestSuggestStoreBuilder {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kSuggestSuggestStoreBuilderPointerType);
+ dom::UniFFIPointer::Create(mValue, &kLoginsStaticKeyManagerPointerType);
mValue = nullptr;
}
@@ -2156,44 +2521,44 @@ class FfiValueObjectHandleSuggestSuggestStoreBuilder {
return temp;
}
- static FfiValueObjectHandleSuggestSuggestStoreBuilder FromRust(void* aValue) {
- return FfiValueObjectHandleSuggestSuggestStoreBuilder(aValue);
+ static FfiValueObjectHandleLoginsStaticKeyManager FromRust(void* aValue) {
+ return FfiValueObjectHandleLoginsStaticKeyManager(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_suggest_fn_free_suggeststorebuilder)(mValue, &callStatus);
+ (uniffi_logins_fn_free_statickeymanager)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleSuggestSuggestStoreBuilder() {
+ ~FfiValueObjectHandleLoginsStaticKeyManager() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kTabsRemoteCommandStorePointerType {
- "tabs::RemoteCommandStore"_ns,
- uniffi_tabs_fn_clone_remotecommandstore,
- uniffi_tabs_fn_free_remotecommandstore,
+const static mozilla::uniffi::UniFFIPointerType kRelevancyRelevancyStorePointerType {
+ "relevancy::RelevancyStore"_ns,
+ uniffi_relevancy_fn_clone_relevancystore,
+ uniffi_relevancy_fn_free_relevancystore,
};
-class FfiValueObjectHandleTabsRemoteCommandStore {
+class FfiValueObjectHandleRelevancyRelevancyStore {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleTabsRemoteCommandStore() = default;
- explicit FfiValueObjectHandleTabsRemoteCommandStore(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleRelevancyRelevancyStore() = default;
+ explicit FfiValueObjectHandleRelevancyRelevancyStore(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleTabsRemoteCommandStore(const FfiValueObjectHandleTabsRemoteCommandStore&) = delete;
- FfiValueObjectHandleTabsRemoteCommandStore& operator=(const FfiValueObjectHandleTabsRemoteCommandStore&) = delete;
+ FfiValueObjectHandleRelevancyRelevancyStore(const FfiValueObjectHandleRelevancyRelevancyStore&) = delete;
+ FfiValueObjectHandleRelevancyRelevancyStore& operator=(const FfiValueObjectHandleRelevancyRelevancyStore&) = delete;
- FfiValueObjectHandleTabsRemoteCommandStore& operator=(FfiValueObjectHandleTabsRemoteCommandStore&& aOther) {
+ FfiValueObjectHandleRelevancyRelevancyStore& operator=(FfiValueObjectHandleRelevancyRelevancyStore&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2207,7 +2572,7 @@ class FfiValueObjectHandleTabsRemoteCommandStore {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kTabsRemoteCommandStorePointerType)) {
+ if (!value.IsSamePtrType(&kRelevancyRelevancyStorePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2225,7 +2590,7 @@ class FfiValueObjectHandleTabsRemoteCommandStore {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kTabsRemoteCommandStorePointerType);
+ dom::UniFFIPointer::Create(mValue, &kRelevancyRelevancyStorePointerType);
mValue = nullptr;
}
@@ -2235,44 +2600,44 @@ class FfiValueObjectHandleTabsRemoteCommandStore {
return temp;
}
- static FfiValueObjectHandleTabsRemoteCommandStore FromRust(void* aValue) {
- return FfiValueObjectHandleTabsRemoteCommandStore(aValue);
+ static FfiValueObjectHandleRelevancyRelevancyStore FromRust(void* aValue) {
+ return FfiValueObjectHandleRelevancyRelevancyStore(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_tabs_fn_free_remotecommandstore)(mValue, &callStatus);
+ (uniffi_relevancy_fn_free_relevancystore)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleTabsRemoteCommandStore() {
+ ~FfiValueObjectHandleRelevancyRelevancyStore() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kTabsTabsBridgedEnginePointerType {
- "tabs::TabsBridgedEngine"_ns,
- uniffi_tabs_fn_clone_tabsbridgedengine,
- uniffi_tabs_fn_free_tabsbridgedengine,
+const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsPointerType {
+ "remote_settings::RemoteSettings"_ns,
+ uniffi_remote_settings_fn_clone_remotesettings,
+ uniffi_remote_settings_fn_free_remotesettings,
};
-class FfiValueObjectHandleTabsTabsBridgedEngine {
+class FfiValueObjectHandleRemoteSettingsRemoteSettings {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleTabsTabsBridgedEngine() = default;
- explicit FfiValueObjectHandleTabsTabsBridgedEngine(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleRemoteSettingsRemoteSettings() = default;
+ explicit FfiValueObjectHandleRemoteSettingsRemoteSettings(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleTabsTabsBridgedEngine(const FfiValueObjectHandleTabsTabsBridgedEngine&) = delete;
- FfiValueObjectHandleTabsTabsBridgedEngine& operator=(const FfiValueObjectHandleTabsTabsBridgedEngine&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettings(const FfiValueObjectHandleRemoteSettingsRemoteSettings&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettings& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettings&) = delete;
- FfiValueObjectHandleTabsTabsBridgedEngine& operator=(FfiValueObjectHandleTabsTabsBridgedEngine&& aOther) {
+ FfiValueObjectHandleRemoteSettingsRemoteSettings& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettings&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2286,7 +2651,7 @@ class FfiValueObjectHandleTabsTabsBridgedEngine {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kTabsTabsBridgedEnginePointerType)) {
+ if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2304,7 +2669,7 @@ class FfiValueObjectHandleTabsTabsBridgedEngine {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kTabsTabsBridgedEnginePointerType);
+ dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsPointerType);
mValue = nullptr;
}
@@ -2314,44 +2679,44 @@ class FfiValueObjectHandleTabsTabsBridgedEngine {
return temp;
}
- static FfiValueObjectHandleTabsTabsBridgedEngine FromRust(void* aValue) {
- return FfiValueObjectHandleTabsTabsBridgedEngine(aValue);
+ static FfiValueObjectHandleRemoteSettingsRemoteSettings FromRust(void* aValue) {
+ return FfiValueObjectHandleRemoteSettingsRemoteSettings(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_tabs_fn_free_tabsbridgedengine)(mValue, &callStatus);
+ (uniffi_remote_settings_fn_free_remotesettings)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleTabsTabsBridgedEngine() {
+ ~FfiValueObjectHandleRemoteSettingsRemoteSettings() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kTabsTabsStorePointerType {
- "tabs::TabsStore"_ns,
- uniffi_tabs_fn_clone_tabsstore,
- uniffi_tabs_fn_free_tabsstore,
+const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsClientPointerType {
+ "remote_settings::RemoteSettingsClient"_ns,
+ uniffi_remote_settings_fn_clone_remotesettingsclient,
+ uniffi_remote_settings_fn_free_remotesettingsclient,
};
-class FfiValueObjectHandleTabsTabsStore {
+class FfiValueObjectHandleRemoteSettingsRemoteSettingsClient {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleTabsTabsStore() = default;
- explicit FfiValueObjectHandleTabsTabsStore(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient() = default;
+ explicit FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleTabsTabsStore(const FfiValueObjectHandleTabsTabsStore&) = delete;
- FfiValueObjectHandleTabsTabsStore& operator=(const FfiValueObjectHandleTabsTabsStore&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(const FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&) = delete;
- FfiValueObjectHandleTabsTabsStore& operator=(FfiValueObjectHandleTabsTabsStore&& aOther) {
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettingsClient&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2365,7 +2730,7 @@ class FfiValueObjectHandleTabsTabsStore {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kTabsTabsStorePointerType)) {
+ if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsClientPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2383,7 +2748,7 @@ class FfiValueObjectHandleTabsTabsStore {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kTabsTabsStorePointerType);
+ dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsClientPointerType);
mValue = nullptr;
}
@@ -2393,163 +2758,123 @@ class FfiValueObjectHandleTabsTabsStore {
return temp;
}
- static FfiValueObjectHandleTabsTabsStore FromRust(void* aValue) {
- return FfiValueObjectHandleTabsTabsStore(aValue);
+ static FfiValueObjectHandleRemoteSettingsRemoteSettingsClient FromRust(void* aValue) {
+ return FfiValueObjectHandleRemoteSettingsRemoteSettingsClient(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_tabs_fn_free_tabsstore)(mValue, &callStatus);
+ (uniffi_remote_settings_fn_free_remotesettingsclient)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleTabsTabsStore() {
+ ~FfiValueObjectHandleRemoteSettingsRemoteSettingsClient() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kViaductBackendPointerType {
- "viaduct::Backend"_ns,
- uniffi_viaduct_fn_clone_backend,
- uniffi_viaduct_fn_free_backend,
+const static mozilla::uniffi::UniFFIPointerType kRemoteSettingsRemoteSettingsServicePointerType {
+ "remote_settings::RemoteSettingsService"_ns,
+ uniffi_remote_settings_fn_clone_remotesettingsservice,
+ uniffi_remote_settings_fn_free_remotesettingsservice,
};
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_viaduct_backend(uint64_t uniffiHandle);
-
-// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
-// interface version
-class FfiValueObjectHandleViaductBackend {
+class FfiValueObjectHandleRemoteSettingsRemoteSettingsService {
private:
- // Did we lower a callback interface, rather than lift an object interface?
- // This is weird, but it's a needed work until something like
- // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
- bool mLoweredCallbackInterface = false;
- // The raw FFI value is a pointer.
- // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
- // handles are incremented by one at a time, so even on a 32-bit system this
- // shouldn't overflow.
void* mValue = nullptr;
public:
- FfiValueObjectHandleViaductBackend() = default;
- explicit FfiValueObjectHandleViaductBackend(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService() = default;
+ explicit FfiValueObjectHandleRemoteSettingsRemoteSettingsService(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleViaductBackend(const FfiValueObjectHandleViaductBackend&) = delete;
- FfiValueObjectHandleViaductBackend& operator=(const FfiValueObjectHandleViaductBackend&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService(const FfiValueObjectHandleRemoteSettingsRemoteSettingsService&) = delete;
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService& operator=(const FfiValueObjectHandleRemoteSettingsRemoteSettingsService&) = delete;
- FfiValueObjectHandleViaductBackend& operator=(FfiValueObjectHandleViaductBackend&& aOther) {
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService& operator=(FfiValueObjectHandleRemoteSettingsRemoteSettingsService&& aOther) {
FreeHandle();
mValue = aOther.mValue;
- mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
aOther.mValue = nullptr;
- aOther.mLoweredCallbackInterface = false;
return *this;
}
- // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
- return;
- }
- double floatValue = aValue.GetAsDouble();
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
- return;
- }
- FreeHandle();
- mValue = reinterpret_cast<void *>(intValue);
- mLoweredCallbackInterface = true;
- }
-
- // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
- void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
if (!aValue.IsUniFFIPointer()) {
aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kViaductBackendPointerType)) {
+ if (!value.IsSamePtrType(&kRemoteSettingsRemoteSettingsServicePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
FreeHandle();
mValue = value.ClonePtr();
- mLoweredCallbackInterface = false;
}
- // Lift treats `aDest` as a regular interface
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
+ }
+
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kViaductBackendPointerType);
+ dom::UniFFIPointer::Create(mValue, &kRemoteSettingsRemoteSettingsServicePointerType);
mValue = nullptr;
- mLoweredCallbackInterface = false;
}
void* IntoRust() {
auto temp = mValue;
mValue = nullptr;
- mLoweredCallbackInterface = false;
return temp;
}
- static FfiValueObjectHandleViaductBackend FromRust(void* aValue) {
- return FfiValueObjectHandleViaductBackend(aValue);
+ static FfiValueObjectHandleRemoteSettingsRemoteSettingsService FromRust(void* aValue) {
+ return FfiValueObjectHandleRemoteSettingsRemoteSettingsService(aValue);
}
void FreeHandle() {
- // This behavior depends on if we lowered a callback interface handle or lifted an interface
- // pointer.
- if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
- printf("FREEING CB %p\n", mValue);
- callback_free_viaduct_backend(reinterpret_cast<uintptr_t>(mValue));
- mValue = reinterpret_cast<void *>(0);
- } else if (!mLoweredCallbackInterface && mValue != nullptr) {
- printf("FREEING interface %p\n", mValue);
+ if (mValue) {
RustCallStatus callStatus{};
- (uniffi_viaduct_fn_free_backend)(mValue, &callStatus);
+ (uniffi_remote_settings_fn_free_remotesettingsservice)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
- mValue = nullptr;
- mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleViaductBackend() {
+ ~FfiValueObjectHandleRemoteSettingsRemoteSettingsService() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kWebextstorageWebExtStorageBridgedEnginePointerType {
- "webextstorage::WebExtStorageBridgedEngine"_ns,
- uniffi_webext_storage_fn_clone_webextstoragebridgedengine,
- uniffi_webext_storage_fn_free_webextstoragebridgedengine,
+const static mozilla::uniffi::UniFFIPointerType kSearchSearchEngineSelectorPointerType {
+ "search::SearchEngineSelector"_ns,
+ uniffi_search_fn_clone_searchengineselector,
+ uniffi_search_fn_free_searchengineselector,
};
-class FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine {
+class FfiValueObjectHandleSearchSearchEngineSelector {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine() = default;
- explicit FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleSearchSearchEngineSelector() = default;
+ explicit FfiValueObjectHandleSearchSearchEngineSelector(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(const FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&) = delete;
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine& operator=(const FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&) = delete;
+ FfiValueObjectHandleSearchSearchEngineSelector(const FfiValueObjectHandleSearchSearchEngineSelector&) = delete;
+ FfiValueObjectHandleSearchSearchEngineSelector& operator=(const FfiValueObjectHandleSearchSearchEngineSelector&) = delete;
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine& operator=(FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&& aOther) {
+ FfiValueObjectHandleSearchSearchEngineSelector& operator=(FfiValueObjectHandleSearchSearchEngineSelector&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2563,7 +2888,7 @@ class FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kWebextstorageWebExtStorageBridgedEnginePointerType)) {
+ if (!value.IsSamePtrType(&kSearchSearchEngineSelectorPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2581,7 +2906,7 @@ class FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kWebextstorageWebExtStorageBridgedEnginePointerType);
+ dom::UniFFIPointer::Create(mValue, &kSearchSearchEngineSelectorPointerType);
mValue = nullptr;
}
@@ -2591,44 +2916,44 @@ class FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine {
return temp;
}
- static FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine FromRust(void* aValue) {
- return FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(aValue);
+ static FfiValueObjectHandleSearchSearchEngineSelector FromRust(void* aValue) {
+ return FfiValueObjectHandleSearchSearchEngineSelector(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_webext_storage_fn_free_webextstoragebridgedengine)(mValue, &callStatus);
+ (uniffi_search_fn_free_searchengineselector)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine() {
+ ~FfiValueObjectHandleSearchSearchEngineSelector() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kWebextstorageWebExtStorageStorePointerType {
- "webextstorage::WebExtStorageStore"_ns,
- uniffi_webext_storage_fn_clone_webextstoragestore,
- uniffi_webext_storage_fn_free_webextstoragestore,
+const static mozilla::uniffi::UniFFIPointerType kSuggestSuggestStorePointerType {
+ "suggest::SuggestStore"_ns,
+ uniffi_suggest_fn_clone_suggeststore,
+ uniffi_suggest_fn_free_suggeststore,
};
-class FfiValueObjectHandleWebextstorageWebExtStorageStore {
+class FfiValueObjectHandleSuggestSuggestStore {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleWebextstorageWebExtStorageStore() = default;
- explicit FfiValueObjectHandleWebextstorageWebExtStorageStore(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleSuggestSuggestStore() = default;
+ explicit FfiValueObjectHandleSuggestSuggestStore(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleWebextstorageWebExtStorageStore(const FfiValueObjectHandleWebextstorageWebExtStorageStore&) = delete;
- FfiValueObjectHandleWebextstorageWebExtStorageStore& operator=(const FfiValueObjectHandleWebextstorageWebExtStorageStore&) = delete;
+ FfiValueObjectHandleSuggestSuggestStore(const FfiValueObjectHandleSuggestSuggestStore&) = delete;
+ FfiValueObjectHandleSuggestSuggestStore& operator=(const FfiValueObjectHandleSuggestSuggestStore&) = delete;
- FfiValueObjectHandleWebextstorageWebExtStorageStore& operator=(FfiValueObjectHandleWebextstorageWebExtStorageStore&& aOther) {
+ FfiValueObjectHandleSuggestSuggestStore& operator=(FfiValueObjectHandleSuggestSuggestStore&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2642,7 +2967,7 @@ class FfiValueObjectHandleWebextstorageWebExtStorageStore {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kWebextstorageWebExtStorageStorePointerType)) {
+ if (!value.IsSamePtrType(&kSuggestSuggestStorePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2660,7 +2985,7 @@ class FfiValueObjectHandleWebextstorageWebExtStorageStore {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kWebextstorageWebExtStorageStorePointerType);
+ dom::UniFFIPointer::Create(mValue, &kSuggestSuggestStorePointerType);
mValue = nullptr;
}
@@ -2670,46 +2995,44 @@ class FfiValueObjectHandleWebextstorageWebExtStorageStore {
return temp;
}
- static FfiValueObjectHandleWebextstorageWebExtStorageStore FromRust(void* aValue) {
- return FfiValueObjectHandleWebextstorageWebExtStorageStore(aValue);
+ static FfiValueObjectHandleSuggestSuggestStore FromRust(void* aValue) {
+ return FfiValueObjectHandleSuggestSuggestStore(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_webext_storage_fn_free_webextstoragestore)(mValue, &callStatus);
+ (uniffi_suggest_fn_free_suggeststore)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleWebextstorageWebExtStorageStore() {
+ ~FfiValueObjectHandleSuggestSuggestStore() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-
-#ifdef MOZ_UNIFFI_FIXTURES
-const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsTestInterfacePointerType {
- "uniffi_bindings_tests::TestInterface"_ns,
- uniffi_uniffi_bindings_tests_fn_clone_testinterface,
- uniffi_uniffi_bindings_tests_fn_free_testinterface,
+const static mozilla::uniffi::UniFFIPointerType kSuggestSuggestStoreBuilderPointerType {
+ "suggest::SuggestStoreBuilder"_ns,
+ uniffi_suggest_fn_clone_suggeststorebuilder,
+ uniffi_suggest_fn_free_suggeststorebuilder,
};
-class FfiValueObjectHandleUniffiBindingsTestsTestInterface {
+class FfiValueObjectHandleSuggestSuggestStoreBuilder {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleUniffiBindingsTestsTestInterface() = default;
- explicit FfiValueObjectHandleUniffiBindingsTestsTestInterface(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleSuggestSuggestStoreBuilder() = default;
+ explicit FfiValueObjectHandleSuggestSuggestStoreBuilder(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleUniffiBindingsTestsTestInterface(const FfiValueObjectHandleUniffiBindingsTestsTestInterface&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsTestInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsTestInterface&) = delete;
+ FfiValueObjectHandleSuggestSuggestStoreBuilder(const FfiValueObjectHandleSuggestSuggestStoreBuilder&) = delete;
+ FfiValueObjectHandleSuggestSuggestStoreBuilder& operator=(const FfiValueObjectHandleSuggestSuggestStoreBuilder&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsTestInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsTestInterface&& aOther) {
+ FfiValueObjectHandleSuggestSuggestStoreBuilder& operator=(FfiValueObjectHandleSuggestSuggestStoreBuilder&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2723,7 +3046,7 @@ class FfiValueObjectHandleUniffiBindingsTestsTestInterface {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kUniffiBindingsTestsTestInterfacePointerType)) {
+ if (!value.IsSamePtrType(&kSuggestSuggestStoreBuilderPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2741,7 +3064,7 @@ class FfiValueObjectHandleUniffiBindingsTestsTestInterface {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsTestInterfacePointerType);
+ dom::UniFFIPointer::Create(mValue, &kSuggestSuggestStoreBuilderPointerType);
mValue = nullptr;
}
@@ -2751,44 +3074,44 @@ class FfiValueObjectHandleUniffiBindingsTestsTestInterface {
return temp;
}
- static FfiValueObjectHandleUniffiBindingsTestsTestInterface FromRust(void* aValue) {
- return FfiValueObjectHandleUniffiBindingsTestsTestInterface(aValue);
+ static FfiValueObjectHandleSuggestSuggestStoreBuilder FromRust(void* aValue) {
+ return FfiValueObjectHandleSuggestSuggestStoreBuilder(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_uniffi_bindings_tests_fn_free_testinterface)(mValue, &callStatus);
+ (uniffi_suggest_fn_free_suggeststorebuilder)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleUniffiBindingsTestsTestInterface() {
+ ~FfiValueObjectHandleSuggestSuggestStoreBuilder() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsAsyncInterfacePointerType {
- "uniffi_bindings_tests::AsyncInterface"_ns,
- uniffi_uniffi_bindings_tests_fn_clone_asyncinterface,
- uniffi_uniffi_bindings_tests_fn_free_asyncinterface,
+const static mozilla::uniffi::UniFFIPointerType kTabsRemoteCommandStorePointerType {
+ "tabs::RemoteCommandStore"_ns,
+ uniffi_tabs_fn_clone_remotecommandstore,
+ uniffi_tabs_fn_free_remotecommandstore,
};
-class FfiValueObjectHandleUniffiBindingsTestsAsyncInterface {
+class FfiValueObjectHandleTabsRemoteCommandStore {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface() = default;
- explicit FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleTabsRemoteCommandStore() = default;
+ explicit FfiValueObjectHandleTabsRemoteCommandStore(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(const FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&) = delete;
+ FfiValueObjectHandleTabsRemoteCommandStore(const FfiValueObjectHandleTabsRemoteCommandStore&) = delete;
+ FfiValueObjectHandleTabsRemoteCommandStore& operator=(const FfiValueObjectHandleTabsRemoteCommandStore&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&& aOther) {
+ FfiValueObjectHandleTabsRemoteCommandStore& operator=(FfiValueObjectHandleTabsRemoteCommandStore&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -2802,7 +3125,7 @@ class FfiValueObjectHandleUniffiBindingsTestsAsyncInterface {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kUniffiBindingsTestsAsyncInterfacePointerType)) {
+ if (!value.IsSamePtrType(&kTabsRemoteCommandStorePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -2820,7 +3143,7 @@ class FfiValueObjectHandleUniffiBindingsTestsAsyncInterface {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsAsyncInterfacePointerType);
+ dom::UniFFIPointer::Create(mValue, &kTabsRemoteCommandStorePointerType);
mValue = nullptr;
}
@@ -2830,163 +3153,123 @@ class FfiValueObjectHandleUniffiBindingsTestsAsyncInterface {
return temp;
}
- static FfiValueObjectHandleUniffiBindingsTestsAsyncInterface FromRust(void* aValue) {
- return FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(aValue);
+ static FfiValueObjectHandleTabsRemoteCommandStore FromRust(void* aValue) {
+ return FfiValueObjectHandleTabsRemoteCommandStore(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_uniffi_bindings_tests_fn_free_asyncinterface)(mValue, &callStatus);
+ (uniffi_tabs_fn_free_remotecommandstore)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleUniffiBindingsTestsAsyncInterface() {
+ ~FfiValueObjectHandleTabsRemoteCommandStore() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsAsyncTestTraitInterfacePointerType {
- "uniffi_bindings_tests::AsyncTestTraitInterface"_ns,
- uniffi_uniffi_bindings_tests_fn_clone_asynctesttraitinterface,
- uniffi_uniffi_bindings_tests_fn_free_asynctesttraitinterface,
+const static mozilla::uniffi::UniFFIPointerType kTabsTabsBridgedEnginePointerType {
+ "tabs::TabsBridgedEngine"_ns,
+ uniffi_tabs_fn_clone_tabsbridgedengine,
+ uniffi_tabs_fn_free_tabsbridgedengine,
};
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_uniffi_bindings_tests_async_test_trait_interface(uint64_t uniffiHandle);
-
-// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
-// interface version
-class FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface {
+class FfiValueObjectHandleTabsTabsBridgedEngine {
private:
- // Did we lower a callback interface, rather than lift an object interface?
- // This is weird, but it's a needed work until something like
- // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
- bool mLoweredCallbackInterface = false;
- // The raw FFI value is a pointer.
- // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
- // handles are incremented by one at a time, so even on a 32-bit system this
- // shouldn't overflow.
void* mValue = nullptr;
public:
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface() = default;
- explicit FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleTabsTabsBridgedEngine() = default;
+ explicit FfiValueObjectHandleTabsTabsBridgedEngine(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(const FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&) = delete;
+ FfiValueObjectHandleTabsTabsBridgedEngine(const FfiValueObjectHandleTabsTabsBridgedEngine&) = delete;
+ FfiValueObjectHandleTabsTabsBridgedEngine& operator=(const FfiValueObjectHandleTabsTabsBridgedEngine&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&& aOther) {
+ FfiValueObjectHandleTabsTabsBridgedEngine& operator=(FfiValueObjectHandleTabsTabsBridgedEngine&& aOther) {
FreeHandle();
mValue = aOther.mValue;
- mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
aOther.mValue = nullptr;
- aOther.mLoweredCallbackInterface = false;
return *this;
}
- // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
- return;
- }
- double floatValue = aValue.GetAsDouble();
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
- return;
- }
- FreeHandle();
- mValue = reinterpret_cast<void *>(intValue);
- mLoweredCallbackInterface = true;
- }
-
- // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
- void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
if (!aValue.IsUniFFIPointer()) {
aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kUniffiBindingsTestsAsyncTestTraitInterfacePointerType)) {
+ if (!value.IsSamePtrType(&kTabsTabsBridgedEnginePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
FreeHandle();
mValue = value.ClonePtr();
- mLoweredCallbackInterface = false;
}
- // Lift treats `aDest` as a regular interface
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
+ }
+
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType);
+ dom::UniFFIPointer::Create(mValue, &kTabsTabsBridgedEnginePointerType);
mValue = nullptr;
- mLoweredCallbackInterface = false;
}
void* IntoRust() {
auto temp = mValue;
mValue = nullptr;
- mLoweredCallbackInterface = false;
return temp;
}
- static FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface FromRust(void* aValue) {
- return FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(aValue);
+ static FfiValueObjectHandleTabsTabsBridgedEngine FromRust(void* aValue) {
+ return FfiValueObjectHandleTabsTabsBridgedEngine(aValue);
}
void FreeHandle() {
- // This behavior depends on if we lowered a callback interface handle or lifted an interface
- // pointer.
- if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
- printf("FREEING CB %p\n", mValue);
- callback_free_uniffi_bindings_tests_async_test_trait_interface(reinterpret_cast<uintptr_t>(mValue));
- mValue = reinterpret_cast<void *>(0);
- } else if (!mLoweredCallbackInterface && mValue != nullptr) {
- printf("FREEING interface %p\n", mValue);
+ if (mValue) {
RustCallStatus callStatus{};
- (uniffi_uniffi_bindings_tests_fn_free_asynctesttraitinterface)(mValue, &callStatus);
+ (uniffi_tabs_fn_free_tabsbridgedengine)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
- mValue = nullptr;
- mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface() {
+ ~FfiValueObjectHandleTabsTabsBridgedEngine() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsComplexMethodsPointerType {
- "uniffi_bindings_tests::ComplexMethods"_ns,
- uniffi_uniffi_bindings_tests_fn_clone_complexmethods,
- uniffi_uniffi_bindings_tests_fn_free_complexmethods,
+const static mozilla::uniffi::UniFFIPointerType kTabsTabsStorePointerType {
+ "tabs::TabsStore"_ns,
+ uniffi_tabs_fn_clone_tabsstore,
+ uniffi_tabs_fn_free_tabsstore,
};
-class FfiValueObjectHandleUniffiBindingsTestsComplexMethods {
+class FfiValueObjectHandleTabsTabsStore {
private:
void* mValue = nullptr;
public:
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods() = default;
- explicit FfiValueObjectHandleUniffiBindingsTestsComplexMethods(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleTabsTabsStore() = default;
+ explicit FfiValueObjectHandleTabsTabsStore(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods(const FfiValueObjectHandleUniffiBindingsTestsComplexMethods&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods& operator=(const FfiValueObjectHandleUniffiBindingsTestsComplexMethods&) = delete;
+ FfiValueObjectHandleTabsTabsStore(const FfiValueObjectHandleTabsTabsStore&) = delete;
+ FfiValueObjectHandleTabsTabsStore& operator=(const FfiValueObjectHandleTabsTabsStore&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods& operator=(FfiValueObjectHandleUniffiBindingsTestsComplexMethods&& aOther) {
+ FfiValueObjectHandleTabsTabsStore& operator=(FfiValueObjectHandleTabsTabsStore&& aOther) {
FreeHandle();
mValue = aOther.mValue;
aOther.mValue = nullptr;
@@ -3000,7 +3283,7 @@ class FfiValueObjectHandleUniffiBindingsTestsComplexMethods {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kUniffiBindingsTestsComplexMethodsPointerType)) {
+ if (!value.IsSamePtrType(&kTabsTabsStorePointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -3018,7 +3301,7 @@ class FfiValueObjectHandleUniffiBindingsTestsComplexMethods {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsComplexMethodsPointerType);
+ dom::UniFFIPointer::Create(mValue, &kTabsTabsStorePointerType);
mValue = nullptr;
}
@@ -3028,37 +3311,37 @@ class FfiValueObjectHandleUniffiBindingsTestsComplexMethods {
return temp;
}
- static FfiValueObjectHandleUniffiBindingsTestsComplexMethods FromRust(void* aValue) {
- return FfiValueObjectHandleUniffiBindingsTestsComplexMethods(aValue);
+ static FfiValueObjectHandleTabsTabsStore FromRust(void* aValue) {
+ return FfiValueObjectHandleTabsTabsStore(aValue);
}
void FreeHandle() {
if (mValue) {
RustCallStatus callStatus{};
- (uniffi_uniffi_bindings_tests_fn_free_complexmethods)(mValue, &callStatus);
+ (uniffi_tabs_fn_free_tabsstore)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
}
- ~FfiValueObjectHandleUniffiBindingsTestsComplexMethods() {
+ ~FfiValueObjectHandleTabsTabsStore() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsTestTraitInterfacePointerType {
- "uniffi_bindings_tests::TestTraitInterface"_ns,
- uniffi_uniffi_bindings_tests_fn_clone_testtraitinterface,
- uniffi_uniffi_bindings_tests_fn_free_testtraitinterface,
+const static mozilla::uniffi::UniFFIPointerType kViaductBackendPointerType {
+ "viaduct::Backend"_ns,
+ uniffi_viaduct_fn_clone_backend,
+ uniffi_viaduct_fn_free_backend,
};
// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_uniffi_bindings_tests_test_trait_interface(uint64_t uniffiHandle);
+extern "C" void callback_free_viaduct_backend(uint64_t uniffiHandle);
// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
// interface version
-class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
+class FfiValueObjectHandleViaductBackend {
private:
// Did we lower a callback interface, rather than lift an object interface?
// This is weird, but it's a needed work until something like
@@ -3071,14 +3354,14 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
void* mValue = nullptr;
public:
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface() = default;
- explicit FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(void* aValue) : mValue(aValue) {}
+ FfiValueObjectHandleViaductBackend() = default;
+ explicit FfiValueObjectHandleViaductBackend(void* aValue) : mValue(aValue) {}
// Delete copy constructor and assignment as this type is non-copyable.
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(const FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&) = delete;
+ FfiValueObjectHandleViaductBackend(const FfiValueObjectHandleViaductBackend&) = delete;
+ FfiValueObjectHandleViaductBackend& operator=(const FfiValueObjectHandleViaductBackend&) = delete;
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&& aOther) {
+ FfiValueObjectHandleViaductBackend& operator=(FfiValueObjectHandleViaductBackend&& aOther) {
FreeHandle();
mValue = aOther.mValue;
mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
@@ -3113,7 +3396,7 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
return;
}
dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
- if (!value.IsSamePtrType(&kUniffiBindingsTestsTestTraitInterfacePointerType)) {
+ if (!value.IsSamePtrType(&kViaductBackendPointerType)) {
aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
@@ -3126,7 +3409,7 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
aDest->SetAsUniFFIPointer() =
- dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsTestTraitInterfacePointerType);
+ dom::UniFFIPointer::Create(mValue, &kViaductBackendPointerType);
mValue = nullptr;
mLoweredCallbackInterface = false;
}
@@ -3138,8 +3421,8 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
return temp;
}
- static FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface FromRust(void* aValue) {
- return FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(aValue);
+ static FfiValueObjectHandleViaductBackend FromRust(void* aValue) {
+ return FfiValueObjectHandleViaductBackend(aValue);
}
void FreeHandle() {
@@ -3147,12 +3430,12 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
// pointer.
if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
printf("FREEING CB %p\n", mValue);
- callback_free_uniffi_bindings_tests_test_trait_interface(reinterpret_cast<uintptr_t>(mValue));
+ callback_free_viaduct_backend(reinterpret_cast<uintptr_t>(mValue));
mValue = reinterpret_cast<void *>(0);
} else if (!mLoweredCallbackInterface && mValue != nullptr) {
printf("FREEING interface %p\n", mValue);
RustCallStatus callStatus{};
- (uniffi_uniffi_bindings_tests_fn_free_testtraitinterface)(mValue, &callStatus);
+ (uniffi_viaduct_fn_free_backend)(mValue, &callStatus);
// No need to check `RustCallStatus`, it's only part of the API to match
// other FFI calls. The free function can never fail.
}
@@ -3160,489 +3443,371 @@ class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
mLoweredCallbackInterface = false;
}
- ~FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface() {
+ ~FfiValueObjectHandleViaductBackend() {
// If the pointer is non-null, this means Lift/IntoRust was never called
// because there was some failure along the way. Free the pointer to avoid a
// leak
FreeHandle();
}
};
-#endif /* MOZ_UNIFFI_FIXTURES */
-
-Maybe<already_AddRefed<UniFFIPointer>> ReadPointer(const GlobalObject& aGlobal, uint64_t aId, const ArrayBuffer& aArrayBuff, long aPosition, ErrorResult& aError) {
- const UniFFIPointerType* type;
- switch (aId) {
-
- case 1: {
- type = &kContextIdContextIdComponentPointerType;
- break;
- }
- case 2: {
- type = &kFilterAdultFilterAdultComponentPointerType;
- break;
- }
- case 3: {
- type = &kRelevancyRelevancyStorePointerType;
- break;
- }
- case 4: {
- type = &kRemoteSettingsRemoteSettingsPointerType;
- break;
- }
- case 5: {
- type = &kRemoteSettingsRemoteSettingsClientPointerType;
- break;
- }
- case 6: {
- type = &kRemoteSettingsRemoteSettingsServicePointerType;
- break;
- }
- case 7: {
- type = &kSearchSearchEngineSelectorPointerType;
- break;
- }
- case 8: {
- type = &kSuggestSuggestStorePointerType;
- break;
- }
- case 9: {
- type = &kSuggestSuggestStoreBuilderPointerType;
- break;
- }
- case 10: {
- type = &kTabsRemoteCommandStorePointerType;
- break;
- }
- case 11: {
- type = &kTabsTabsBridgedEnginePointerType;
- break;
- }
- case 12: {
- type = &kTabsTabsStorePointerType;
- break;
- }
- case 13: {
- type = &kViaductBackendPointerType;
- break;
- }
- case 14: {
- type = &kWebextstorageWebExtStorageBridgedEnginePointerType;
- break;
- }
- case 15: {
- type = &kWebextstorageWebExtStorageStorePointerType;
- break;
- }
-
-#ifdef MOZ_UNIFFI_FIXTURES
- case 16: {
- type = &kUniffiBindingsTestsTestInterfacePointerType;
- break;
- }
- case 17: {
- type = &kUniffiBindingsTestsAsyncInterfacePointerType;
- break;
- }
- case 18: {
- type = &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType;
- break;
- }
- case 19: {
- type = &kUniffiBindingsTestsComplexMethodsPointerType;
- break;
- }
- case 20: {
- type = &kUniffiBindingsTestsTestTraitInterfacePointerType;
- break;
- }
-#endif /* MOZ_UNIFFI_FIXTURES */
- default:
- return Nothing();
- }
- return Some(UniFFIPointer::Read(aArrayBuff, aPosition, type, aError));
-}
+const static mozilla::uniffi::UniFFIPointerType kWebextstorageWebExtStorageBridgedEnginePointerType {
+ "webextstorage::WebExtStorageBridgedEngine"_ns,
+ uniffi_webext_storage_fn_clone_webextstoragebridgedengine,
+ uniffi_webext_storage_fn_free_webextstoragebridgedengine,
+};
+class FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine {
+ private:
+ void* mValue = nullptr;
-bool WritePointer(const GlobalObject& aGlobal, uint64_t aId, const UniFFIPointer& aPtr, const ArrayBuffer& aArrayBuff, long aPosition, ErrorResult& aError) {
- const UniFFIPointerType* type;
- switch (aId) {
+ public:
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine() = default;
+ explicit FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(void* aValue) : mValue(aValue) {}
- case 1: {
- type = &kContextIdContextIdComponentPointerType;
- break;
- }
- case 2: {
- type = &kFilterAdultFilterAdultComponentPointerType;
- break;
- }
- case 3: {
- type = &kRelevancyRelevancyStorePointerType;
- break;
- }
- case 4: {
- type = &kRemoteSettingsRemoteSettingsPointerType;
- break;
- }
- case 5: {
- type = &kRemoteSettingsRemoteSettingsClientPointerType;
- break;
- }
- case 6: {
- type = &kRemoteSettingsRemoteSettingsServicePointerType;
- break;
- }
- case 7: {
- type = &kSearchSearchEngineSelectorPointerType;
- break;
- }
- case 8: {
- type = &kSuggestSuggestStorePointerType;
- break;
- }
- case 9: {
- type = &kSuggestSuggestStoreBuilderPointerType;
- break;
- }
- case 10: {
- type = &kTabsRemoteCommandStorePointerType;
- break;
- }
- case 11: {
- type = &kTabsTabsBridgedEnginePointerType;
- break;
- }
- case 12: {
- type = &kTabsTabsStorePointerType;
- break;
- }
- case 13: {
- type = &kViaductBackendPointerType;
- break;
- }
- case 14: {
- type = &kWebextstorageWebExtStorageBridgedEnginePointerType;
- break;
- }
- case 15: {
- type = &kWebextstorageWebExtStorageStorePointerType;
- break;
- }
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(const FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&) = delete;
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine& operator=(const FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&) = delete;
-#ifdef MOZ_UNIFFI_FIXTURES
- case 16: {
- type = &kUniffiBindingsTestsTestInterfacePointerType;
- break;
- }
- case 17: {
- type = &kUniffiBindingsTestsAsyncInterfacePointerType;
- break;
- }
- case 18: {
- type = &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType;
- break;
- }
- case 19: {
- type = &kUniffiBindingsTestsComplexMethodsPointerType;
- break;
- }
- case 20: {
- type = &kUniffiBindingsTestsTestTraitInterfacePointerType;
- break;
- }
-#endif /* MOZ_UNIFFI_FIXTURES */
- default:
- return false;
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine& operator=(FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ aOther.mValue = nullptr;
+ return *this;
}
- aPtr.Write(aArrayBuff, aPosition, type, aError);
- return true;
-}
-/* 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 https://mozilla.org/MPL/2.0/. */
-
-
-// Callback interface FfiValueClasses
-//
-// These need to come first so they're defined for the scaffolding call code
-
-
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_context_id_context_id_callback(uint64_t uniffiHandle);
-
-// FfiValue class for these callback interface handles. This works like the
-// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
-class FfiValueCallbackInterfacecontext_id_ContextIdCallback {
- private:
- // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
- // it up if we don't pass it to Rust because other values failed to lower
- bool mLowered = false;
- uint64_t mValue = 0;
-
- public:
- FfiValueCallbackInterfacecontext_id_ContextIdCallback() = default;
- explicit FfiValueCallbackInterfacecontext_id_ContextIdCallback(uint64_t aValue) : mValue(aValue) {}
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- double floatValue = aValue.GetAsDouble();
-
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kWebextstorageWebExtStorageBridgedEnginePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
- ReleaseHandleIfSet();
- mValue = intValue;
- mLowered = true;
+ FreeHandle();
+ mValue = value.ClonePtr();
+ }
+
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
}
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
- aDest->SetAsDouble() = mValue;
- mValue = 0;
- mLowered = false;
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kWebextstorageWebExtStorageBridgedEnginePointerType);
+ mValue = nullptr;
}
- uint64_t IntoRust() {
- auto handle = mValue;
- mValue = 0;
- mLowered = false;
- return handle;
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ return temp;
}
- static FfiValueCallbackInterfacecontext_id_ContextIdCallback FromRust(uint64_t aValue) { return FfiValueCallbackInterfacecontext_id_ContextIdCallback(aValue); };
+ static FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine FromRust(void* aValue) {
+ return FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine(aValue);
+ }
- void ReleaseHandleIfSet() {
- // A non-zero value indicates that we own a callback handle that was never passed to Rust or
- // lifted to JS and needs to be freed.
- if (mValue != 0 && mLowered) {
- callback_free_context_id_context_id_callback(mValue);
- mValue = 0;
- mLowered = false;
+ void FreeHandle() {
+ if (mValue) {
+ RustCallStatus callStatus{};
+ (uniffi_webext_storage_fn_free_webextstoragebridgedengine)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
}
}
- ~FfiValueCallbackInterfacecontext_id_ContextIdCallback() {
- ReleaseHandleIfSet();
+ ~FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_tracing_event_sink(uint64_t uniffiHandle);
-
-// FfiValue class for these callback interface handles. This works like the
-// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
-class FfiValueCallbackInterfacetracing_EventSink {
+const static mozilla::uniffi::UniFFIPointerType kWebextstorageWebExtStorageStorePointerType {
+ "webextstorage::WebExtStorageStore"_ns,
+ uniffi_webext_storage_fn_clone_webextstoragestore,
+ uniffi_webext_storage_fn_free_webextstoragestore,
+};
+class FfiValueObjectHandleWebextstorageWebExtStorageStore {
private:
- // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
- // it up if we don't pass it to Rust because other values failed to lower
- bool mLowered = false;
- uint64_t mValue = 0;
+ void* mValue = nullptr;
public:
- FfiValueCallbackInterfacetracing_EventSink() = default;
- explicit FfiValueCallbackInterfacetracing_EventSink(uint64_t aValue) : mValue(aValue) {}
+ FfiValueObjectHandleWebextstorageWebExtStorageStore() = default;
+ explicit FfiValueObjectHandleWebextstorageWebExtStorageStore(void* aValue) : mValue(aValue) {}
+
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleWebextstorageWebExtStorageStore(const FfiValueObjectHandleWebextstorageWebExtStorageStore&) = delete;
+ FfiValueObjectHandleWebextstorageWebExtStorageStore& operator=(const FfiValueObjectHandleWebextstorageWebExtStorageStore&) = delete;
+
+ FfiValueObjectHandleWebextstorageWebExtStorageStore& operator=(FfiValueObjectHandleWebextstorageWebExtStorageStore&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ aOther.mValue = nullptr;
+ return *this;
+ }
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- double floatValue = aValue.GetAsDouble();
-
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kWebextstorageWebExtStorageStorePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
- ReleaseHandleIfSet();
- mValue = intValue;
- mLowered = true;
+ FreeHandle();
+ mValue = value.ClonePtr();
+ }
+
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
}
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
- aDest->SetAsDouble() = mValue;
- mValue = 0;
- mLowered = false;
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kWebextstorageWebExtStorageStorePointerType);
+ mValue = nullptr;
}
- uint64_t IntoRust() {
- auto handle = mValue;
- mValue = 0;
- mLowered = false;
- return handle;
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ return temp;
}
- static FfiValueCallbackInterfacetracing_EventSink FromRust(uint64_t aValue) { return FfiValueCallbackInterfacetracing_EventSink(aValue); };
+ static FfiValueObjectHandleWebextstorageWebExtStorageStore FromRust(void* aValue) {
+ return FfiValueObjectHandleWebextstorageWebExtStorageStore(aValue);
+ }
- void ReleaseHandleIfSet() {
- // A non-zero value indicates that we own a callback handle that was never passed to Rust or
- // lifted to JS and needs to be freed.
- if (mValue != 0 && mLowered) {
- callback_free_tracing_event_sink(mValue);
- mValue = 0;
- mLowered = false;
+ void FreeHandle() {
+ if (mValue) {
+ RustCallStatus callStatus{};
+ (uniffi_webext_storage_fn_free_webextstoragestore)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
}
}
- ~FfiValueCallbackInterfacetracing_EventSink() {
- ReleaseHandleIfSet();
+ ~FfiValueObjectHandleWebextstorageWebExtStorageStore() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
#ifdef MOZ_UNIFFI_FIXTURES
-
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_uniffi_bindings_tests_test_async_callback_interface(uint64_t uniffiHandle);
-
-// FfiValue class for these callback interface handles. This works like the
-// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
-class FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface {
+const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsTestInterfacePointerType {
+ "uniffi_bindings_tests::TestInterface"_ns,
+ uniffi_uniffi_bindings_tests_fn_clone_testinterface,
+ uniffi_uniffi_bindings_tests_fn_free_testinterface,
+};
+class FfiValueObjectHandleUniffiBindingsTestsTestInterface {
private:
- // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
- // it up if we don't pass it to Rust because other values failed to lower
- bool mLowered = false;
- uint64_t mValue = 0;
+ void* mValue = nullptr;
public:
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface() = default;
- explicit FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface() = default;
+ explicit FfiValueObjectHandleUniffiBindingsTestsTestInterface(void* aValue) : mValue(aValue) {}
+
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface(const FfiValueObjectHandleUniffiBindingsTestsTestInterface&) = delete;
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsTestInterface&) = delete;
+
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsTestInterface&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ aOther.mValue = nullptr;
+ return *this;
+ }
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- double floatValue = aValue.GetAsDouble();
-
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kUniffiBindingsTestsTestInterfacePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
- ReleaseHandleIfSet();
- mValue = intValue;
- mLowered = true;
+ FreeHandle();
+ mValue = value.ClonePtr();
+ }
+
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
}
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
- aDest->SetAsDouble() = mValue;
- mValue = 0;
- mLowered = false;
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsTestInterfacePointerType);
+ mValue = nullptr;
}
- uint64_t IntoRust() {
- auto handle = mValue;
- mValue = 0;
- mLowered = false;
- return handle;
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ return temp;
}
- static FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface(aValue); };
+ static FfiValueObjectHandleUniffiBindingsTestsTestInterface FromRust(void* aValue) {
+ return FfiValueObjectHandleUniffiBindingsTestsTestInterface(aValue);
+ }
- void ReleaseHandleIfSet() {
- // A non-zero value indicates that we own a callback handle that was never passed to Rust or
- // lifted to JS and needs to be freed.
- if (mValue != 0 && mLowered) {
- callback_free_uniffi_bindings_tests_test_async_callback_interface(mValue);
- mValue = 0;
- mLowered = false;
+ void FreeHandle() {
+ if (mValue) {
+ RustCallStatus callStatus{};
+ (uniffi_uniffi_bindings_tests_fn_free_testinterface)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
}
}
- ~FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface() {
- ReleaseHandleIfSet();
+ ~FfiValueObjectHandleUniffiBindingsTestsTestInterface() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-
-// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_uniffi_bindings_tests_test_callback_interface(uint64_t uniffiHandle);
-
-// FfiValue class for these callback interface handles. This works like the
-// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
-class FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface {
+const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsAsyncInterfacePointerType {
+ "uniffi_bindings_tests::AsyncInterface"_ns,
+ uniffi_uniffi_bindings_tests_fn_clone_asyncinterface,
+ uniffi_uniffi_bindings_tests_fn_free_asyncinterface,
+};
+class FfiValueObjectHandleUniffiBindingsTestsAsyncInterface {
private:
- // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
- // it up if we don't pass it to Rust because other values failed to lower
- bool mLowered = false;
- uint64_t mValue = 0;
+ void* mValue = nullptr;
public:
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface() = default;
- explicit FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface() = default;
+ explicit FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(void* aValue) : mValue(aValue) {}
- void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
- ErrorResult& aError) {
- if (!aValue.IsDouble()) {
- aError.ThrowTypeError("Bad argument type"_ns);
- return;
- }
- double floatValue = aValue.GetAsDouble();
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(const FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&) = delete;
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&) = delete;
- uint64_t intValue = static_cast<uint64_t>(floatValue);
- if (intValue != floatValue) {
- aError.ThrowTypeError("Not an integer"_ns);
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsAsyncInterface&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ aOther.mValue = nullptr;
+ return *this;
+ }
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- ReleaseHandleIfSet();
- mValue = intValue;
- mLowered = true;
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kUniffiBindingsTestsAsyncInterfacePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
+ return;
+ }
+ FreeHandle();
+ mValue = value.ClonePtr();
+ }
+
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
}
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
- aDest->SetAsDouble() = mValue;
- mValue = 0;
- mLowered = false;
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsAsyncInterfacePointerType);
+ mValue = nullptr;
}
- uint64_t IntoRust() {
- auto handle = mValue;
- mValue = 0;
- mLowered = false;
- return handle;
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ return temp;
}
- static FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface(aValue); };
+ static FfiValueObjectHandleUniffiBindingsTestsAsyncInterface FromRust(void* aValue) {
+ return FfiValueObjectHandleUniffiBindingsTestsAsyncInterface(aValue);
+ }
- void ReleaseHandleIfSet() {
- // A non-zero value indicates that we own a callback handle that was never passed to Rust or
- // lifted to JS and needs to be freed.
- if (mValue != 0 && mLowered) {
- callback_free_uniffi_bindings_tests_test_callback_interface(mValue);
- mValue = 0;
- mLowered = false;
+ void FreeHandle() {
+ if (mValue) {
+ RustCallStatus callStatus{};
+ (uniffi_uniffi_bindings_tests_fn_free_asyncinterface)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
}
}
- ~FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface() {
- ReleaseHandleIfSet();
+ ~FfiValueObjectHandleUniffiBindingsTestsAsyncInterface() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-
+const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsAsyncTestTraitInterfacePointerType {
+ "uniffi_bindings_tests::AsyncTestTraitInterface"_ns,
+ uniffi_uniffi_bindings_tests_fn_clone_asynctesttraitinterface,
+ uniffi_uniffi_bindings_tests_fn_free_asynctesttraitinterface,
+};
// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
-extern "C" void callback_free_uniffi_bindings_tests_collision_test_callback_interface(uint64_t uniffiHandle);
+extern "C" void callback_free_uniffi_bindings_tests_async_test_trait_interface(uint64_t uniffiHandle);
-// FfiValue class for these callback interface handles. This works like the
-// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
-class FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface {
+// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
+// interface version
+class FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface {
private:
- // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
- // it up if we don't pass it to Rust because other values failed to lower
- bool mLowered = false;
- uint64_t mValue = 0;
+ // Did we lower a callback interface, rather than lift an object interface?
+ // This is weird, but it's a needed work until something like
+ // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
+ bool mLoweredCallbackInterface = false;
+ // The raw FFI value is a pointer.
+ // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
+ // handles are incremented by one at a time, so even on a 32-bit system this
+ // shouldn't overflow.
+ void* mValue = nullptr;
public:
- FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface() = default;
- explicit FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface() = default;
+ explicit FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(void* aValue) : mValue(aValue) {}
+
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(const FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&) = delete;
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&) = delete;
+
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
+ aOther.mValue = nullptr;
+ aOther.mLoweredCallbackInterface = false;
+ return *this;
+ }
+ // Lower treats `aValue` as a callback interface
void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
ErrorResult& aError) {
if (!aValue.IsDouble()) {
@@ -3650,866 +3815,907 @@ class FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInter
return;
}
double floatValue = aValue.GetAsDouble();
-
uint64_t intValue = static_cast<uint64_t>(floatValue);
if (intValue != floatValue) {
aError.ThrowTypeError("Not an integer"_ns);
return;
}
- ReleaseHandleIfSet();
- mValue = intValue;
- mLowered = true;
+ FreeHandle();
+ mValue = reinterpret_cast<void *>(intValue);
+ mLoweredCallbackInterface = true;
+ }
+
+ // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
+ return;
+ }
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kUniffiBindingsTestsAsyncTestTraitInterfacePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
+ return;
+ }
+ FreeHandle();
+ mValue = value.ClonePtr();
+ mLoweredCallbackInterface = false;
}
+ // Lift treats `aDest` as a regular interface
void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
ErrorResult& aError) {
- aDest->SetAsDouble() = mValue;
- mValue = 0;
- mLowered = false;
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType);
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- uint64_t IntoRust() {
- auto handle = mValue;
- mValue = 0;
- mLowered = false;
- return handle;
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
+ return temp;
}
- static FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface(aValue); };
+ static FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface FromRust(void* aValue) {
+ return FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface(aValue);
+ }
- void ReleaseHandleIfSet() {
- // A non-zero value indicates that we own a callback handle that was never passed to Rust or
- // lifted to JS and needs to be freed.
- if (mValue != 0 && mLowered) {
- callback_free_uniffi_bindings_tests_collision_test_callback_interface(mValue);
- mValue = 0;
- mLowered = false;
+ void FreeHandle() {
+ // This behavior depends on if we lowered a callback interface handle or lifted an interface
+ // pointer.
+ if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
+ printf("FREEING CB %p\n", mValue);
+ callback_free_uniffi_bindings_tests_async_test_trait_interface(reinterpret_cast<uintptr_t>(mValue));
+ mValue = reinterpret_cast<void *>(0);
+ } else if (!mLoweredCallbackInterface && mValue != nullptr) {
+ printf("FREEING interface %p\n", mValue);
+ RustCallStatus callStatus{};
+ (uniffi_uniffi_bindings_tests_fn_free_asynctesttraitinterface)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
}
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- ~FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface() {
- ReleaseHandleIfSet();
+ ~FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-#endif /* MOZ_UNIFFI_FIXTURES */
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 https://mozilla.org/MPL/2.0/. */
+const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsComplexMethodsPointerType {
+ "uniffi_bindings_tests::ComplexMethods"_ns,
+ uniffi_uniffi_bindings_tests_fn_clone_complexmethods,
+ uniffi_uniffi_bindings_tests_fn_free_complexmethods,
+};
+class FfiValueObjectHandleUniffiBindingsTestsComplexMethods {
+ private:
+ void* mValue = nullptr;
-// Define scaffolding call classes for each combination of return/argument types
+ public:
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods() = default;
+ explicit FfiValueObjectHandleUniffiBindingsTestsComplexMethods(void* aValue) : mValue(aValue) {}
-class ScaffoldingCallHandlerUniffiContextIdFnConstructorContextidcomponentNew : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mInitContextId{};
- FfiValueInt<int64_t> mCreationTimestampS{};
- FfiValueInt<int8_t> mRunningInTestAutomation{};
- FfiValueCallbackInterfacecontext_id_ContextIdCallback mCallback{};
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods(const FfiValueObjectHandleUniffiBindingsTestsComplexMethods&) = delete;
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods& operator=(const FfiValueObjectHandleUniffiBindingsTestsComplexMethods&) = delete;
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleContextIdContextIdComponent mUniffiReturnValue{};
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods& operator=(FfiValueObjectHandleUniffiBindingsTestsComplexMethods&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ aOther.mValue = nullptr;
+ return *this;
+ }
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 4) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_constructor_contextidcomponent_new (expected: 4, actual: %zu)", aArgs.Length()));
- return;
- }
- mInitContextId.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mCreationTimestampS.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mRunningInTestAutomation.Lower(aArgs[2], aError);
- if (aError.Failed()) {
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- mCallback.Lower(aArgs[3], aError);
- if (aError.Failed()) {
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kUniffiBindingsTestsComplexMethodsPointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
+ FreeHandle();
+ mValue = value.ClonePtr();
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleContextIdContextIdComponent::FromRust(
- uniffi_context_id_fn_constructor_contextidcomponent_new(
- mInitContextId.IntoRust(),
- mCreationTimestampS.IntoRust(),
- mRunningInTestAutomation.IntoRust(),
- mCallback.IntoRust(),
- aOutStatus
- )
- );
+ // LowerReceiver is used for method receivers. For non-trait interfaces, it works exactly the
+ // same as `Lower`
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ Lower(aValue, aError);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsComplexMethodsPointerType);
+ mValue = nullptr;
}
-};
-class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentForceRotation : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
- // MakeRustCall stores the result of the call in these fields
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ return temp;
+ }
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_force_rotation (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
+ static FfiValueObjectHandleUniffiBindingsTestsComplexMethods FromRust(void* aValue) {
+ return FfiValueObjectHandleUniffiBindingsTestsComplexMethods(aValue);
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_context_id_fn_method_contextidcomponent_force_rotation(
- mUniffiPtr.IntoRust(),
- aOutStatus
- );
+ void FreeHandle() {
+ if (mValue) {
+ RustCallStatus callStatus{};
+ (uniffi_uniffi_bindings_tests_fn_free_complexmethods)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
+ }
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ ~FfiValueObjectHandleUniffiBindingsTestsComplexMethods() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentRequest : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
- FfiValueInt<uint8_t> mRotationDaysInS{};
+const static mozilla::uniffi::UniFFIPointerType kUniffiBindingsTestsTestTraitInterfacePointerType {
+ "uniffi_bindings_tests::TestTraitInterface"_ns,
+ uniffi_uniffi_bindings_tests_fn_clone_testtraitinterface,
+ uniffi_uniffi_bindings_tests_fn_free_testtraitinterface,
+};
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_uniffi_bindings_tests_test_trait_interface(uint64_t uniffiHandle);
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+// Trait interface FFI value class. This is a hybrid between the one for interfaces and callback
+// interface version
+class FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface {
+ private:
+ // Did we lower a callback interface, rather than lift an object interface?
+ // This is weird, but it's a needed work until something like
+ // https://github.com/mozilla/uniffi-rs/pull/1823 lands.
+ bool mLoweredCallbackInterface = false;
+ // The raw FFI value is a pointer.
+ // For callback interfaces, the uint64_t handle gets casted to a pointer. Callback interface
+ // handles are incremented by one at a time, so even on a 32-bit system this
+ // shouldn't overflow.
+ void* mValue = nullptr;
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_request (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ public:
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface() = default;
+ explicit FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(void* aValue) : mValue(aValue) {}
+
+ // Delete copy constructor and assignment as this type is non-copyable.
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(const FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&) = delete;
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface& operator=(const FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&) = delete;
+
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface& operator=(FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface&& aOther) {
+ FreeHandle();
+ mValue = aOther.mValue;
+ mLoweredCallbackInterface = aOther.mLoweredCallbackInterface;
+ aOther.mValue = nullptr;
+ aOther.mLoweredCallbackInterface = false;
+ return *this;
+ }
+
+ // Lower treats `aValue` as a callback interface
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mRotationDaysInS.Lower(aArgs[1], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ FreeHandle();
+ mValue = reinterpret_cast<void *>(intValue);
+ mLoweredCallbackInterface = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_context_id_fn_method_contextidcomponent_request(
- mUniffiPtr.IntoRust(),
- mRotationDaysInS.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
- }
-};
-class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentUnsetCallback : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
-
- // MakeRustCall stores the result of the call in these fields
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_unset_callback (expected: 1, actual: %zu)", aArgs.Length()));
+ // LowerReceiver is used for method receivers. It treats `aValue` as an object pointer.
+ void LowerReciever(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsUniFFIPointer()) {
+ aError.ThrowTypeError("Expected UniFFI pointer argument"_ns);
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ dom::UniFFIPointer& value = aValue.GetAsUniFFIPointer();
+ if (!value.IsSamePtrType(&kUniffiBindingsTestsTestTraitInterfacePointerType)) {
+ aError.ThrowTypeError("Incorrect UniFFI pointer type"_ns);
return;
}
+ FreeHandle();
+ mValue = value.ClonePtr();
+ mLoweredCallbackInterface = false;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_context_id_fn_method_contextidcomponent_unset_callback(
- mUniffiPtr.IntoRust(),
- aOutStatus
- );
+ // Lift treats `aDest` as a regular interface
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsUniFFIPointer() =
+ dom::UniFFIPointer::Create(mValue, &kUniffiBindingsTestsTestTraitInterfacePointerType);
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void* IntoRust() {
+ auto temp = mValue;
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
+ return temp;
}
-};
-class ScaffoldingCallHandlerUniffiFilterAdultFnConstructorFilteradultcomponentNew : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleFilterAdultFilterAdultComponent mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ static FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface FromRust(void* aValue) {
+ return FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface(aValue);
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleFilterAdultFilterAdultComponent::FromRust(
- uniffi_filter_adult_fn_constructor_filteradultcomponent_new(
- aOutStatus
- )
- );
+ void FreeHandle() {
+ // This behavior depends on if we lowered a callback interface handle or lifted an interface
+ // pointer.
+ if (mLoweredCallbackInterface && reinterpret_cast<uintptr_t>(mValue) != 0) {
+ printf("FREEING CB %p\n", mValue);
+ callback_free_uniffi_bindings_tests_test_trait_interface(reinterpret_cast<uintptr_t>(mValue));
+ mValue = reinterpret_cast<void *>(0);
+ } else if (!mLoweredCallbackInterface && mValue != nullptr) {
+ printf("FREEING interface %p\n", mValue);
+ RustCallStatus callStatus{};
+ (uniffi_uniffi_bindings_tests_fn_free_testtraitinterface)(mValue, &callStatus);
+ // No need to check `RustCallStatus`, it's only part of the API to match
+ // other FFI calls. The free function can never fail.
+ }
+ mValue = nullptr;
+ mLoweredCallbackInterface = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ ~FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface() {
+ // If the pointer is non-null, this means Lift/IntoRust was never called
+ // because there was some failure along the way. Free the pointer to avoid a
+ // leak
+ FreeHandle();
}
};
-class ScaffoldingCallHandlerUniffiFilterAdultFnMethodFilteradultcomponentContains : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleFilterAdultFilterAdultComponent mUniffiPtr{};
- FfiValueRustBuffer mBaseDomainToCheck{};
+#endif /* MOZ_UNIFFI_FIXTURES */
- // MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+Maybe<already_AddRefed<UniFFIPointer>> ReadPointer(const GlobalObject& aGlobal, uint64_t aId, const ArrayBuffer& aArrayBuff, long aPosition, ErrorResult& aError) {
+ const UniFFIPointerType* type;
+ switch (aId) {
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_filter_adult_fn_method_filteradultcomponent_contains (expected: 2, actual: %zu)", aArgs.Length()));
- return;
+ case 1: {
+ type = &kContextIdContextIdComponentPointerType;
+ break;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 2: {
+ type = &kFilterAdultFilterAdultComponentPointerType;
+ break;
}
- mBaseDomainToCheck.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 3: {
+ type = &kLoginsEncryptorDecryptorPointerType;
+ break;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_filter_adult_fn_method_filteradultcomponent_contains(
- mUniffiPtr.IntoRust(),
- mBaseDomainToCheck.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnFuncScore : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mInterestVector{};
- FfiValueRustBuffer mContentCategories{};
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueFloat<double> mUniffiReturnValue{};
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_func_score (expected: 2, actual: %zu)", aArgs.Length()));
- return;
+ case 4: {
+ type = &kLoginsKeyManagerPointerType;
+ break;
}
- mInterestVector.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 5: {
+ type = &kLoginsLoginStorePointerType;
+ break;
}
- mContentCategories.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 6: {
+ type = &kLoginsManagedEncryptorDecryptorPointerType;
+ break;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<double>::FromRust(
- uniffi_relevancy_fn_func_score(
- mInterestVector.IntoRust(),
- mContentCategories.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnConstructorRelevancystoreNew : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mDbPath{};
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRemoteSettings{};
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiReturnValue{};
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_constructor_relevancystore_new (expected: 2, actual: %zu)", aArgs.Length()));
- return;
+ case 7: {
+ type = &kLoginsNssKeyManagerPointerType;
+ break;
}
- mDbPath.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 8: {
+ type = &kLoginsPrimaryPasswordAuthenticatorPointerType;
+ break;
}
- mRemoteSettings.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 9: {
+ type = &kLoginsStaticKeyManagerPointerType;
+ break;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleRelevancyRelevancyStore::FromRust(
- uniffi_relevancy_fn_constructor_relevancystore_new(
- mDbPath.IntoRust(),
- mRemoteSettings.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditInit : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- FfiValueRustBuffer mBandit{};
- FfiValueRustBuffer mArms{};
-
- // MakeRustCall stores the result of the call in these fields
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_init (expected: 3, actual: %zu)", aArgs.Length()));
- return;
+ case 10: {
+ type = &kRelevancyRelevancyStorePointerType;
+ break;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 11: {
+ type = &kRemoteSettingsRemoteSettingsPointerType;
+ break;
}
- mBandit.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 12: {
+ type = &kRemoteSettingsRemoteSettingsClientPointerType;
+ break;
}
- mArms.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
+ case 13: {
+ type = &kRemoteSettingsRemoteSettingsServicePointerType;
+ break;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_relevancy_fn_method_relevancystore_bandit_init(
- mUniffiPtr.IntoRust(),
- mBandit.IntoRust(),
- mArms.IntoRust(),
- aOutStatus
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditSelect : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- FfiValueRustBuffer mBandit{};
- FfiValueRustBuffer mArms{};
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_select (expected: 3, actual: %zu)", aArgs.Length()));
- return;
+ case 14: {
+ type = &kSearchSearchEngineSelectorPointerType;
+ break;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 15: {
+ type = &kSuggestSuggestStorePointerType;
+ break;
}
- mBandit.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 16: {
+ type = &kSuggestSuggestStoreBuilderPointerType;
+ break;
}
- mArms.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
+ case 17: {
+ type = &kTabsRemoteCommandStorePointerType;
+ break;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_relevancy_fn_method_relevancystore_bandit_select(
- mUniffiPtr.IntoRust(),
- mBandit.IntoRust(),
- mArms.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditUpdate : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- FfiValueRustBuffer mBandit{};
- FfiValueRustBuffer mArm{};
- FfiValueInt<int8_t> mSelected{};
-
- // MakeRustCall stores the result of the call in these fields
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 4) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_update (expected: 4, actual: %zu)", aArgs.Length()));
- return;
+ case 18: {
+ type = &kTabsTabsBridgedEnginePointerType;
+ break;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 19: {
+ type = &kTabsTabsStorePointerType;
+ break;
}
- mBandit.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
+ case 20: {
+ type = &kViaductBackendPointerType;
+ break;
}
- mArm.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
+ case 21: {
+ type = &kWebextstorageWebExtStorageBridgedEnginePointerType;
+ break;
}
- mSelected.Lower(aArgs[3], aError);
- if (aError.Failed()) {
- return;
+ case 22: {
+ type = &kWebextstorageWebExtStorageStorePointerType;
+ break;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_relevancy_fn_method_relevancystore_bandit_update(
- mUniffiPtr.IntoRust(),
- mBandit.IntoRust(),
- mArm.IntoRust(),
- mSelected.IntoRust(),
- aOutStatus
- );
+#ifdef MOZ_UNIFFI_FIXTURES
+ case 23: {
+ type = &kUniffiBindingsTestsTestInterfacePointerType;
+ break;
+ }
+ case 24: {
+ type = &kUniffiBindingsTestsAsyncInterfacePointerType;
+ break;
+ }
+ case 25: {
+ type = &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType;
+ break;
+ }
+ case 26: {
+ type = &kUniffiBindingsTestsComplexMethodsPointerType;
+ break;
+ }
+ case 27: {
+ type = &kUniffiBindingsTestsTestTraitInterfacePointerType;
+ break;
+ }
+#endif /* MOZ_UNIFFI_FIXTURES */
+ default:
+ return Nothing();
}
+ return Some(UniFFIPointer::Read(aArrayBuff, aPosition, type, aError));
+}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreClose : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+bool WritePointer(const GlobalObject& aGlobal, uint64_t aId, const UniFFIPointer& aPtr, const ArrayBuffer& aArrayBuff, long aPosition, ErrorResult& aError) {
+ const UniFFIPointerType* type;
+ switch (aId) {
- // MakeRustCall stores the result of the call in these fields
+ case 1: {
+ type = &kContextIdContextIdComponentPointerType;
+ break;
+ }
+ case 2: {
+ type = &kFilterAdultFilterAdultComponentPointerType;
+ break;
+ }
+ case 3: {
+ type = &kLoginsEncryptorDecryptorPointerType;
+ break;
+ }
+ case 4: {
+ type = &kLoginsKeyManagerPointerType;
+ break;
+ }
+ case 5: {
+ type = &kLoginsLoginStorePointerType;
+ break;
+ }
+ case 6: {
+ type = &kLoginsManagedEncryptorDecryptorPointerType;
+ break;
+ }
+ case 7: {
+ type = &kLoginsNssKeyManagerPointerType;
+ break;
+ }
+ case 8: {
+ type = &kLoginsPrimaryPasswordAuthenticatorPointerType;
+ break;
+ }
+ case 9: {
+ type = &kLoginsStaticKeyManagerPointerType;
+ break;
+ }
+ case 10: {
+ type = &kRelevancyRelevancyStorePointerType;
+ break;
+ }
+ case 11: {
+ type = &kRemoteSettingsRemoteSettingsPointerType;
+ break;
+ }
+ case 12: {
+ type = &kRemoteSettingsRemoteSettingsClientPointerType;
+ break;
+ }
+ case 13: {
+ type = &kRemoteSettingsRemoteSettingsServicePointerType;
+ break;
+ }
+ case 14: {
+ type = &kSearchSearchEngineSelectorPointerType;
+ break;
+ }
+ case 15: {
+ type = &kSuggestSuggestStorePointerType;
+ break;
+ }
+ case 16: {
+ type = &kSuggestSuggestStoreBuilderPointerType;
+ break;
+ }
+ case 17: {
+ type = &kTabsRemoteCommandStorePointerType;
+ break;
+ }
+ case 18: {
+ type = &kTabsTabsBridgedEnginePointerType;
+ break;
+ }
+ case 19: {
+ type = &kTabsTabsStorePointerType;
+ break;
+ }
+ case 20: {
+ type = &kViaductBackendPointerType;
+ break;
+ }
+ case 21: {
+ type = &kWebextstorageWebExtStorageBridgedEnginePointerType;
+ break;
+ }
+ case 22: {
+ type = &kWebextstorageWebExtStorageStorePointerType;
+ break;
+ }
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_close (expected: 1, actual: %zu)", aArgs.Length()));
- return;
+#ifdef MOZ_UNIFFI_FIXTURES
+ case 23: {
+ type = &kUniffiBindingsTestsTestInterfacePointerType;
+ break;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ case 24: {
+ type = &kUniffiBindingsTestsAsyncInterfacePointerType;
+ break;
+ }
+ case 25: {
+ type = &kUniffiBindingsTestsAsyncTestTraitInterfacePointerType;
+ break;
+ }
+ case 26: {
+ type = &kUniffiBindingsTestsComplexMethodsPointerType;
+ break;
+ }
+ case 27: {
+ type = &kUniffiBindingsTestsTestTraitInterfacePointerType;
+ break;
}
+#endif /* MOZ_UNIFFI_FIXTURES */
+ default:
+ return false;
}
+ aPtr.Write(aArrayBuff, aPosition, type, aError);
+ return true;
+}
+/* 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 https://mozilla.org/MPL/2.0/. */
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_relevancy_fn_method_relevancystore_close(
- mUniffiPtr.IntoRust(),
- aOutStatus
- );
- }
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreEnsureInterestDataPopulated : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+// Callback interface FfiValueClasses
+//
+// These need to come first so they're defined for the scaffolding call code
- // MakeRustCall stores the result of the call in these fields
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated (expected: 1, actual: %zu)", aArgs.Length()));
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_context_id_context_id_callback(uint64_t uniffiHandle);
+
+// FfiValue class for these callback interface handles. This works like the
+// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
+class FfiValueCallbackInterfacecontext_id_ContextIdCallback {
+ private:
+ // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
+ // it up if we don't pass it to Rust because other values failed to lower
+ bool mLowered = false;
+ uint64_t mValue = 0;
+
+ public:
+ FfiValueCallbackInterfacecontext_id_ContextIdCallback() = default;
+ explicit FfiValueCallbackInterfacecontext_id_ContextIdCallback(uint64_t aValue) : mValue(aValue) {}
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ ReleaseHandleIfSet();
+ mValue = intValue;
+ mLowered = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated(
- mUniffiPtr.IntoRust(),
- aOutStatus
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsDouble() = mValue;
+ mValue = 0;
+ mLowered = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ uint64_t IntoRust() {
+ auto handle = mValue;
+ mValue = 0;
+ mLowered = false;
+ return handle;
}
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreGetBanditData : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- FfiValueRustBuffer mBandit{};
- FfiValueRustBuffer mArm{};
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ static FfiValueCallbackInterfacecontext_id_ContextIdCallback FromRust(uint64_t aValue) { return FfiValueCallbackInterfacecontext_id_ContextIdCallback(aValue); };
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_get_bandit_data (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mBandit.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mArm.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
+ void ReleaseHandleIfSet() {
+ // A non-zero value indicates that we own a callback handle that was never passed to Rust or
+ // lifted to JS and needs to be freed.
+ if (mValue != 0 && mLowered) {
+ callback_free_context_id_context_id_callback(mValue);
+ mValue = 0;
+ mLowered = false;
}
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_relevancy_fn_method_relevancystore_get_bandit_data(
- mUniffiPtr.IntoRust(),
- mBandit.IntoRust(),
- mArm.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ ~FfiValueCallbackInterfacecontext_id_ContextIdCallback() {
+ ReleaseHandleIfSet();
}
};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreIngest : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- FfiValueRustBuffer mTopUrlsByFrecency{};
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_tracing_event_sink(uint64_t uniffiHandle);
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_ingest (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+// FfiValue class for these callback interface handles. This works like the
+// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
+class FfiValueCallbackInterfacetracing_EventSink {
+ private:
+ // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
+ // it up if we don't pass it to Rust because other values failed to lower
+ bool mLowered = false;
+ uint64_t mValue = 0;
+
+ public:
+ FfiValueCallbackInterfacetracing_EventSink() = default;
+ explicit FfiValueCallbackInterfacetracing_EventSink(uint64_t aValue) : mValue(aValue) {}
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mTopUrlsByFrecency.Lower(aArgs[1], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ ReleaseHandleIfSet();
+ mValue = intValue;
+ mLowered = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_relevancy_fn_method_relevancystore_ingest(
- mUniffiPtr.IntoRust(),
- mTopUrlsByFrecency.IntoRust(),
- aOutStatus
- )
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsDouble() = mValue;
+ mValue = 0;
+ mLowered = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ uint64_t IntoRust() {
+ auto handle = mValue;
+ mValue = 0;
+ mLowered = false;
+ return handle;
}
-};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreInterrupt : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- // MakeRustCall stores the result of the call in these fields
+ static FfiValueCallbackInterfacetracing_EventSink FromRust(uint64_t aValue) { return FfiValueCallbackInterfacetracing_EventSink(aValue); };
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_interrupt (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ void ReleaseHandleIfSet() {
+ // A non-zero value indicates that we own a callback handle that was never passed to Rust or
+ // lifted to JS and needs to be freed.
+ if (mValue != 0 && mLowered) {
+ callback_free_tracing_event_sink(mValue);
+ mValue = 0;
+ mLowered = false;
}
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_relevancy_fn_method_relevancystore_interrupt(
- mUniffiPtr.IntoRust(),
- aOutStatus
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ ~FfiValueCallbackInterfacetracing_EventSink() {
+ ReleaseHandleIfSet();
}
};
-class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreUserInterestVector : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+#ifdef MOZ_UNIFFI_FIXTURES
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_user_interest_vector (expected: 1, actual: %zu)", aArgs.Length()));
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_uniffi_bindings_tests_test_async_callback_interface(uint64_t uniffiHandle);
+
+// FfiValue class for these callback interface handles. This works like the
+// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
+class FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface {
+ private:
+ // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
+ // it up if we don't pass it to Rust because other values failed to lower
+ bool mLowered = false;
+ uint64_t mValue = 0;
+
+ public:
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface() = default;
+ explicit FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ ReleaseHandleIfSet();
+ mValue = intValue;
+ mLowered = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_relevancy_fn_method_relevancystore_user_interest_vector(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsDouble() = mValue;
+ mValue = 0;
+ mLowered = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ uint64_t IntoRust() {
+ auto handle = mValue;
+ mValue = 0;
+ mLowered = false;
+ return handle;
}
-};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsNew : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mRemoteSettingsConfig{};
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiReturnValue{};
+ static FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface(aValue); };
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_constructor_remotesettings_new (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mRemoteSettingsConfig.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
+ void ReleaseHandleIfSet() {
+ // A non-zero value indicates that we own a callback handle that was never passed to Rust or
+ // lifted to JS and needs to be freed.
+ if (mValue != 0 && mLowered) {
+ callback_free_uniffi_bindings_tests_test_async_callback_interface(mValue);
+ mValue = 0;
+ mLowered = false;
}
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettings::FromRust(
- uniffi_remote_settings_fn_constructor_remotesettings_new(
- mRemoteSettingsConfig.IntoRust(),
- aOutStatus
- )
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ ~FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface() {
+ ReleaseHandleIfSet();
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsDownloadAttachmentToPath : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
- FfiValueRustBuffer mAttachmentId{};
- FfiValueRustBuffer mPath{};
- // MakeRustCall stores the result of the call in these fields
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_uniffi_bindings_tests_test_callback_interface(uint64_t uniffiHandle);
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mAttachmentId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
+// FfiValue class for these callback interface handles. This works like the
+// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
+class FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface {
+ private:
+ // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
+ // it up if we don't pass it to Rust because other values failed to lower
+ bool mLowered = false;
+ uint64_t mValue = 0;
+
+ public:
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface() = default;
+ explicit FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mPath.Lower(aArgs[2], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ ReleaseHandleIfSet();
+ mValue = intValue;
+ mLowered = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path(
- mUniffiPtr.IntoRust(),
- mAttachmentId.IntoRust(),
- mPath.IntoRust(),
- aOutStatus
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsDouble() = mValue;
+ mValue = 0;
+ mLowered = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ uint64_t IntoRust() {
+ auto handle = mValue;
+ mValue = 0;
+ mLowered = false;
+ return handle;
+ }
+
+ static FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface(aValue); };
+
+ void ReleaseHandleIfSet() {
+ // A non-zero value indicates that we own a callback handle that was never passed to Rust or
+ // lifted to JS and needs to be freed.
+ if (mValue != 0 && mLowered) {
+ callback_free_uniffi_bindings_tests_test_callback_interface(mValue);
+ mValue = 0;
+ mLowered = false;
+ }
+ }
+
+ ~FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface() {
+ ReleaseHandleIfSet();
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecords : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+// Forward declare the free function, which is defined later on in `CallbackInterfaces.cpp`
+extern "C" void callback_free_uniffi_bindings_tests_collision_test_callback_interface(uint64_t uniffiHandle);
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_get_records (expected: 1, actual: %zu)", aArgs.Length()));
+// FfiValue class for these callback interface handles. This works like the
+// `FfiValueInt<uint64_t>`, except it has extra code to cleanup the callback handles.
+class FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface {
+ private:
+ // Was this value lowered? If so, that means we own the handle and are responsible for cleaning
+ // it up if we don't pass it to Rust because other values failed to lower
+ bool mLowered = false;
+ uint64_t mValue = 0;
+
+ public:
+ FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface() = default;
+ explicit FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface(uint64_t aValue) : mValue(aValue) {}
+
+ void Lower(const dom::OwningUniFFIScaffoldingValue& aValue,
+ ErrorResult& aError) {
+ if (!aValue.IsDouble()) {
+ aError.ThrowTypeError("Bad argument type"_ns);
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ double floatValue = aValue.GetAsDouble();
+
+ uint64_t intValue = static_cast<uint64_t>(floatValue);
+ if (intValue != floatValue) {
+ aError.ThrowTypeError("Not an integer"_ns);
return;
}
+ ReleaseHandleIfSet();
+ mValue = intValue;
+ mLowered = true;
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettings_get_records(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
- );
+ void Lift(JSContext* aContext, dom::OwningUniFFIScaffoldingValue* aDest,
+ ErrorResult& aError) {
+ aDest->SetAsDouble() = mValue;
+ mValue = 0;
+ mLowered = false;
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ uint64_t IntoRust() {
+ auto handle = mValue;
+ mValue = 0;
+ mLowered = false;
+ return handle;
+ }
+
+ static FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface FromRust(uint64_t aValue) { return FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface(aValue); };
+
+ void ReleaseHandleIfSet() {
+ // A non-zero value indicates that we own a callback handle that was never passed to Rust or
+ // lifted to JS and needs to be freed.
+ if (mValue != 0 && mLowered) {
+ callback_free_uniffi_bindings_tests_collision_test_callback_interface(mValue);
+ mValue = 0;
+ mLowered = false;
+ }
+ }
+
+ ~FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface() {
+ ReleaseHandleIfSet();
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecordsSince : public UniffiSyncCallHandler {
+#endif /* MOZ_UNIFFI_FIXTURES */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+// Define scaffolding call classes for each combination of return/argument types
+
+class ScaffoldingCallHandlerUniffiContextIdFnConstructorContextidcomponentNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
- FfiValueInt<uint64_t> mTimestamp{};
+ FfiValueRustBuffer mInitContextId{};
+ FfiValueInt<int64_t> mCreationTimestampS{};
+ FfiValueInt<int8_t> mRunningInTestAutomation{};
+ FfiValueCallbackInterfacecontext_id_ContextIdCallback mCallback{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleContextIdContextIdComponent mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_get_records_since (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 4) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_constructor_contextidcomponent_new (expected: 4, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mInitContextId.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mTimestamp.Lower(aArgs[1], aError);
+ mCreationTimestampS.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mRunningInTestAutomation.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mCallback.Lower(aArgs[3], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettings_get_records_since(
- mUniffiPtr.IntoRust(),
- mTimestamp.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleContextIdContextIdComponent::FromRust(
+ uniffi_context_id_fn_constructor_contextidcomponent_new(
+ mInitContextId.IntoRust(),
+ mCreationTimestampS.IntoRust(),
+ mRunningInTestAutomation.IntoRust(),
+ mCallback.IntoRust(),
aOutStatus
)
);
@@ -4523,18 +4729,17 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientCollectionName : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentForceRotation : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_collection_name (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_force_rotation (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -4544,27 +4749,20 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsclient_collection_name(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ uniffi_context_id_fn_method_contextidcomponent_force_rotation(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetAttachment : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentRequest : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
- FfiValueRustBuffer mRecord{};
+ FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
+ FfiValueInt<uint8_t> mRotationDaysInS{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -4572,14 +4770,14 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_request (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mRecord.Lower(aArgs[1], aError);
+ mRotationDaysInS.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -4587,9 +4785,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment(
+ uniffi_context_id_fn_method_contextidcomponent_request(
mUniffiPtr.IntoRust(),
- mRecord.IntoRust(),
+ mRotationDaysInS.IntoRust(),
aOutStatus
)
);
@@ -4603,79 +4801,92 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecords : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentUnsetCallback : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
- FfiValueInt<int8_t> mSyncIfEmpty{};
+ FfiValueObjectHandleContextIdContextIdComponent mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_records (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_context_id_fn_method_contextidcomponent_unset_callback (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSyncIfEmpty.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsclient_get_records(
- mUniffiPtr.IntoRust(),
- mSyncIfEmpty.IntoRust(),
- aOutStatus
- )
+ uniffi_context_id_fn_method_contextidcomponent_unset_callback(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecordsMap : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiFilterAdultFnConstructorFilteradultcomponentNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
- FfiValueInt<int8_t> mSyncIfEmpty{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleFilterAdultFilterAdultComponent mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleFilterAdultFilterAdultComponent::FromRust(
+ uniffi_filter_adult_fn_constructor_filteradultcomponent_new(
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiFilterAdultFnMethodFilteradultcomponentContains : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleFilterAdultFilterAdultComponent mUniffiPtr{};
+ FfiValueRustBuffer mBaseDomainToCheck{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_filter_adult_fn_method_filteradultcomponent_contains (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSyncIfEmpty.Lower(aArgs[1], aError);
+ mBaseDomainToCheck.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_filter_adult_fn_method_filteradultcomponent_contains(
mUniffiPtr.IntoRust(),
- mSyncIfEmpty.IntoRust(),
+ mBaseDomainToCheck.IntoRust(),
aOutStatus
)
);
@@ -4689,28 +4900,24 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientShutdown : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiInitRustComponentsFnFuncInitialize : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueRustBuffer mProfilePath{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_shutdown (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mProfilePath.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_remote_settings_fn_method_remotesettingsclient_shutdown(
- mUniffiPtr.IntoRust(),
+ uniffi_init_rust_components_fn_func_initialize(
+ mProfilePath.IntoRust(),
aOutStatus
);
}
@@ -4718,65 +4925,77 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCheckCanary : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueRustBuffer mCanary{};
+ FfiValueRustBuffer mText{};
+ FfiValueRustBuffer mEncryptionKey{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_sync (expected: 1, actual: %zu)", aArgs.Length()));
+ mCanary.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mText.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mEncryptionKey.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_remote_settings_fn_method_remotesettingsclient_sync(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_logins_fn_func_check_canary(
+ mCanary.IntoRust(),
+ mText.IntoRust(),
+ mEncryptionKey.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsserviceNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateCanary : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mStorageDir{};
- FfiValueRustBuffer mConfig{};
+ FfiValueRustBuffer mText{};
+ FfiValueRustBuffer mEncryptionKey{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_constructor_remotesettingsservice_new (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mStorageDir.Lower(aArgs[0], aError);
+ mText.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mConfig.Lower(aArgs[1], aError);
+ mEncryptionKey.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettingsService::FromRust(
- uniffi_remote_settings_fn_constructor_remotesettingsservice_new(
- mStorageDir.IntoRust(),
- mConfig.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_func_create_canary(
+ mText.IntoRust(),
+ mEncryptionKey.IntoRust(),
aOutStatus
)
);
@@ -4790,36 +5009,20 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceMakeClient : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateKey : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
- FfiValueRustBuffer mCollectionName{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_make_client (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mCollectionName.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettingsClient::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsservice_make_client(
- mUniffiPtr.IntoRust(),
- mCollectionName.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_func_create_key(
aOutStatus
)
);
@@ -4833,30 +5036,32 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateLoginStoreWithNssKeymanager : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
+ FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator mPrimaryPasswordAuthenticator{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_sync (expected: 1, actual: %zu)", aArgs.Length()));
+ mPath.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mPrimaryPasswordAuthenticator.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_remote_settings_fn_method_remotesettingsservice_sync(
- mUniffiPtr.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleLoginsLoginStore::FromRust(
+ uniffi_logins_fn_func_create_login_store_with_nss_keymanager(
+ mPath.IntoRust(),
+ mPrimaryPasswordAuthenticator.IntoRust(),
aOutStatus
)
);
@@ -4870,55 +5075,65 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceUpdateConfig : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateLoginStoreWithStaticKeyManager : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
- FfiValueRustBuffer mConfig{};
+ FfiValueRustBuffer mPath{};
+ FfiValueRustBuffer mKey{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleLoginsLoginStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_update_config (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mPath.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mConfig.Lower(aArgs[1], aError);
+ mKey.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_remote_settings_fn_method_remotesettingsservice_update_config(
- mUniffiPtr.IntoRust(),
- mConfig.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleLoginsLoginStore::FromRust(
+ uniffi_logins_fn_func_create_login_store_with_static_key_manager(
+ mPath.IntoRust(),
+ mKey.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateManagedEncdec : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleLoginsKeyManager mKeyManager{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiReturnValue{};
+ FfiValueObjectHandleLoginsEncryptorDecryptor mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ mKeyManager.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSearchSearchEngineSelector::FromRust(
- uniffi_search_fn_constructor_searchengineselector_new(
+ mUniffiReturnValue = FfiValueObjectHandleLoginsEncryptorDecryptor::FromRust(
+ uniffi_logins_fn_func_create_managed_encdec(
+ mKeyManager.IntoRust(),
aOutStatus
)
);
@@ -4932,55 +5147,55 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorClearSearchConfig : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnFuncCreateStaticKeyManager : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
+ FfiValueRustBuffer mKey{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleLoginsKeyManager mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_clear_search_config (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mKey.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_search_fn_method_searchengineselector_clear_search_config(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleLoginsKeyManager::FromRust(
+ uniffi_logins_fn_func_create_static_key_manager(
+ mKey.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorFilterEngineConfiguration : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodEncryptordecryptorDecrypt : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
- FfiValueRustBuffer mUserEnvironment{};
+ FfiValueObjectHandleLoginsEncryptorDecryptor mUniffiPtr{};
+ FfiValueRustBuffer mCiphertext{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_filter_engine_configuration (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mUserEnvironment.Lower(aArgs[1], aError);
+ mCiphertext.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -4988,9 +5203,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_search_fn_method_searchengineselector_filter_engine_configuration(
+ uniffi_logins_fn_method_encryptordecryptor_decrypt(
mUniffiPtr.IntoRust(),
- mUserEnvironment.IntoRust(),
+ mCiphertext.IntoRust(),
aOutStatus
)
);
@@ -5004,147 +5219,143 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodEncryptordecryptorEncrypt : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
- FfiValueRustBuffer mOverrides{};
+ FfiValueObjectHandleLoginsEncryptorDecryptor mUniffiPtr{};
+ FfiValueRustBuffer mCleartext{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_set_config_overrides (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mOverrides.Lower(aArgs[1], aError);
+ mCleartext.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_search_fn_method_searchengineselector_set_config_overrides(
- mUniffiPtr.IntoRust(),
- mOverrides.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_encryptordecryptor_encrypt(
+ mUniffiPtr.IntoRust(),
+ mCleartext.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodKeymanagerGetKey : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
- FfiValueRustBuffer mConfiguration{};
+ FfiValueObjectHandleLoginsKeyManager mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_set_search_config (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mConfiguration.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_search_fn_method_searchengineselector_set_search_config(
- mUniffiPtr.IntoRust(),
- mConfiguration.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_keymanager_get_key(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnConstructorLoginstoreNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mService{};
- FfiValueInt<int8_t> mApplyEngineOverrides{};
+ FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleLoginsEncryptorDecryptor mEncdec{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleLoginsLoginStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_use_remote_settings_server (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mService.Lower(aArgs[1], aError);
+ mPath.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mApplyEngineOverrides.Lower(aArgs[2], aError);
+ mEncdec.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_search_fn_method_searchengineselector_use_remote_settings_server(
- mUniffiPtr.IntoRust(),
- mService.IntoRust(),
- mApplyEngineOverrides.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleLoginsLoginStore::FromRust(
+ uniffi_logins_fn_constructor_loginstore_new(
+ mPath.IntoRust(),
+ mEncdec.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAdd : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mRawUrl{};
- FfiValueRustBuffer mCookedUrl{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mLogin{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_func_raw_suggestion_url_matches (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mRawUrl.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mCookedUrl.Lower(aArgs[1], aError);
+ mLogin.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_suggest_fn_func_raw_suggestion_url_matches(
- mRawUrl.IntoRust(),
- mCookedUrl.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_add(
+ mUniffiPtr.IntoRust(),
+ mLogin.IntoRust(),
aOutStatus
)
);
@@ -5158,36 +5369,32 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddMany : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mPath{};
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRemoteSettingsService{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mLogins{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_constructor_suggeststore_new (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mPath.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mRemoteSettingsService.Lower(aArgs[1], aError);
+ mLogins.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStore::FromRust(
- uniffi_suggest_fn_constructor_suggeststore_new(
- mPath.IntoRust(),
- mRemoteSettingsService.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_add_many(
+ mUniffiPtr.IntoRust(),
+ mLogins.IntoRust(),
aOutStatus
)
);
@@ -5201,30 +5408,32 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreAnyDismissedSuggestions : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddManyWithMeta : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mEntriesWithMeta{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions (expected: 1, actual: %zu)", aArgs.Length()));
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mEntriesWithMeta.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_add_many_with_meta(
mUniffiPtr.IntoRust(),
+ mEntriesWithMeta.IntoRust(),
aOutStatus
)
);
@@ -5238,199 +5447,221 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddOrUpdate : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mLogin{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_clear (expected: 1, actual: %zu)", aArgs.Length()));
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mLogin.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_clear(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_add_or_update(
+ mUniffiPtr.IntoRust(),
+ mLogin.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddWithMeta : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mEntryWithMeta{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions (expected: 1, actual: %zu)", aArgs.Length()));
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mEntryWithMeta.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_add_with_meta(
+ mUniffiPtr.IntoRust(),
+ mEntryWithMeta.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissByKey : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCount : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mKey{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_by_key (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mKey.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_dismiss_by_key(
- mUniffiPtr.IntoRust(),
- mKey.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_logins_fn_method_loginstore_count(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissBySuggestion : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCountByFormActionOrigin : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mSuggestion{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mFormActionOrigin{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSuggestion.Lower(aArgs[1], aError);
+ mFormActionOrigin.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion(
- mUniffiPtr.IntoRust(),
- mSuggestion.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_logins_fn_method_loginstore_count_by_form_action_origin(
+ mUniffiPtr.IntoRust(),
+ mFormActionOrigin.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCountByOrigin : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mSuggestionUrl{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mOrigin{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSuggestionUrl.Lower(aArgs[1], aError);
+ mOrigin.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_dismiss_suggestion(
- mUniffiPtr.IntoRust(),
- mSuggestionUrl.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_logins_fn_method_loginstore_count_by_origin(
+ mUniffiPtr.IntoRust(),
+ mOrigin.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonameAlternates : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDelete : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mGeoname{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mId{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mGeoname.Lower(aArgs[1], aError);
+ mId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_logins_fn_method_loginstore_delete(
mUniffiPtr.IntoRust(),
- mGeoname.IntoRust(),
+ mId.IntoRust(),
aOutStatus
)
);
@@ -5444,36 +5675,22 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDeleteMany : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mQuery{};
- FfiValueInt<int8_t> mMatchNamePrefix{};
- FfiValueRustBuffer mFilter{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mIds{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 4) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_geonames (expected: 4, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mQuery.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mMatchNamePrefix.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
- mFilter.Lower(aArgs[3], aError);
+ mIds.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -5481,11 +5698,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_fetch_geonames(
+ uniffi_logins_fn_method_loginstore_delete_many(
mUniffiPtr.IntoRust(),
- mQuery.IntoRust(),
- mMatchNamePrefix.IntoRust(),
- mFilter.IntoRust(),
+ mIds.IntoRust(),
aOutStatus
)
);
@@ -5499,20 +5714,16 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGlobalConfig : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDeleteUndecryptableRecordsForRemoteReplacement : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_global_config (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
@@ -5521,7 +5732,7 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_fetch_global_config(
+ uniffi_logins_fn_method_loginstore_delete_undecryptable_records_for_remote_replacement(
mUniffiPtr.IntoRust(),
aOutStatus
)
@@ -5536,26 +5747,22 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchProviderConfig : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreFindLoginToUpdate : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mProvider{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mLook{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_provider_config (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mProvider.Lower(aArgs[1], aError);
+ mLook.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -5563,9 +5770,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_fetch_provider_config(
+ uniffi_logins_fn_method_loginstore_find_login_to_update(
mUniffiPtr.IntoRust(),
- mProvider.IntoRust(),
+ mLook.IntoRust(),
aOutStatus
)
);
@@ -5579,26 +5786,22 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIngest : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGet : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mConstraints{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mId{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_ingest (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mConstraints.Lower(aArgs[1], aError);
+ mId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -5606,9 +5809,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_ingest(
+ uniffi_logins_fn_method_loginstore_get(
mUniffiPtr.IntoRust(),
- mConstraints.IntoRust(),
+ mId.IntoRust(),
aOutStatus
)
);
@@ -5622,71 +5825,65 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreInterrupt : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGetByBaseDomain : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mKind{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mBaseDomain{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_interrupt (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mKind.Lower(aArgs[1], aError);
+ mBaseDomain.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_suggest_fn_method_suggeststore_interrupt(
- mUniffiPtr.IntoRust(),
- mKind.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_get_by_base_domain(
+ mUniffiPtr.IntoRust(),
+ mBaseDomain.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedByKey : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGetCheckpoint : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mKey{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mKey.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_get_checkpoint(
mUniffiPtr.IntoRust(),
- mKey.IntoRust(),
aOutStatus
)
);
@@ -5700,26 +5897,22 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedBySuggestion : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreHasLoginsByBaseDomain : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mSuggestion{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mBaseDomain{};
// MakeRustCall stores the result of the call in these fields
FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSuggestion.Lower(aArgs[1], aError);
+ mBaseDomain.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -5727,9 +5920,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion(
+ uniffi_logins_fn_method_loginstore_has_logins_by_base_domain(
mUniffiPtr.IntoRust(),
- mSuggestion.IntoRust(),
+ mBaseDomain.IntoRust(),
aOutStatus
)
);
@@ -5743,36 +5936,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQuery : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreIsEmpty : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mQuery{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_query (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mQuery.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_query(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_logins_fn_method_loginstore_is_empty(
mUniffiPtr.IntoRust(),
- mQuery.IntoRust(),
aOutStatus
)
);
@@ -5786,36 +5969,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQueryWithMetrics : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreList : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
- FfiValueRustBuffer mQuery{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_query_with_metrics (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mQuery.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_suggest_fn_method_suggeststore_query_with_metrics(
+ uniffi_logins_fn_method_loginstore_list(
mUniffiPtr.IntoRust(),
- mQuery.IntoRust(),
aOutStatus
)
);
@@ -5829,47 +6002,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststorebuilderNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreRegisterWithSyncManager : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_constructor_suggeststorebuilder_new(
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_register_with_sync_manager(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderBuild : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreReset : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_build (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
@@ -5877,230 +6043,159 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStore::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_build(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_reset(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderCachePath : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreRunMaintenance : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_cache_path (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mPath.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_cache_path(
- mUniffiPtr.IntoRust(),
- mPath.IntoRust(),
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_run_maintenance(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderDataPath : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreSetCheckpoint : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mCheckpoint{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_data_path (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mPath.Lower(aArgs[1], aError);
+ mCheckpoint.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_data_path(
- mUniffiPtr.IntoRust(),
- mPath.IntoRust(),
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_set_checkpoint(
+ mUniffiPtr.IntoRust(),
+ mCheckpoint.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderLoadExtension : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreShutdown : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueRustBuffer mLibrary{};
- FfiValueRustBuffer mEntryPoint{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_load_extension (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mLibrary.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mEntryPoint.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_load_extension(
- mUniffiPtr.IntoRust(),
- mLibrary.IntoRust(),
- mEntryPoint.IntoRust(),
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_shutdown(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsBucketName : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreTouch : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueRustBuffer mBucketName{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mId{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mBucketName.Lower(aArgs[1], aError);
+ mId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name(
- mUniffiPtr.IntoRust(),
- mBucketName.IntoRust(),
- aOutStatus
- )
+ uniffi_logins_fn_method_loginstore_touch(
+ mUniffiPtr.IntoRust(),
+ mId.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsServer : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreUpdate : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueRustBuffer mServer{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
+ FfiValueRustBuffer mId{};
+ FfiValueRustBuffer mLogin{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server (expected: 2, actual: %zu)", aArgs.Length()));
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
- mServer.Lower(aArgs[1], aError);
+ mLogin.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_logins_fn_method_loginstore_update(
mUniffiPtr.IntoRust(),
- mServer.IntoRust(),
+ mId.IntoRust(),
+ mLogin.IntoRust(),
aOutStatus
)
);
@@ -6114,36 +6209,51 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsService : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreWipeLocal : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
- FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRsService{};
+ FfiValueObjectHandleLoginsLoginStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mRsService.Lower(aArgs[1], aError);
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_logins_fn_method_loginstore_wipe_local(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiLoginsFnConstructorManagedencryptordecryptorNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleLoginsKeyManager mKeyManager{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleLoginsManagedEncryptorDecryptor mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ mKeyManager.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
- uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service(
- mUniffiPtr.IntoRust(),
- mRsService.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleLoginsManagedEncryptorDecryptor::FromRust(
+ uniffi_logins_fn_constructor_managedencryptordecryptor_new(
+ mKeyManager.IntoRust(),
aOutStatus
)
);
@@ -6157,42 +6267,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommand : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnConstructorNsskeymanagerNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
- FfiValueRustBuffer mDeviceId{};
- FfiValueRustBuffer mCommand{};
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator mPrimaryPasswordAuthenticator{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueObjectHandleLoginsNssKeyManager mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_add_remote_command (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mDeviceId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mCommand.Lower(aArgs[2], aError);
+ mPrimaryPasswordAuthenticator.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_tabs_fn_method_remotecommandstore_add_remote_command(
- mUniffiPtr.IntoRust(),
- mDeviceId.IntoRust(),
- mCommand.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleLoginsNssKeyManager::FromRust(
+ uniffi_logins_fn_constructor_nsskeymanager_new(
+ mPrimaryPasswordAuthenticator.IntoRust(),
aOutStatus
)
);
@@ -6206,48 +6300,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommandAt : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiLoginsFnMethodNsskeymanagerIntoDynKeyManager : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
- FfiValueRustBuffer mDeviceId{};
- FfiValueRustBuffer mCommand{};
- FfiValueInt<int64_t> mWhen{};
+ FfiValueObjectHandleLoginsNssKeyManager mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueObjectHandleLoginsKeyManager mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 4) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at (expected: 4, actual: %zu)", aArgs.Length()));
- return;
- }
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mDeviceId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mCommand.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
- mWhen.Lower(aArgs[3], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at(
+ mUniffiReturnValue = FfiValueObjectHandleLoginsKeyManager::FromRust(
+ uniffi_logins_fn_method_nsskeymanager_into_dyn_key_manager(
mUniffiPtr.IntoRust(),
- mDeviceId.IntoRust(),
- mCommand.IntoRust(),
- mWhen.IntoRust(),
aOutStatus
)
);
@@ -6261,36 +6333,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreGetUnsentCommands : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+class ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorGetPrimaryPassword : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorGetPrimaryPassword() : UniffiAsyncCallHandler(
+ ffi_logins_rust_future_poll_rust_buffer,
+ ffi_logins_rust_future_free_rust_buffer
+ ) { }
- // MakeRustCall stores the result of the call in these fields
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
FfiValueRustBuffer mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator mUniffiPtr{};
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+
+ mFutureHandle = uniffi_logins_fn_method_primarypasswordauthenticator_get_primary_password(
+ mUniffiPtr.IntoRust()
+ );
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
- );
+ ffi_logins_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -6298,42 +6374,94 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreRemoveRemoteCommand : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
- FfiValueRustBuffer mDeviceId{};
- FfiValueRustBuffer mCommand{};
+class ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationSuccess : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationSuccess() : UniffiAsyncCallHandler(
+ ffi_logins_rust_future_poll_void,
+ ffi_logins_rust_future_free_void
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_remove_remote_command (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator mUniffiPtr{};
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mDeviceId.Lower(aArgs[1], aError);
+
+ mFutureHandle = uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_success(
+ mUniffiPtr.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_logins_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationFailure : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationFailure() : UniffiAsyncCallHandler(
+ ffi_logins_rust_future_poll_void,
+ ffi_logins_rust_future_free_void
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleLoginsPrimaryPasswordAuthenticator mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mCommand.Lower(aArgs[2], aError);
+
+ mFutureHandle = uniffi_logins_fn_method_primarypasswordauthenticator_on_authentication_failure(
+ mUniffiPtr.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_logins_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiLoginsFnConstructorStatickeymanagerNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mKey{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleLoginsStaticKeyManager mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ mKey.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_tabs_fn_method_remotecommandstore_remove_remote_command(
- mUniffiPtr.IntoRust(),
- mDeviceId.IntoRust(),
- mCommand.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleLoginsStaticKeyManager::FromRust(
+ uniffi_logins_fn_constructor_statickeymanager_new(
+ mKey.IntoRust(),
aOutStatus
)
);
@@ -6347,36 +6475,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreSetPendingCommandSent : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnFuncScore : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
- FfiValueRustBuffer mCommand{};
+ FfiValueRustBuffer mInterestVector{};
+ FfiValueRustBuffer mContentCategories{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueFloat<double> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_func_score (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mInterestVector.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mCommand.Lower(aArgs[1], aError);
+ mContentCategories.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent(
- mUniffiPtr.IntoRust(),
- mCommand.IntoRust(),
+ mUniffiReturnValue = FfiValueFloat<double>::FromRust(
+ uniffi_relevancy_fn_func_score(
+ mInterestVector.IntoRust(),
+ mContentCategories.IntoRust(),
aOutStatus
)
);
@@ -6390,30 +6518,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineApply : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnConstructorRelevancystoreNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mDbPath{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRemoteSettings{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_apply (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_constructor_relevancystore_new (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mDbPath.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mRemoteSettings.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_tabsbridgedengine_apply(
- mUniffiPtr.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleRelevancyRelevancyStore::FromRust(
+ uniffi_relevancy_fn_constructor_relevancystore_new(
+ mDbPath.IntoRust(),
+ mRemoteSettings.IntoRust(),
aOutStatus
)
);
@@ -6427,73 +6561,83 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineEnsureCurrentSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditInit : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mNewSyncId{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+ FfiValueRustBuffer mBandit{};
+ FfiValueRustBuffer mArms{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_init (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mNewSyncId.Lower(aArgs[1], aError);
+ mBandit.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mArms.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id(
- mUniffiPtr.IntoRust(),
- mNewSyncId.IntoRust(),
- aOutStatus
- )
+ uniffi_relevancy_fn_method_relevancystore_bandit_init(
+ mUniffiPtr.IntoRust(),
+ mBandit.IntoRust(),
+ mArms.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineLastSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditSelect : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+ FfiValueRustBuffer mBandit{};
+ FfiValueRustBuffer mArms{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int64_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_last_sync (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_select (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mBandit.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mArms.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
- uniffi_tabs_fn_method_tabsbridgedengine_last_sync(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_relevancy_fn_method_relevancystore_bandit_select(
mUniffiPtr.IntoRust(),
+ mBandit.IntoRust(),
+ mArms.IntoRust(),
aOutStatus
)
);
@@ -6507,63 +6651,46 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedenginePrepareForSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditUpdate : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mClientData{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+ FfiValueRustBuffer mBandit{};
+ FfiValueRustBuffer mArm{};
+ FfiValueInt<int8_t> mSelected{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 4) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_bandit_update (expected: 4, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mClientData.Lower(aArgs[1], aError);
+ mBandit.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync(
- mUniffiPtr.IntoRust(),
- mClientData.IntoRust(),
- aOutStatus
- );
- }
-
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineReset : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
-
- // MakeRustCall stores the result of the call in these fields
-
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_reset (expected: 1, actual: %zu)", aArgs.Length()));
+ mArm.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mSelected.Lower(aArgs[3], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_reset(
+ uniffi_relevancy_fn_method_relevancystore_bandit_update(
mUniffiPtr.IntoRust(),
+ mBandit.IntoRust(),
+ mArm.IntoRust(),
+ mSelected.IntoRust(),
aOutStatus
);
}
@@ -6571,18 +6698,17 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineResetSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreClose : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_close (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -6592,50 +6718,37 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ uniffi_relevancy_fn_method_relevancystore_close(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetLastSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreEnsureInterestDataPopulated : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
- FfiValueInt<int64_t> mLastSync{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mLastSync.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync(
+ uniffi_relevancy_fn_method_relevancystore_ensure_interest_data_populated(
mUniffiPtr.IntoRust(),
- mLastSync.IntoRust(),
aOutStatus
);
}
@@ -6643,93 +6756,109 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetUploaded : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreGetBanditData : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
- FfiValueInt<int64_t> mNewTimestamp{};
- FfiValueRustBuffer mUploadedIds{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+ FfiValueRustBuffer mBandit{};
+ FfiValueRustBuffer mArm{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded (expected: 3, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_get_bandit_data (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mNewTimestamp.Lower(aArgs[1], aError);
+ mBandit.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
- mUploadedIds.Lower(aArgs[2], aError);
+ mArm.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded(
- mUniffiPtr.IntoRust(),
- mNewTimestamp.IntoRust(),
- mUploadedIds.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_relevancy_fn_method_relevancystore_get_bandit_data(
+ mUniffiPtr.IntoRust(),
+ mBandit.IntoRust(),
+ mArm.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineStoreIncoming : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreIngest : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mIncomingEnvelopesAsJson{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
+ FfiValueRustBuffer mTopUrlsByFrecency{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_store_incoming (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_ingest (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mIncomingEnvelopesAsJson.Lower(aArgs[1], aError);
+ mTopUrlsByFrecency.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_store_incoming(
- mUniffiPtr.IntoRust(),
- mIncomingEnvelopesAsJson.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_relevancy_fn_method_relevancystore_ingest(
+ mUniffiPtr.IntoRust(),
+ mTopUrlsByFrecency.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncFinished : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreInterrupt : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_finished (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_interrupt (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -6739,7 +6868,7 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_sync_finished(
+ uniffi_relevancy_fn_method_relevancystore_interrupt(
mUniffiPtr.IntoRust(),
aOutStatus
);
@@ -6748,10 +6877,10 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreUserInterestVector : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleRelevancyRelevancyStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -6759,7 +6888,7 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_relevancy_fn_method_relevancystore_user_interest_vector (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -6770,7 +6899,7 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_tabsbridgedengine_sync_id(
+ uniffi_relevancy_fn_method_relevancystore_user_interest_vector(
mUniffiPtr.IntoRust(),
aOutStatus
)
@@ -6785,57 +6914,77 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncStarted : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mRemoteSettingsConfig{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_started (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_constructor_remotesettings_new (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mRemoteSettingsConfig.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_sync_started(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettings::FromRust(
+ uniffi_remote_settings_fn_constructor_remotesettings_new(
+ mRemoteSettingsConfig.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineWipe : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsDownloadAttachmentToPath : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
+ FfiValueRustBuffer mAttachmentId{};
+ FfiValueRustBuffer mPath{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_wipe (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mAttachmentId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mPath.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsbridgedengine_wipe(
+ uniffi_remote_settings_fn_method_remotesettings_download_attachment_to_path(
mUniffiPtr.IntoRust(),
+ mAttachmentId.IntoRust(),
+ mPath.IntoRust(),
aOutStatus
);
}
@@ -6843,30 +6992,30 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiTabsFnConstructorTabsstoreNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecords : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_constructor_tabsstore_new (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_get_records (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mPath.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleTabsTabsStore::FromRust(
- uniffi_tabs_fn_constructor_tabsstore_new(
- mPath.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettings_get_records(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -6880,30 +7029,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreBridgedEngine : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecordsSince : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettings mUniffiPtr{};
+ FfiValueInt<uint64_t> mTimestamp{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleTabsTabsBridgedEngine mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_bridged_engine (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettings_get_records_since (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mTimestamp.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleTabsTabsBridgedEngine::FromRust(
- uniffi_tabs_fn_method_tabsstore_bridged_engine(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettings_get_records_since(
mUniffiPtr.IntoRust(),
+ mTimestamp.IntoRust(),
aOutStatus
)
);
@@ -6917,17 +7072,18 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreCloseConnection : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientCollectionName : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_close_connection (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_collection_name (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -6937,39 +7093,52 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsstore_close_connection(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettingsclient_collection_name(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreGetAll : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetAttachment : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueRustBuffer mRecord{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_get_all (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mRecord.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_tabs_fn_method_tabsstore_get_all(
+ uniffi_remote_settings_fn_method_remotesettingsclient_get_attachment(
mUniffiPtr.IntoRust(),
+ mRecord.IntoRust(),
aOutStatus
)
);
@@ -6983,30 +7152,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreNewRemoteCommandStore : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecords : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueInt<int8_t> mSyncIfEmpty{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleTabsRemoteCommandStore mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_new_remote_command_store (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_records (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mSyncIfEmpty.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleTabsRemoteCommandStore::FromRust(
- uniffi_tabs_fn_method_tabsstore_new_remote_command_store(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettingsclient_get_records(
mUniffiPtr.IntoRust(),
+ mSyncIfEmpty.IntoRust(),
aOutStatus
)
);
@@ -7020,63 +7195,71 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreRegisterWithSyncManager : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecordsMap : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
+ FfiValueInt<int8_t> mSyncIfEmpty{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_register_with_sync_manager (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mSyncIfEmpty.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsstore_register_with_sync_manager(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettingsclient_get_records_map(
+ mUniffiPtr.IntoRust(),
+ mSyncIfEmpty.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreSetLocalTabs : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientShutdown : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
- FfiValueRustBuffer mRemoteTabs{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_set_local_tabs (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_shutdown (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mRemoteTabs.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tabs_fn_method_tabsstore_set_local_tabs(
+ uniffi_remote_settings_fn_method_remotesettingsclient_shutdown(
mUniffiPtr.IntoRust(),
- mRemoteTabs.IntoRust(),
aOutStatus
);
}
@@ -7084,123 +7267,186 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterEventSink : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mTarget{};
- FfiValueRustBuffer mLevel{};
- FfiValueCallbackInterfacetracing_EventSink mSink{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_register_event_sink (expected: 3, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsclient_sync (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mTarget.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mLevel.Lower(aArgs[1], aError);
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_remote_settings_fn_method_remotesettingsclient_sync(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsserviceNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mStorageDir{};
+ FfiValueRustBuffer mConfig{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_constructor_remotesettingsservice_new (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mStorageDir.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSink.Lower(aArgs[2], aError);
+ mConfig.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tracing_support_fn_func_register_event_sink(
- mTarget.IntoRust(),
- mLevel.IntoRust(),
- mSink.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettingsService::FromRust(
+ uniffi_remote_settings_fn_constructor_remotesettingsservice_new(
+ mStorageDir.IntoRust(),
+ mConfig.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterMinLevelEventSink : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceMakeClient : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mLevel{};
- FfiValueCallbackInterfacetracing_EventSink mSink{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
+ FfiValueRustBuffer mCollectionName{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsClient mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_register_min_level_event_sink (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_make_client (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mLevel.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mSink.Lower(aArgs[1], aError);
+ mCollectionName.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tracing_support_fn_func_register_min_level_event_sink(
- mLevel.IntoRust(),
- mSink.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleRemoteSettingsRemoteSettingsClient::FromRust(
+ uniffi_remote_settings_fn_method_remotesettingsservice_make_client(
+ mUniffiPtr.IntoRust(),
+ mCollectionName.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterEventSink : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mTarget{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_unregister_event_sink (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_sync (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mTarget.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tracing_support_fn_func_unregister_event_sink(
- mTarget.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_remote_settings_fn_method_remotesettingsservice_sync(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterMinLevelEventSink : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceUpdateConfig : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mUniffiPtr{};
+ FfiValueRustBuffer mConfig{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_remote_settings_fn_method_remotesettingsservice_update_config (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mConfig.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_tracing_support_fn_func_unregister_min_level_event_sink(
+ uniffi_remote_settings_fn_method_remotesettingsservice_update_config(
+ mUniffiPtr.IntoRust(),
+ mConfig.IntoRust(),
aOutStatus
);
}
@@ -7208,47 +7454,55 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiViaductFnFuncAllowAndroidEmulatorLoopback : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_viaduct_fn_func_allow_android_emulator_loopback(
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleSearchSearchEngineSelector::FromRust(
+ uniffi_search_fn_constructor_searchengineselector_new(
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiViaductFnFuncInitBackend : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorClearSearchConfig : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleViaductBackend mBackend{};
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_viaduct_fn_func_init_backend (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_clear_search_config (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mBackend.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_viaduct_fn_func_init_backend(
- mBackend.IntoRust(),
+ uniffi_search_fn_method_searchengineselector_clear_search_config(
+ mUniffiPtr.IntoRust(),
aOutStatus
);
}
@@ -7256,52 +7510,42 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest() : UniffiAsyncCallHandler(
- ffi_viaduct_rust_future_poll_rust_buffer,
- ffi_viaduct_rust_future_free_rust_buffer
- ) { }
-
+class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorFilterEngineConfiguration : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
+ FfiValueRustBuffer mUserEnvironment{};
+
+ // MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleViaductBackend mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_filter_engine_configuration (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- FfiValueRustBuffer mRequest{};
- mRequest.Lower(aArgs[1], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- FfiValueRustBuffer mSettings{};
- mSettings.Lower(aArgs[2], aError);
+ mUserEnvironment.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
+ }
- mFutureHandle = uniffi_viaduct_fn_method_backend_send_request(
- mUniffiPtr.IntoRust(),
- mRequest.IntoRust(),
- mSettings.IntoRust()
- );
- }
-
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_viaduct_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ uniffi_search_fn_method_searchengineselector_filter_engine_configuration(
+ mUniffiPtr.IntoRust(),
+ mUserEnvironment.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -7309,199 +7553,215 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineApply : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
+ FfiValueRustBuffer mOverrides{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_set_config_overrides (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mOverrides.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ uniffi_search_fn_method_searchengineselector_set_config_overrides(
+ mUniffiPtr.IntoRust(),
+ mOverrides.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineEnsureCurrentSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mNewSyncId{};
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
+ FfiValueRustBuffer mConfiguration{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_set_search_config (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mNewSyncId.Lower(aArgs[1], aError);
+ mConfiguration.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id(
- mUniffiPtr.IntoRust(),
- mNewSyncId.IntoRust(),
- aOutStatus
- )
+ uniffi_search_fn_method_searchengineselector_set_search_config(
+ mUniffiPtr.IntoRust(),
+ mConfiguration.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineLastSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSearchSearchEngineSelector mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mService{};
+ FfiValueInt<int8_t> mApplyEngineOverrides{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_search_fn_method_searchengineselector_use_remote_settings_server (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mService.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mApplyEngineOverrides.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ uniffi_search_fn_method_searchengineselector_use_remote_settings_server(
+ mUniffiPtr.IntoRust(),
+ mService.IntoRust(),
+ mApplyEngineOverrides.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedenginePrepareForSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mClientData{};
+ FfiValueRustBuffer mRawUrl{};
+ FfiValueRustBuffer mCookedUrl{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_func_raw_suggestion_url_matches (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mRawUrl.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mClientData.Lower(aArgs[1], aError);
+ mCookedUrl.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync(
- mUniffiPtr.IntoRust(),
- mClientData.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_suggest_fn_func_raw_suggestion_url_matches(
+ mRawUrl.IntoRust(),
+ mCookedUrl.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineReset : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRemoteSettingsService{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_constructor_suggeststore_new (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mPath.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mRemoteSettingsService.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStore::FromRust(
+ uniffi_suggest_fn_constructor_suggeststore_new(
+ mPath.IntoRust(),
+ mRemoteSettingsService.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineResetSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreAnyDismissedSuggestions : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
@@ -7511,8 +7771,8 @@ public:
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_suggest_fn_method_suggeststore_any_dismissed_suggestions(
mUniffiPtr.IntoRust(),
aOutStatus
)
@@ -7527,34 +7787,28 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetLastSync : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
- FfiValueInt<int64_t> mLastSync{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync (expected: 2, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_clear (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mLastSync.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync(
+ uniffi_suggest_fn_method_suggeststore_clear(
mUniffiPtr.IntoRust(),
- mLastSync.IntoRust(),
aOutStatus
);
}
@@ -7562,40 +7816,28 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetUploaded : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
- FfiValueInt<int64_t> mServerModifiedMillis{};
- FfiValueRustBuffer mGuids{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded (expected: 3, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mServerModifiedMillis.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mGuids.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded(
+ uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions(
mUniffiPtr.IntoRust(),
- mServerModifiedMillis.IntoRust(),
- mGuids.IntoRust(),
aOutStatus
);
}
@@ -7603,34 +7845,34 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineStoreIncoming : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissByKey : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
- FfiValueRustBuffer mIncoming{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mKey{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_by_key (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mIncoming.Lower(aArgs[1], aError);
+ mKey.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming(
+ uniffi_suggest_fn_method_suggeststore_dismiss_by_key(
mUniffiPtr.IntoRust(),
- mIncoming.IntoRust(),
+ mKey.IntoRust(),
aOutStatus
);
}
@@ -7638,28 +7880,34 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncFinished : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissBySuggestion : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mSuggestion{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mSuggestion.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished(
+ uniffi_suggest_fn_method_suggeststore_dismiss_by_suggestion(
mUniffiPtr.IntoRust(),
+ mSuggestion.IntoRust(),
aOutStatus
);
}
@@ -7667,125 +7915,163 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncId : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mSuggestionUrl{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_dismiss_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ mSuggestionUrl.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_suggest_fn_method_suggeststore_dismiss_suggestion(
+ mUniffiPtr.IntoRust(),
+ mSuggestionUrl.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncStarted : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonameAlternates : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mGeoname{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mGeoname.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_suggest_fn_method_suggeststore_fetch_geoname_alternates(
+ mUniffiPtr.IntoRust(),
+ mGeoname.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineWipe : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mQuery{};
+ FfiValueInt<int8_t> mMatchNamePrefix{};
+ FfiValueRustBuffer mFilter{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 4) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_geonames (expected: 4, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mQuery.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mMatchNamePrefix.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mFilter.Lower(aArgs[3], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_suggest_fn_method_suggeststore_fetch_geonames(
+ mUniffiPtr.IntoRust(),
+ mQuery.IntoRust(),
+ mMatchNamePrefix.IntoRust(),
+ mFilter.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnConstructorWebextstoragestoreNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGlobalConfig : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mPath{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_constructor_webextstoragestore_new (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_global_config (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mPath.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleWebextstorageWebExtStorageStore::FromRust(
- uniffi_webext_storage_fn_constructor_webextstoragestore_new(
- mPath.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_suggest_fn_method_suggeststore_fetch_global_config(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -7799,30 +8085,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreBridgedEngine : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchProviderConfig : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mProvider{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_fetch_provider_config (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mProvider.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine(
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_suggest_fn_method_suggeststore_fetch_provider_config(
mUniffiPtr.IntoRust(),
+ mProvider.IntoRust(),
aOutStatus
)
);
@@ -7836,11 +8128,11 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClear : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIngest : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mConstraints{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -7848,14 +8140,14 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_clear (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_ingest (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mExtId.Lower(aArgs[1], aError);
+ mConstraints.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -7863,9 +8155,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_clear(
+ uniffi_suggest_fn_method_suggeststore_ingest(
mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
+ mConstraints.IntoRust(),
aOutStatus
)
);
@@ -7879,28 +8171,34 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClose : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreInterrupt : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mKind{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_close (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_interrupt (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mKind.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_webext_storage_fn_method_webextstoragestore_close(
+ uniffi_suggest_fn_method_suggeststore_interrupt(
mUniffiPtr.IntoRust(),
+ mKind.IntoRust(),
aOutStatus
);
}
@@ -7908,42 +8206,36 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGet : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedByKey : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
- FfiValueRustBuffer mKeys{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mKey{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get (expected: 3, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mExtId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mKeys.Lower(aArgs[2], aError);
+ mKey.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_get(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_suggest_fn_method_suggeststore_is_dismissed_by_key(
mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
- mKeys.IntoRust(),
+ mKey.IntoRust(),
aOutStatus
)
);
@@ -7957,42 +8249,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetBytesInUse : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedBySuggestion : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
- FfiValueRustBuffer mKeys{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mSuggestion{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint64_t> mUniffiReturnValue{};
+ FfiValueInt<int8_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use (expected: 3, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mExtId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mKeys.Lower(aArgs[2], aError);
+ mSuggestion.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use(
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_suggest_fn_method_suggeststore_is_dismissed_by_suggestion(
mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
- mKeys.IntoRust(),
+ mSuggestion.IntoRust(),
aOutStatus
)
);
@@ -8006,11 +8292,11 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetKeys : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQuery : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mQuery{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -8018,14 +8304,14 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_keys (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_query (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mExtId.Lower(aArgs[1], aError);
+ mQuery.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -8033,9 +8319,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_get_keys(
+ uniffi_suggest_fn_method_suggeststore_query(
mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
+ mQuery.IntoRust(),
aOutStatus
)
);
@@ -8049,30 +8335,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetSyncedChanges : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQueryWithMetrics : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiPtr{};
+ FfiValueRustBuffer mQuery{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststore_query_with_metrics (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ mQuery.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes(
+ uniffi_suggest_fn_method_suggeststore_query_with_metrics(
mUniffiPtr.IntoRust(),
+ mQuery.IntoRust(),
aOutStatus
)
);
@@ -8086,42 +8378,20 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreRemove : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststorebuilderNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
- FfiValueRustBuffer mKeys{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_remove (expected: 3, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mExtId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mKeys.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_remove(
- mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
- mKeys.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_constructor_suggeststorebuilder_new(
aOutStatus
)
);
@@ -8135,42 +8405,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreSet : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderBuild : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
- FfiValueRustBuffer mExtId{};
- FfiValueRustBuffer mVal{};
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleSuggestSuggestStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 3) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_set (expected: 3, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_build (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mExtId.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mVal.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_webext_storage_fn_method_webextstoragestore_set(
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStore::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_build(
mUniffiPtr.IntoRust(),
- mExtId.IntoRust(),
- mVal.IntoRust(),
aOutStatus
)
);
@@ -8184,42 +8442,42 @@ public:
);
}
};
-
-#ifdef MOZ_UNIFFI_FIXTURES
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_f32,
- ffi_uniffi_bindings_tests_rust_future_free_f32
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderCachePath : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueFloat<float> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueRustBuffer mPath{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueFloat<float> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_cache_path (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mPath.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f32(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<float>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_f32(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_cache_path(
+ mUniffiPtr.IntoRust(),
+ mPath.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8227,40 +8485,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_f64,
- ffi_uniffi_bindings_tests_rust_future_free_f64
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderDataPath : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueFloat<double> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueRustBuffer mPath{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueFloat<double> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_data_path (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mPath.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f64(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<double>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_f64(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_data_path(
+ mUniffiPtr.IntoRust(),
+ mPath.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8268,40 +8528,48 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_i16,
- ffi_uniffi_bindings_tests_rust_future_free_i16
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderLoadExtension : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<int16_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueRustBuffer mLibrary{};
+ FfiValueRustBuffer mEntryPoint{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<int16_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_load_extension (expected: 3, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mLibrary.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mEntryPoint.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i16(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int16_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_i16(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_load_extension(
+ mUniffiPtr.IntoRust(),
+ mLibrary.IntoRust(),
+ mEntryPoint.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8309,40 +8577,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_i32,
- ffi_uniffi_bindings_tests_rust_future_free_i32
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsBucketName : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<int32_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueRustBuffer mBucketName{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<int32_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mBucketName.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i32(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int32_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_i32(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name(
+ mUniffiPtr.IntoRust(),
+ mBucketName.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8350,40 +8620,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_i64,
- ffi_uniffi_bindings_tests_rust_future_free_i64
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsServer : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<int64_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueRustBuffer mServer{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<int64_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mServer.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i64(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_i64(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server(
+ mUniffiPtr.IntoRust(),
+ mServer.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8391,40 +8663,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_i8,
- ffi_uniffi_bindings_tests_rust_future_free_i8
- ) { }
-
+class ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsService : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiPtr{};
+ FfiValueObjectHandleRemoteSettingsRemoteSettingsService mRsService{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<int8_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleSuggestSuggestStoreBuilder mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mRsService.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i8(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_i8(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleSuggestSuggestStoreBuilder::FromRust(
+ uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service(
+ mUniffiPtr.IntoRust(),
+ mRsService.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8432,40 +8706,48 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommand : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueRustBuffer mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+ FfiValueRustBuffer mDeviceId{};
+ FfiValueRustBuffer mCommand{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueRustBuffer mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_add_remote_command (expected: 3, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mDeviceId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mCommand.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_map(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_tabs_fn_method_remotecommandstore_add_remote_command(
+ mUniffiPtr.IntoRust(),
+ mDeviceId.IntoRust(),
+ mCommand.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8473,40 +8755,54 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_pointer,
- ffi_uniffi_bindings_tests_rust_future_free_pointer
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommandAt : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+ FfiValueRustBuffer mDeviceId{};
+ FfiValueRustBuffer mCommand{};
+ FfiValueInt<int64_t> mWhen{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 4) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at (expected: 4, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mDeviceId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mCommand.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mWhen.Lower(aArgs[3], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_obj(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncInterface::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_pointer(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at(
+ mUniffiPtr.IntoRust(),
+ mDeviceId.IntoRust(),
+ mCommand.IntoRust(),
+ mWhen.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8514,40 +8810,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreGetUnsentCommands : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueRustBuffer mV{};
- mV.Lower(aArgs[0], aError);
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_string(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8555,40 +8847,48 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u16,
- ffi_uniffi_bindings_tests_rust_future_free_u16
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreRemoveRemoteCommand : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint16_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+ FfiValueRustBuffer mDeviceId{};
+ FfiValueRustBuffer mCommand{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<uint16_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_remove_remote_command (expected: 3, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mDeviceId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mCommand.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u16(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint16_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u16(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_tabs_fn_method_remotecommandstore_remove_remote_command(
+ mUniffiPtr.IntoRust(),
+ mDeviceId.IntoRust(),
+ mCommand.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8596,40 +8896,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u32,
- ffi_uniffi_bindings_tests_rust_future_free_u32
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreSetPendingCommandSent : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiPtr{};
+ FfiValueRustBuffer mCommand{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<uint32_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mCommand.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u32(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent(
+ mUniffiPtr.IntoRust(),
+ mCommand.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8637,40 +8939,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u64,
- ffi_uniffi_bindings_tests_rust_future_free_u64
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineApply : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint64_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<uint64_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_apply (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u64(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u64(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_tabs_fn_method_tabsbridgedengine_apply(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8678,40 +8976,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8 : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u8,
- ffi_uniffi_bindings_tests_rust_future_free_u8
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineEnsureCurrentSyncId : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint8_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mNewSyncId{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueInt<uint8_t> mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNewSyncId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u8(
- mV.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint8_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u8(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id(
+ mUniffiPtr.IntoRust(),
+ mNewSyncId.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8719,40 +9019,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineLastSync : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueRustBuffer mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueRustBuffer mV{};
- mV.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_last_sync (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
+ }
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_vec(
- mV.IntoRust()
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_tabs_fn_method_tabsbridgedengine_last_sync(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
);
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
- }
-
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -8760,95 +9056,94 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedenginePrepareForSync : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mClientData{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ // MakeRustCall stores the result of the call in these fields
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_throw_error(
- );
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mClientData.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync(
+ mUniffiPtr.IntoRust(),
+ mClientData.IntoRust(),
+ aOutStatus
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCloneInterface : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineReset : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mInt{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_clone_interface (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_reset (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mInt.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_clone_interface(
- mInt.IntoRust(),
- aOutStatus
- )
+ uniffi_tabs_fn_method_tabsbridgedengine_reset(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateAsyncTestTraitInterface : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineResetSyncId : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mValue{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mValue.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface(
- mValue.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -8862,102 +9157,110 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateTestTraitInterface : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetLastSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mValue{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueInt<int64_t> mLastSync{};
// MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mValue.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mLastSync.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface(
- mValue.IntoRust(),
- aOutStatus
- )
+ uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync(
+ mUniffiPtr.IntoRust(),
+ mLastSync.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithDefault : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetUploaded : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mArg{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueInt<int64_t> mNewTimestamp{};
+ FfiValueRustBuffer mUploadedIds{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_default (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mArg.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNewTimestamp.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mUploadedIds.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_func_with_default(
- mArg.IntoRust(),
- aOutStatus
- )
+ uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded(
+ mUniffiPtr.IntoRust(),
+ mNewTimestamp.IntoRust(),
+ mUploadedIds.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithError : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineStoreIncoming : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mInput{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mIncomingEnvelopesAsJson{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_error (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_store_incoming (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mInput.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mIncomingEnvelopesAsJson.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_func_with_error(
- mInput.IntoRust(),
+ uniffi_tabs_fn_method_tabsbridgedengine_store_incoming(
+ mUniffiPtr.IntoRust(),
+ mIncomingEnvelopesAsJson.IntoRust(),
aOutStatus
);
}
@@ -8965,28 +9268,28 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithFlatError : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncFinished : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mInput{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_finished (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mInput.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error(
- mInput.IntoRust(),
+ uniffi_tabs_fn_method_tabsbridgedengine_sync_finished(
+ mUniffiPtr.IntoRust(),
aOutStatus
);
}
@@ -8994,10 +9297,10 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithMultiWordArg : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncId : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mTheArgument{};
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -9005,10 +9308,10 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mTheArgument.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
@@ -9016,8 +9319,8 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg(
- mTheArgument.IntoRust(),
+ uniffi_tabs_fn_method_tabsbridgedengine_sync_id(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -9031,67 +9334,94 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncGetCustomTypesDemo : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncStarted : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_sync_started (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_get_custom_types_demo(
- aOutStatus
- )
+ uniffi_tabs_fn_method_tabsbridgedengine_sync_started(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u32,
- ffi_uniffi_bindings_tests_rust_future_free_u32
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineWipe : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
- mInt.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsbridgedengine_wipe (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_get_value(
- mInt.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_tabs_fn_method_tabsbridgedengine_wipe(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ );
}
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiTabsFnConstructorTabsstoreNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mPath{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiReturnValue{};
+
public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_constructor_tabsstore_new (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mPath.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleTabsTabsStore::FromRust(
+ uniffi_tabs_fn_constructor_tabsstore_new(
+ mPath.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -9099,120 +9429,102 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreBridgedEngine : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
- mInt.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleTabsTabsBridgedEngine mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_bridged_engine (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_noop(
- mInt.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleTabsTabsBridgedEngine::FromRust(
+ uniffi_tabs_fn_method_tabsstore_bridged_engine(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreCloseConnection : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
- mInt.Lower(aArgs[0], aError);
- if (aError.Failed()) {
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_close_connection (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- FfiValueInt<uint32_t> mValue{};
- mValue.Lower(aArgs[1], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_set_value(
- mInt.IntoRust(),
- mValue.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_tabs_fn_method_tabsstore_close_connection(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreGetAll : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
- mInt.Lower(aArgs[0], aError);
- if (aError.Failed()) {
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_get_all (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- FfiValueRustBuffer mNumbers{};
- mNumbers.Lower(aArgs[1], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_throw_if_equal(
- mInt.IntoRust(),
- mNumbers.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ uniffi_tabs_fn_method_tabsstore_get_all(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -9220,40 +9532,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u32,
- ffi_uniffi_bindings_tests_rust_future_free_u32
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreNewRemoteCommandStore : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
- mCbi.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleTabsRemoteCommandStore mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_new_remote_command_store (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_get_value(
- mCbi.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleTabsRemoteCommandStore::FromRust(
+ uniffi_tabs_fn_method_tabsstore_new_remote_command_store(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
}
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -9261,186 +9569,104 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
- ) { }
-
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreRegisterWithSyncManager : public UniffiSyncCallHandler {
private:
- // Complete stores the result of the call in mUniffiReturnValue
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
- mCbi.Lower(aArgs[0], aError);
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_register_with_sync_manager (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_noop(
- mCbi.IntoRust()
- );
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
- }
-
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
- ) { }
-
-private:
- // Complete stores the result of the call in mUniffiReturnValue
-
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
- mCbi.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- FfiValueInt<uint32_t> mValue{};
- mValue.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_set_value(
- mCbi.IntoRust(),
- mValue.IntoRust()
- );
- }
-
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
- }
-
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual : public UniffiAsyncCallHandler {
-public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
- ) { }
-
-private:
- // Complete stores the result of the call in mUniffiReturnValue
- FfiValueRustBuffer mUniffiReturnValue{};
-
-protected:
- // Convert a sequence of JS arguments and call the scaffolding function.
- // Always called on the main thread since async Rust calls don't block, they
- // return a future.
- void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
- mCbi.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- FfiValueRustBuffer mNumbers{};
- mNumbers.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
-
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_throw_if_equal(
- mCbi.IntoRust(),
- mNumbers.IntoRust()
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_tabs_fn_method_tabsstore_register_with_sync_manager(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
- void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
- }
-
-public:
- void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceGetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreSetLocalTabs : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+ FfiValueObjectHandleTabsTabsStore mUniffiPtr{};
+ FfiValueRustBuffer mRemoteTabs{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tabs_fn_method_tabsstore_set_local_tabs (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mCbi.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mRemoteTabs.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value(
- mCbi.IntoRust(),
- aOutStatus
- )
+ uniffi_tabs_fn_method_tabsstore_set_local_tabs(
+ mUniffiPtr.IntoRust(),
+ mRemoteTabs.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceNoop : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterEventSink : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+ FfiValueRustBuffer mTarget{};
+ FfiValueRustBuffer mLevel{};
+ FfiValueCallbackInterfacetracing_EventSink mSink{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_register_event_sink (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mCbi.Lower(aArgs[0], aError);
+ mTarget.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mLevel.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mSink.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop(
- mCbi.IntoRust(),
+ uniffi_tracing_support_fn_func_register_event_sink(
+ mTarget.IntoRust(),
+ mLevel.IntoRust(),
+ mSink.IntoRust(),
aOutStatus
);
}
@@ -9448,34 +9674,34 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceSetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterMinLevelEventSink : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
- FfiValueInt<uint32_t> mValue{};
+ FfiValueRustBuffer mLevel{};
+ FfiValueCallbackInterfacetracing_EventSink mSink{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_register_min_level_event_sink (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mCbi.Lower(aArgs[0], aError);
+ mLevel.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mValue.Lower(aArgs[1], aError);
+ mSink.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value(
- mCbi.IntoRust(),
- mValue.IntoRust(),
+ uniffi_tracing_support_fn_func_register_min_level_event_sink(
+ mLevel.IntoRust(),
+ mSink.IntoRust(),
aOutStatus
);
}
@@ -9483,108 +9709,66 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceThrowIfEqual : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterEventSink : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
- FfiValueRustBuffer mNumbers{};
+ FfiValueRustBuffer mTarget{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mCbi.Lower(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_tracing_support_fn_func_unregister_event_sink (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mNumbers.Lower(aArgs[1], aError);
+ mTarget.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal(
- mCbi.IntoRust(),
- mNumbers.IntoRust(),
- aOutStatus
- )
+ uniffi_tracing_support_fn_func_unregister_event_sink(
+ mTarget.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceGetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterMinLevelEventSink : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mInt.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value(
- mInt.IntoRust(),
- aOutStatus
- )
+ uniffi_tracing_support_fn_func_unregister_min_level_event_sink(
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceNoop : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiViaductFnFuncAllowAndroidEmulatorLoopback : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mInt.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop(
- mInt.IntoRust(),
+ uniffi_viaduct_fn_func_allow_android_emulator_loopback(
aOutStatus
);
}
@@ -9592,34 +9776,28 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceSetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiViaductFnFuncInitBackend : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
- FfiValueInt<uint32_t> mValue{};
+ FfiValueObjectHandleViaductBackend mBackend{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mInt.Lower(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_viaduct_fn_func_init_backend (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mValue.Lower(aArgs[1], aError);
+ mBackend.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value(
- mInt.IntoRust(),
- mValue.IntoRust(),
+ uniffi_viaduct_fn_func_init_backend(
+ mBackend.IntoRust(),
aOutStatus
);
}
@@ -9627,42 +9805,52 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceThrowIfEqual : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
- FfiValueRustBuffer mNumbers{};
+class ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest() : UniffiAsyncCallHandler(
+ ffi_viaduct_rust_future_poll_rust_buffer,
+ ffi_viaduct_rust_future_free_rust_buffer
+ ) { }
- // MakeRustCall stores the result of the call in these fields
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
FfiValueRustBuffer mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleViaductBackend mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mInt.Lower(aArgs[0], aError);
+ FfiValueRustBuffer mRequest{};
+ mRequest.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
- mNumbers.Lower(aArgs[1], aError);
+ FfiValueRustBuffer mSettings{};
+ mSettings.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
+
+ mFutureHandle = uniffi_viaduct_fn_method_backend_send_request(
+ mUniffiPtr.IntoRust(),
+ mRequest.IntoRust(),
+ mSettings.IntoRust()
+ );
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal(
- mInt.IntoRust(),
- mNumbers.IntoRust(),
- aOutStatus
- )
- );
+ ffi_viaduct_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -9670,30 +9858,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripBool : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineApply : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int8_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -9707,21 +9895,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexCompound : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineEnsureCurrentSyncId : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mNewSyncId{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNewSyncId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -9729,8 +9922,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound(
- mA.IntoRust(),
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id(
+ mUniffiPtr.IntoRust(),
+ mNewSyncId.IntoRust(),
aOutStatus
)
);
@@ -9744,30 +9938,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexEnum : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineLastSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mEn{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mEn.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum(
- mEn.IntoRust(),
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -9781,84 +9975,74 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexRec : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedenginePrepareForSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mRec{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mClientData{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mRec.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mClientData.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec(
- mRec.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync(
+ mUniffiPtr.IntoRust(),
+ mClientData.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripCustomType : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineReset : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint64_t> mHandle{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mHandle.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type(
- mHandle.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumNoData : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineResetSyncId : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mEn{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -9866,10 +10050,10 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mEn.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
@@ -9877,8 +10061,8 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data(
- mEn.IntoRust(),
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -9892,178 +10076,170 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumWithData : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetLastSync : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mEn{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueInt<int64_t> mLastSync{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mEn.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mLastSync.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data(
- mEn.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync(
+ mUniffiPtr.IntoRust(),
+ mLastSync.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF32 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetUploaded : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueFloat<float> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueInt<int64_t> mServerModifiedMillis{};
+ FfiValueRustBuffer mGuids{};
// MakeRustCall stores the result of the call in these fields
- FfiValueFloat<float> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32 (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mServerModifiedMillis.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mGuids.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<float>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded(
+ mUniffiPtr.IntoRust(),
+ mServerModifiedMillis.IntoRust(),
+ mGuids.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF64 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineStoreIncoming : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueFloat<double> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
+ FfiValueRustBuffer mIncoming{};
// MakeRustCall stores the result of the call in these fields
- FfiValueFloat<double> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64 (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mIncoming.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<double>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming(
+ mUniffiPtr.IntoRust(),
+ mIncoming.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripHashMap : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncFinished : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI16 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncId : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int16_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int16_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16 (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int16_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -10077,104 +10253,88 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI32 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncStarted : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int32_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int32_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32 (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI64 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineWipe : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int64_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64 (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI8 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnConstructorWebextstoragestoreNew : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int8_t> mA{};
+ FfiValueRustBuffer mPath{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int8_t> mUniffiReturnValue{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8 (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_constructor_webextstoragestore_new (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mPath.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleWebextstorageWebExtStorageStore::FromRust(
+ uniffi_webext_storage_fn_constructor_webextstoragestore_new(
+ mPath.IntoRust(),
aOutStatus
)
);
@@ -10188,30 +10348,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripOption : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreBridgedEngine : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_option (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_option(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleWebextstorageWebExtStorageBridgedEngine::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -10225,21 +10385,26 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripSimpleRec : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClear : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mRec{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_clear (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mRec.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
@@ -10247,8 +10412,9 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec(
- mRec.IntoRust(),
+ uniffi_webext_storage_fn_method_webextstoragestore_clear(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
aOutStatus
)
);
@@ -10262,67 +10428,71 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripString : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClose : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_string (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_close (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_string(
- mA.IntoRust(),
- aOutStatus
- )
+ uniffi_webext_storage_fn_method_webextstoragestore_close(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalMs : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGet : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<int64_t> mTime{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
+ FfiValueRustBuffer mKeys{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<int64_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mTime.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mKeys.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms(
- mTime.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_get(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
+ mKeys.IntoRust(),
aOutStatus
)
);
@@ -10336,30 +10506,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecDbl : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetBytesInUse : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueFloat<double> mTime{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
+ FfiValueRustBuffer mKeys{};
// MakeRustCall stores the result of the call in these fields
- FfiValueFloat<double> mUniffiReturnValue{};
+ FfiValueInt<uint64_t> mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mTime.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mKeys.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<double>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl(
- mTime.IntoRust(),
+ mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
+ mKeys.IntoRust(),
aOutStatus
)
);
@@ -10373,30 +10555,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecFlt : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetKeys : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueFloat<float> mTime{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
// MakeRustCall stores the result of the call in these fields
- FfiValueFloat<float> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_keys (expected: 2, actual: %zu)", aArgs.Length()));
return;
}
- mTime.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<float>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt(
- mTime.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_get_keys(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
aOutStatus
)
);
@@ -10410,30 +10598,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU16 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetSyncedChanges : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint16_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint16_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16 (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint16_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes(
+ mUniffiPtr.IntoRust(),
aOutStatus
)
);
@@ -10447,30 +10635,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU32 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreRemove : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
+ FfiValueRustBuffer mKeys{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32 (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_remove (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mKeys.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_remove(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
+ mKeys.IntoRust(),
aOutStatus
)
);
@@ -10484,30 +10684,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU64 : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreSet : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint64_t> mA{};
+ FfiValueObjectHandleWebextstorageWebExtStorageStore mUniffiPtr{};
+ FfiValueRustBuffer mExtId{};
+ FfiValueRustBuffer mVal{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint64_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64 (expected: 1, actual: %zu)", aArgs.Length()));
+ if (aArgs.Length() < 3) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_webext_storage_fn_method_webextstoragestore_set (expected: 3, actual: %zu)", aArgs.Length()));
return;
}
- mA.Lower(aArgs[0], aError);
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mExtId.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mVal.Lower(aArgs[2], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64(
- mA.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_webext_storage_fn_method_webextstoragestore_set(
+ mUniffiPtr.IntoRust(),
+ mExtId.IntoRust(),
+ mVal.IntoRust(),
aOutStatus
)
);
@@ -10521,36 +10733,42 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU8 : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint8_t> mA{};
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint8_t> mUniffiReturnValue{};
+#ifdef MOZ_UNIFFI_FIXTURES
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32 : public UniffiAsyncCallHandler {
public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8 (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mA.Lower(aArgs[0], aError);
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_f32,
+ ffi_uniffi_bindings_tests_rust_future_free_f32
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueFloat<float> mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueFloat<float> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint8_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8(
- mA.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f32(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<float>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_f32(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10558,36 +10776,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripUrl : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mUrl{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64 : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_f64,
+ ffi_uniffi_bindings_tests_rust_future_free_f64
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueFloat<double> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_url (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUrl.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueFloat<double> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_url(
- mUrl.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_f64(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<double>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_f64(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10595,36 +10817,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripVec : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mA{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16 : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_i16,
+ ffi_uniffi_bindings_tests_rust_future_free_i16
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<int16_t> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mA.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueInt<int16_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec(
- mA.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i16(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int16_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_i16(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10632,96 +10858,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSumWithManyTypes : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint8_t> mA{};
- FfiValueInt<int8_t> mB{};
- FfiValueInt<uint16_t> mC{};
- FfiValueInt<int16_t> mD{};
- FfiValueInt<uint32_t> mE{};
- FfiValueInt<int32_t> mF{};
- FfiValueInt<uint64_t> mG{};
- FfiValueInt<int64_t> mH{};
- FfiValueFloat<float> mI{};
- FfiValueFloat<double> mJ{};
- FfiValueInt<int8_t> mNegate{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32 : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_i32,
+ ffi_uniffi_bindings_tests_rust_future_free_i32
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueFloat<double> mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<int32_t> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 11) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types (expected: 11, actual: %zu)", aArgs.Length()));
- return;
- }
- mA.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- mB.Lower(aArgs[1], aError);
- if (aError.Failed()) {
- return;
- }
- mC.Lower(aArgs[2], aError);
- if (aError.Failed()) {
- return;
- }
- mD.Lower(aArgs[3], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueInt<int32_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mE.Lower(aArgs[4], aError);
- if (aError.Failed()) {
- return;
- }
- mF.Lower(aArgs[5], aError);
- if (aError.Failed()) {
- return;
- }
- mG.Lower(aArgs[6], aError);
- if (aError.Failed()) {
- return;
- }
- mH.Lower(aArgs[7], aError);
- if (aError.Failed()) {
- return;
- }
- mI.Lower(aArgs[8], aError);
- if (aError.Failed()) {
- return;
- }
- mJ.Lower(aArgs[9], aError);
- if (aError.Failed()) {
- return;
- }
- mNegate.Lower(aArgs[10], aError);
- if (aError.Failed()) {
- return;
- }
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueFloat<double>::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types(
- mA.IntoRust(),
- mB.IntoRust(),
- mC.IntoRust(),
- mD.IntoRust(),
- mE.IntoRust(),
- mF.IntoRust(),
- mG.IntoRust(),
- mH.IntoRust(),
- mI.IntoRust(),
- mJ.IntoRust(),
- mNegate.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i32(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int32_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_i32(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10729,36 +10899,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSwapTestInterfaces : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mInterfaces{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64 : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_i64,
+ ffi_uniffi_bindings_tests_rust_future_free_i64
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<int64_t> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mInterfaces.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueInt<int64_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces(
- mInterfaces.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i64(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_i64(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10766,55 +10940,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncTestFunc : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
-
- // MakeRustCall stores the result of the call in these fields
-
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8 : public UniffiAsyncCallHandler {
public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- }
-
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_func_test_func(
- aOutStatus
- );
- }
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_i8,
+ ffi_uniffi_bindings_tests_rust_future_free_i8
+ ) { }
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- }
-};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorTestinterfaceNew : public UniffiSyncCallHandler {
private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint32_t> mValue{};
-
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<int8_t> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mValue.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueInt<int8_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
- uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new(
- mValue.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_i8(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_i8(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10822,36 +10981,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceGetValue : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiPtr{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueRustBuffer mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_map(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10859,36 +11022,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceRefCount : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiPtr{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_pointer,
+ ffi_uniffi_bindings_tests_rust_future_free_pointer
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count(
- mUniffiPtr.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_obj(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncInterface::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_pointer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10896,36 +11063,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorAsyncinterfaceNew : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mName{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mName.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueRustBuffer mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncInterface::FromRust(
- uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new(
- mName.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_string(
+ mV.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -10933,36 +11104,36 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName : public UniffiAsyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16 : public UniffiAsyncCallHandler {
public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
- ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u16,
+ ffi_uniffi_bindings_tests_rust_future_free_u16
) { }
private:
// Complete stores the result of the call in mUniffiReturnValue
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueInt<uint16_t> mUniffiReturnValue{};
protected:
// Convert a sequence of JS arguments and call the scaffolding function.
// Always called on the main thread since async Rust calls don't block, they
// return a future.
void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ FfiValueInt<uint16_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asyncinterface_name(
- mUniffiPtr.IntoRust()
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u16(
+ mV.IntoRust()
);
}
void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ mUniffiReturnValue = FfiValueInt<uint16_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u16(mFutureHandle, aOutStatus));
}
public:
@@ -10974,70 +11145,77 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop : public UniffiAsyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32 : public UniffiAsyncCallHandler {
public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u32,
+ ffi_uniffi_bindings_tests_rust_future_free_u32
) { }
private:
// Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
protected:
// Convert a sequence of JS arguments and call the scaffolding function.
// Always called on the main thread since async Rust calls don't block, they
// return a future.
void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ FfiValueInt<uint32_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_noop(
- mUniffiPtr.IntoRust()
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u32(
+ mV.IntoRust()
);
}
void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
}
public:
void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue : public UniffiAsyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64 : public UniffiAsyncCallHandler {
public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_u32,
- ffi_uniffi_bindings_tests_rust_future_free_u32
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u64,
+ ffi_uniffi_bindings_tests_rust_future_free_u64
) { }
private:
// Complete stores the result of the call in mUniffiReturnValue
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ FfiValueInt<uint64_t> mUniffiReturnValue{};
protected:
// Convert a sequence of JS arguments and call the scaffolding function.
// Always called on the main thread since async Rust calls don't block, they
// return a future.
void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ FfiValueInt<uint64_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_get_value(
- mUniffiPtr.IntoRust()
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u64(
+ mV.IntoRust()
);
}
void CallCompleteFn(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u64(mFutureHandle, aOutStatus));
}
public:
@@ -11049,49 +11227,50 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue : public UniffiAsyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8 : public UniffiAsyncCallHandler {
public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue() : UniffiAsyncCallHandler(
- ffi_uniffi_bindings_tests_rust_future_poll_void,
- ffi_uniffi_bindings_tests_rust_future_free_void
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u8,
+ ffi_uniffi_bindings_tests_rust_future_free_u8
) { }
private:
// Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<uint8_t> mUniffiReturnValue{};
protected:
// Convert a sequence of JS arguments and call the scaffolding function.
// Always called on the main thread since async Rust calls don't block, they
// return a future.
void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- FfiValueInt<uint32_t> mValue{};
- mValue.Lower(aArgs[1], aError);
+ FfiValueInt<uint8_t> mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_set_value(
- mUniffiPtr.IntoRust(),
- mValue.IntoRust()
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_u8(
+ mV.IntoRust()
);
}
void CallCompleteFn(RustCallStatus* aOutStatus) override {
- ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ mUniffiReturnValue = FfiValueInt<uint8_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u8(mFutureHandle, aOutStatus));
}
public:
void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual : public UniffiAsyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec : public UniffiAsyncCallHandler {
public:
- ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual() : UniffiAsyncCallHandler(
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec() : UniffiAsyncCallHandler(
ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
) { }
@@ -11105,20 +11284,14 @@ protected:
// Always called on the main thread since async Rust calls don't block, they
// return a future.
void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
- FfiValueRustBuffer mNumbers{};
- mNumbers.Lower(aArgs[1], aError);
+ FfiValueRustBuffer mV{};
+ mV.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_throw_if_equal(
- mUniffiPtr.IntoRust(),
- mNumbers.IntoRust()
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_roundtrip_vec(
+ mV.IntoRust()
);
}
@@ -11136,63 +11309,58 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorComplexmethodsNew : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
+
private:
- // LowerRustArgs stores the resulting arguments in these fields
+ // Complete stores the result of the call in mUniffiReturnValue
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiReturnValue{};
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_async_throw_error(
+ );
}
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsComplexMethods::FromRust(
- uniffi_uniffi_bindings_tests_fn_constructor_complexmethods_new(
- aOutStatus
- )
- );
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithDefault : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCloneInterface : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiPtr{};
- FfiValueRustBuffer mArg{};
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mInt{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_clone_interface (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mArg.Lower(aArgs[1], aError);
+ mInt.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default(
- mUniffiPtr.IntoRust(),
- mArg.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_clone_interface(
+ mInt.IntoRust(),
aOutStatus
)
);
@@ -11206,36 +11374,30 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithMultiWordArg : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateAsyncTestTraitInterface : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiPtr{};
- FfiValueRustBuffer mTheArgument{};
+ FfiValueInt<uint32_t> mValue{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mTheArgument.Lower(aArgs[1], aError);
+ mValue.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg(
- mUniffiPtr.IntoRust(),
- mTheArgument.IntoRust(),
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_create_async_test_trait_interface(
+ mValue.IntoRust(),
aOutStatus
)
);
@@ -11249,59 +11411,67 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceNoop : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateTestTraitInterface : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+ FfiValueInt<uint32_t> mValue{};
// MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mValue.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop(
- mUniffiPtr.IntoRust(),
- aOutStatus
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_create_test_trait_interface(
+ mValue.IntoRust(),
+ aOutStatus
+ )
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceGetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithDefault : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+ FfiValueRustBuffer mArg{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint32_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_default (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mUniffiPtr.LowerReciever(aArgs[0], aError);
+ mArg.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value(
- mUniffiPtr.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_func_with_default(
+ mArg.IntoRust(),
aOutStatus
)
);
@@ -11315,34 +11485,28 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceSetValue : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithError : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
- FfiValueInt<uint32_t> mValue{};
+ FfiValueInt<uint32_t> mInput{};
// MakeRustCall stores the result of the call in these fields
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_error (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mValue.Lower(aArgs[1], aError);
+ mInput.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value(
- mUniffiPtr.IntoRust(),
- mValue.IntoRust(),
+ uniffi_uniffi_bindings_tests_fn_func_func_with_error(
+ mInput.IntoRust(),
aOutStatus
);
}
@@ -11350,53 +11514,39 @@ public:
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceThrowIfEqual : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithFlatError : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
- FfiValueRustBuffer mNumbers{};
+ FfiValueInt<uint32_t> mInput{};
// MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 2) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
- return;
- }
- mUniffiPtr.LowerReciever(aArgs[0], aError);
- if (aError.Failed()) {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mNumbers.Lower(aArgs[1], aError);
+ mInput.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal(
- mUniffiPtr.IntoRust(),
- mNumbers.IntoRust(),
- aOutStatus
- )
+ uniffi_uniffi_bindings_tests_fn_func_func_with_flat_error(
+ mInput.IntoRust(),
+ aOutStatus
);
}
virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsCollisionFnFuncInvokeCollisionCallback : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithMultiWordArg : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface mCb{};
+ FfiValueRustBuffer mTheArgument{};
// MakeRustCall stores the result of the call in these fields
FfiValueRustBuffer mUniffiReturnValue{};
@@ -11404,10 +11554,10 @@ private:
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback (expected: 1, actual: %zu)", aArgs.Length()));
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg (expected: 1, actual: %zu)", aArgs.Length()));
return;
}
- mCb.Lower(aArgs[0], aError);
+ mTheArgument.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
@@ -11415,8 +11565,8 @@ public:
void MakeRustCall(RustCallStatus* aOutStatus) override {
mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback(
- mCb.IntoRust(),
+ uniffi_uniffi_bindings_tests_fn_func_func_with_multi_word_arg(
+ mTheArgument.IntoRust(),
aOutStatus
)
);
@@ -11430,30 +11580,20 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtCustomType : public UniffiSyncCallHandler {
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncGetCustomTypesDemo : public UniffiSyncCallHandler {
private:
// LowerRustArgs stores the resulting arguments in these fields
- FfiValueInt<uint64_t> mCustom{};
// MakeRustCall stores the result of the call in these fields
- FfiValueInt<uint64_t> mUniffiReturnValue{};
+ FfiValueRustBuffer mUniffiReturnValue{};
public:
void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mCustom.Lower(aArgs[0], aError);
- if (aError.Failed()) {
- return;
- }
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
- uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type(
- mCustom.IntoRust(),
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_get_custom_types_demo(
aOutStatus
)
);
@@ -11467,36 +11607,40 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtEnum : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mEn{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u32,
+ ffi_uniffi_bindings_tests_rust_future_free_u32
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
- mEn.Lower(aArgs[0], aError);
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
+ mInt.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum(
- mEn.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_get_value(
+ mInt.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
mUniffiReturnValue.Lift(
aCx,
&aDest.Construct(),
@@ -11504,87 +11648,2492 @@ public:
);
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtInterface : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mInt{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface (expected: 1, actual: %zu)", aArgs.Length()));
- return;
- }
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
mInt.Lower(aArgs[0], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
- uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface(
- mInt.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_noop(
+ mInt.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
-class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtRecord : public UniffiSyncCallHandler {
-private:
- // LowerRustArgs stores the resulting arguments in these fields
- FfiValueRustBuffer mRec{};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
- // MakeRustCall stores the result of the call in these fields
- FfiValueRustBuffer mUniffiReturnValue{};
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
-public:
- void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
- if (aArgs.Length() < 1) {
- aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record (expected: 1, actual: %zu)", aArgs.Length()));
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
return;
}
- mRec.Lower(aArgs[0], aError);
+ FfiValueInt<uint32_t> mValue{};
+ mValue.Lower(aArgs[1], aError);
if (aError.Failed()) {
return;
}
- }
- void MakeRustCall(RustCallStatus* aOutStatus) override {
- mUniffiReturnValue = FfiValueRustBuffer::FromRust(
- uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record(
- mRec.IntoRust(),
- aOutStatus
- )
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_set_value(
+ mInt.IntoRust(),
+ mValue.IntoRust()
);
}
- virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
- mUniffiReturnValue.Lift(
- aCx,
- &aDest.Construct(),
- aError
- );
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
}
-};
-#endif /* MOZ_UNIFFI_FIXTURES */
-
-UniquePtr<UniffiSyncCallHandler> GetSyncCallHandler(uint64_t aId) {
- switch (aId) {
- case 1: {
- return MakeUnique<ScaffoldingCallHandlerUniffiContextIdFnConstructorContextidcomponentNew>();
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mInt{};
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ FfiValueRustBuffer mNumbers{};
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_async_test_trait_interface_throw_if_equal(
+ mInt.IntoRust(),
+ mNumbers.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u32,
+ ffi_uniffi_bindings_tests_rust_future_free_u32
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_get_value(
+ mCbi.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_noop(
+ mCbi.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ FfiValueInt<uint32_t> mValue{};
+ mValue.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_set_value(
+ mCbi.IntoRust(),
+ mValue.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestAsyncCallbackInterface mCbi{};
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ FfiValueRustBuffer mNumbers{};
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_func_invoke_test_async_callback_interface_throw_if_equal(
+ mCbi.IntoRust(),
+ mNumbers.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceGetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_get_value(
+ mCbi.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceNoop : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_noop(
+ mCbi.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceSetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+ FfiValueInt<uint32_t> mValue{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mValue.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_set_value(
+ mCbi.IntoRust(),
+ mValue.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceThrowIfEqual : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueCallbackInterfaceuniffi_bindings_tests_TestCallbackInterface mCbi{};
+ FfiValueRustBuffer mNumbers{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCbi.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_callback_interface_throw_if_equal(
+ mCbi.IntoRust(),
+ mNumbers.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceGetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_get_value(
+ mInt.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceNoop : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_noop(
+ mInt.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceSetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
+ FfiValueInt<uint32_t> mValue{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mValue.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_set_value(
+ mInt.IntoRust(),
+ mValue.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceThrowIfEqual : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mInt{};
+ FfiValueRustBuffer mNumbers{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_invoke_test_trait_interface_throw_if_equal(
+ mInt.IntoRust(),
+ mNumbers.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripBool : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int8_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_bool(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexCompound : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_compound(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexEnum : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mEn{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mEn.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_enum(
+ mEn.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexRec : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mRec{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mRec.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_complex_rec(
+ mRec.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripCustomType : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint64_t> mHandle{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mHandle.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_custom_type(
+ mHandle.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumNoData : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mEn{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mEn.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_no_data(
+ mEn.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumWithData : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mEn{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mEn.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_enum_with_data(
+ mEn.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF32 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueFloat<float> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueFloat<float> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<float>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_f32(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF64 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueFloat<double> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueFloat<double> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<double>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_f64(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripHashMap : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_hash_map(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI16 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int16_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int16_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int16_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_i16(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI32 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int32_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_i32(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI64 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int64_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_i64(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI8 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int8_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int8_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_i8(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripOption : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_option (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_option(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripSimpleRec : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mRec{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mRec.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_simple_rec(
+ mRec.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripString : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_string (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_string(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalMs : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<int64_t> mTime{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<int64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mTime.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<int64_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_ms(
+ mTime.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecDbl : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueFloat<double> mTime{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueFloat<double> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mTime.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<double>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_dbl(
+ mTime.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecFlt : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueFloat<float> mTime{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueFloat<float> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mTime.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<float>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_time_interval_sec_flt(
+ mTime.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU16 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint16_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint16_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint16_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_u16(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU32 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint32_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_u32(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU64 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint64_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_u64(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU8 : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint8_t> mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint8_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8 (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint8_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_u8(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripUrl : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mUrl{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_url (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUrl.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_url(
+ mUrl.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripVec : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mA{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_roundtrip_vec(
+ mA.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSumWithManyTypes : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint8_t> mA{};
+ FfiValueInt<int8_t> mB{};
+ FfiValueInt<uint16_t> mC{};
+ FfiValueInt<int16_t> mD{};
+ FfiValueInt<uint32_t> mE{};
+ FfiValueInt<int32_t> mF{};
+ FfiValueInt<uint64_t> mG{};
+ FfiValueInt<int64_t> mH{};
+ FfiValueFloat<float> mI{};
+ FfiValueFloat<double> mJ{};
+ FfiValueInt<int8_t> mNegate{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueFloat<double> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 11) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types (expected: 11, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mA.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mB.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mC.Lower(aArgs[2], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mD.Lower(aArgs[3], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mE.Lower(aArgs[4], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mF.Lower(aArgs[5], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mG.Lower(aArgs[6], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mH.Lower(aArgs[7], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mI.Lower(aArgs[8], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mJ.Lower(aArgs[9], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNegate.Lower(aArgs[10], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueFloat<double>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_sum_with_many_types(
+ mA.IntoRust(),
+ mB.IntoRust(),
+ mC.IntoRust(),
+ mD.IntoRust(),
+ mE.IntoRust(),
+ mF.IntoRust(),
+ mG.IntoRust(),
+ mH.IntoRust(),
+ mI.IntoRust(),
+ mJ.IntoRust(),
+ mNegate.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSwapTestInterfaces : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mInterfaces{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInterfaces.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_func_swap_test_interfaces(
+ mInterfaces.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncTestFunc : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_func_test_func(
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorTestinterfaceNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint32_t> mValue{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mValue.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
+ uniffi_uniffi_bindings_tests_fn_constructor_testinterface_new(
+ mValue.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceGetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_testinterface_get_value(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceRefCount : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_testinterface_ref_count(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorAsyncinterfaceNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mName{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mName.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsAsyncInterface::FromRust(
+ uniffi_uniffi_bindings_tests_fn_constructor_asyncinterface_new(
+ mName.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncInterface mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asyncinterface_name(
+ mUniffiPtr.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_noop(
+ mUniffiPtr.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_u32,
+ ffi_uniffi_bindings_tests_rust_future_free_u32
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_get_value(
+ mUniffiPtr.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_u32(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_void,
+ ffi_uniffi_bindings_tests_rust_future_free_void
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ FfiValueInt<uint32_t> mValue{};
+ mValue.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_set_value(
+ mUniffiPtr.IntoRust(),
+ mValue.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ ffi_uniffi_bindings_tests_rust_future_complete_void(mFutureHandle, aOutStatus);
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual : public UniffiAsyncCallHandler {
+public:
+ ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual() : UniffiAsyncCallHandler(
+ ffi_uniffi_bindings_tests_rust_future_poll_rust_buffer,
+ ffi_uniffi_bindings_tests_rust_future_free_rust_buffer
+ ) { }
+
+private:
+ // Complete stores the result of the call in mUniffiReturnValue
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+protected:
+ // Convert a sequence of JS arguments and call the scaffolding function.
+ // Always called on the main thread since async Rust calls don't block, they
+ // return a future.
+ void LowerArgsAndMakeRustCall(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ FfiValueObjectHandleUniffiBindingsTestsAsyncTestTraitInterface mUniffiPtr{};
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ FfiValueRustBuffer mNumbers{};
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+
+ mFutureHandle = uniffi_uniffi_bindings_tests_fn_method_asynctesttraitinterface_throw_if_equal(
+ mUniffiPtr.IntoRust(),
+ mNumbers.IntoRust()
+ );
+ }
+
+ void CallCompleteFn(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ ffi_uniffi_bindings_tests_rust_future_complete_rust_buffer(mFutureHandle, aOutStatus));
+ }
+
+public:
+ void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorComplexmethodsNew : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsComplexMethods::FromRust(
+ uniffi_uniffi_bindings_tests_fn_constructor_complexmethods_new(
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithDefault : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiPtr{};
+ FfiValueRustBuffer mArg{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mArg.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_default(
+ mUniffiPtr.IntoRust(),
+ mArg.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithMultiWordArg : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsComplexMethods mUniffiPtr{};
+ FfiValueRustBuffer mTheArgument{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mTheArgument.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_complexmethods_method_with_multi_word_arg(
+ mUniffiPtr.IntoRust(),
+ mTheArgument.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceNoop : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_noop(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceGetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint32_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint32_t>::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_get_value(
+ mUniffiPtr.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceSetValue : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+ FfiValueInt<uint32_t> mValue{};
+
+ // MakeRustCall stores the result of the call in these fields
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mValue.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_set_value(
+ mUniffiPtr.IntoRust(),
+ mValue.IntoRust(),
+ aOutStatus
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceThrowIfEqual : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestTraitInterface mUniffiPtr{};
+ FfiValueRustBuffer mNumbers{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 2) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal (expected: 2, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mUniffiPtr.LowerReciever(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ mNumbers.Lower(aArgs[1], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_fn_method_testtraitinterface_throw_if_equal(
+ mUniffiPtr.IntoRust(),
+ mNumbers.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsCollisionFnFuncInvokeCollisionCallback : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueCallbackInterfaceuniffi_bindings_tests_collision_TestCallbackInterface mCb{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCb.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_collision_fn_func_invoke_collision_callback(
+ mCb.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtCustomType : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueInt<uint64_t> mCustom{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueInt<uint64_t> mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mCustom.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueInt<uint64_t>::FromRust(
+ uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_custom_type(
+ mCustom.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtEnum : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mEn{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mEn.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_enum(
+ mEn.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtInterface : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mInt{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueObjectHandleUniffiBindingsTestsTestInterface mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mInt.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueObjectHandleUniffiBindingsTestsTestInterface::FromRust(
+ uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_interface(
+ mInt.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+class ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtRecord : public UniffiSyncCallHandler {
+private:
+ // LowerRustArgs stores the resulting arguments in these fields
+ FfiValueRustBuffer mRec{};
+
+ // MakeRustCall stores the result of the call in these fields
+ FfiValueRustBuffer mUniffiReturnValue{};
+
+public:
+ void LowerRustArgs(const dom::Sequence<dom::OwningUniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
+ if (aArgs.Length() < 1) {
+ aError.ThrowUnknownError(nsPrintfCString("LowerRustArgs: Incorrect argument length for uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record (expected: 1, actual: %zu)", aArgs.Length()));
+ return;
+ }
+ mRec.Lower(aArgs[0], aError);
+ if (aError.Failed()) {
+ return;
+ }
+ }
+
+ void MakeRustCall(RustCallStatus* aOutStatus) override {
+ mUniffiReturnValue = FfiValueRustBuffer::FromRust(
+ uniffi_uniffi_bindings_tests_external_types_fn_func_roundtrip_ext_record(
+ mRec.IntoRust(),
+ aOutStatus
+ )
+ );
+ }
+
+ virtual void LiftSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::OwningUniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
+ mUniffiReturnValue.Lift(
+ aCx,
+ &aDest.Construct(),
+ aError
+ );
+ }
+};
+#endif /* MOZ_UNIFFI_FIXTURES */
+
+UniquePtr<UniffiSyncCallHandler> GetSyncCallHandler(uint64_t aId) {
+ switch (aId) {
+
+ case 1: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiContextIdFnConstructorContextidcomponentNew>();
}
case 2: {
return MakeUnique<ScaffoldingCallHandlerUniffiContextIdFnMethodContextidcomponentForceRotation>();
@@ -11602,944 +14151,1499 @@ UniquePtr<UniffiSyncCallHandler> GetSyncCallHandler(uint64_t aId) {
return MakeUnique<ScaffoldingCallHandlerUniffiFilterAdultFnMethodFilteradultcomponentContains>();
}
case 7: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnFuncScore>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiInitRustComponentsFnFuncInitialize>();
}
case 8: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnConstructorRelevancystoreNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCheckCanary>();
}
case 9: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditInit>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateCanary>();
}
case 10: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditSelect>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateKey>();
}
case 11: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditUpdate>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateLoginStoreWithNssKeymanager>();
}
case 12: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreClose>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateLoginStoreWithStaticKeyManager>();
}
case 13: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreEnsureInterestDataPopulated>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateManagedEncdec>();
}
case 14: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreGetBanditData>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnFuncCreateStaticKeyManager>();
}
case 15: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreIngest>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodEncryptordecryptorDecrypt>();
}
case 16: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreInterrupt>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodEncryptordecryptorEncrypt>();
}
case 17: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreUserInterestVector>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodKeymanagerGetKey>();
}
case 18: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnConstructorLoginstoreNew>();
}
case 19: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsDownloadAttachmentToPath>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAdd>();
}
case 20: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecords>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddMany>();
}
case 21: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecordsSince>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddManyWithMeta>();
}
case 22: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientCollectionName>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddOrUpdate>();
}
case 23: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetAttachment>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreAddWithMeta>();
}
case 24: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecords>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCount>();
}
case 25: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecordsMap>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCountByFormActionOrigin>();
}
case 26: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientShutdown>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreCountByOrigin>();
}
case 27: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientSync>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDelete>();
}
case 28: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsserviceNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDeleteMany>();
}
case 29: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceMakeClient>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreDeleteUndecryptableRecordsForRemoteReplacement>();
}
case 30: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceSync>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreFindLoginToUpdate>();
}
case 31: {
- return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceUpdateConfig>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGet>();
}
case 32: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGetByBaseDomain>();
}
case 33: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorClearSearchConfig>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreGetCheckpoint>();
}
case 34: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorFilterEngineConfiguration>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreHasLoginsByBaseDomain>();
}
case 35: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreIsEmpty>();
}
case 36: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreList>();
}
case 37: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreRegisterWithSyncManager>();
}
case 38: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreReset>();
}
case 39: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreRunMaintenance>();
}
case 40: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreAnyDismissedSuggestions>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreSetCheckpoint>();
}
case 41: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreShutdown>();
}
case 42: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreTouch>();
}
case 43: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissByKey>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreUpdate>();
}
case 44: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissBySuggestion>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodLoginstoreWipeLocal>();
}
case 45: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnConstructorManagedencryptordecryptorNew>();
}
case 46: {
- return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonameAlternates>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnConstructorNsskeymanagerNew>();
}
case 47: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodNsskeymanagerIntoDynKeyManager>();
+ }
+ case 51: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnConstructorStatickeymanagerNew>();
+ }
+ case 52: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnFuncScore>();
+ }
+ case 53: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnConstructorRelevancystoreNew>();
+ }
+ case 54: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditInit>();
+ }
+ case 55: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditSelect>();
+ }
+ case 56: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreBanditUpdate>();
+ }
+ case 57: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreClose>();
+ }
+ case 58: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreEnsureInterestDataPopulated>();
+ }
+ case 59: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreGetBanditData>();
+ }
+ case 60: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreIngest>();
+ }
+ case 61: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreInterrupt>();
+ }
+ case 62: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRelevancyFnMethodRelevancystoreUserInterestVector>();
+ }
+ case 63: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsNew>();
+ }
+ case 64: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsDownloadAttachmentToPath>();
+ }
+ case 65: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecords>();
+ }
+ case 66: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsGetRecordsSince>();
+ }
+ case 67: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientCollectionName>();
+ }
+ case 68: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetAttachment>();
+ }
+ case 69: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecords>();
+ }
+ case 70: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientGetRecordsMap>();
+ }
+ case 71: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientShutdown>();
+ }
+ case 72: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsclientSync>();
+ }
+ case 73: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnConstructorRemotesettingsserviceNew>();
+ }
+ case 74: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceMakeClient>();
+ }
+ case 75: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceSync>();
+ }
+ case 76: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiRemoteSettingsFnMethodRemotesettingsserviceUpdateConfig>();
+ }
+ case 77: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew>();
+ }
+ case 78: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorClearSearchConfig>();
+ }
+ case 79: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorFilterEngineConfiguration>();
+ }
+ case 80: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides>();
+ }
+ case 81: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig>();
+ }
+ case 82: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer>();
+ }
+ case 83: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches>();
+ }
+ case 84: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew>();
+ }
+ case 85: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreAnyDismissedSuggestions>();
+ }
+ case 86: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear>();
+ }
+ case 87: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions>();
+ }
+ case 88: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissByKey>();
+ }
+ case 89: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissBySuggestion>();
+ }
+ case 90: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion>();
+ }
+ case 91: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonameAlternates>();
+ }
+ case 92: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames>();
}
- case 48: {
+ case 93: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGlobalConfig>();
}
- case 49: {
+ case 94: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchProviderConfig>();
}
- case 50: {
+ case 95: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIngest>();
}
- case 51: {
+ case 96: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreInterrupt>();
}
- case 52: {
+ case 97: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedByKey>();
}
- case 53: {
+ case 98: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIsDismissedBySuggestion>();
}
- case 54: {
+ case 99: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQuery>();
}
- case 55: {
+ case 100: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQueryWithMetrics>();
}
- case 56: {
+ case 101: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststorebuilderNew>();
}
- case 57: {
+ case 102: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderBuild>();
}
- case 58: {
+ case 103: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderCachePath>();
}
- case 59: {
+ case 104: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderDataPath>();
}
- case 60: {
+ case 105: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderLoadExtension>();
}
- case 61: {
+ case 106: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsBucketName>();
}
- case 62: {
+ case 107: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsServer>();
}
- case 63: {
+ case 108: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsService>();
}
- case 64: {
+ case 109: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommand>();
}
- case 65: {
+ case 110: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommandAt>();
}
- case 66: {
+ case 111: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreGetUnsentCommands>();
}
- case 67: {
+ case 112: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreRemoveRemoteCommand>();
}
- case 68: {
+ case 113: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreSetPendingCommandSent>();
}
- case 69: {
+ case 114: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineApply>();
}
- case 70: {
+ case 115: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineEnsureCurrentSyncId>();
}
- case 71: {
+ case 116: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineLastSync>();
}
- case 72: {
+ case 117: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedenginePrepareForSync>();
}
- case 73: {
+ case 118: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineReset>();
}
- case 74: {
+ case 119: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineResetSyncId>();
}
- case 75: {
+ case 120: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetLastSync>();
}
- case 76: {
+ case 121: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetUploaded>();
}
- case 77: {
+ case 122: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineStoreIncoming>();
}
- case 78: {
+ case 123: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncFinished>();
}
- case 79: {
+ case 124: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncId>();
}
- case 80: {
+ case 125: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncStarted>();
}
- case 81: {
+ case 126: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineWipe>();
}
- case 82: {
+ case 127: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnConstructorTabsstoreNew>();
}
- case 83: {
+ case 128: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreBridgedEngine>();
}
- case 84: {
+ case 129: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreCloseConnection>();
}
- case 85: {
+ case 130: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreGetAll>();
}
- case 86: {
+ case 131: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreNewRemoteCommandStore>();
}
- case 87: {
+ case 132: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreRegisterWithSyncManager>();
}
- case 88: {
+ case 133: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreSetLocalTabs>();
}
- case 89: {
+ case 134: {
return MakeUnique<ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterEventSink>();
}
- case 90: {
+ case 135: {
return MakeUnique<ScaffoldingCallHandlerUniffiTracingSupportFnFuncRegisterMinLevelEventSink>();
}
- case 91: {
+ case 136: {
return MakeUnique<ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterEventSink>();
}
- case 92: {
+ case 137: {
return MakeUnique<ScaffoldingCallHandlerUniffiTracingSupportFnFuncUnregisterMinLevelEventSink>();
}
- case 93: {
+ case 138: {
return MakeUnique<ScaffoldingCallHandlerUniffiViaductFnFuncAllowAndroidEmulatorLoopback>();
}
- case 94: {
+ case 139: {
return MakeUnique<ScaffoldingCallHandlerUniffiViaductFnFuncInitBackend>();
}
- case 96: {
+ case 141: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineApply>();
}
- case 97: {
+ case 142: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineEnsureCurrentSyncId>();
}
- case 98: {
+ case 143: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineLastSync>();
}
- case 99: {
+ case 144: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedenginePrepareForSync>();
}
- case 100: {
+ case 145: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineReset>();
}
- case 101: {
+ case 146: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineResetSyncId>();
}
- case 102: {
+ case 147: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetLastSync>();
}
- case 103: {
+ case 148: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetUploaded>();
}
- case 104: {
+ case 149: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineStoreIncoming>();
}
- case 105: {
+ case 150: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncFinished>();
}
- case 106: {
+ case 151: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncId>();
}
- case 107: {
+ case 152: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncStarted>();
}
- case 108: {
+ case 153: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineWipe>();
}
- case 109: {
+ case 154: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnConstructorWebextstoragestoreNew>();
}
- case 110: {
+ case 155: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreBridgedEngine>();
}
- case 111: {
+ case 156: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClear>();
}
- case 112: {
+ case 157: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClose>();
}
- case 113: {
+ case 158: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGet>();
}
- case 114: {
+ case 159: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetBytesInUse>();
}
- case 115: {
+ case 160: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetKeys>();
}
- case 116: {
+ case 161: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetSyncedChanges>();
}
- case 117: {
+ case 162: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreRemove>();
}
- case 118: {
+ case 163: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreSet>();
}
#ifdef MOZ_UNIFFI_FIXTURES
- case 134: {
+ case 179: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCloneInterface>();
}
- case 135: {
+ case 180: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateAsyncTestTraitInterface>();
}
- case 136: {
+ case 181: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncCreateTestTraitInterface>();
}
- case 137: {
+ case 182: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithDefault>();
}
- case 138: {
+ case 183: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithError>();
}
- case 139: {
+ case 184: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithFlatError>();
}
- case 140: {
+ case 185: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncFuncWithMultiWordArg>();
}
- case 141: {
+ case 186: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncGetCustomTypesDemo>();
}
- case 150: {
+ case 195: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceGetValue>();
}
- case 151: {
+ case 196: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceNoop>();
}
- case 152: {
+ case 197: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceSetValue>();
}
- case 153: {
+ case 198: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestCallbackInterfaceThrowIfEqual>();
}
- case 154: {
+ case 199: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceGetValue>();
}
- case 155: {
+ case 200: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceNoop>();
}
- case 156: {
+ case 201: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceSetValue>();
}
- case 157: {
+ case 202: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestTraitInterfaceThrowIfEqual>();
}
- case 158: {
+ case 203: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripBool>();
}
- case 159: {
+ case 204: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexCompound>();
}
- case 160: {
+ case 205: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexEnum>();
}
- case 161: {
+ case 206: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripComplexRec>();
}
- case 162: {
+ case 207: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripCustomType>();
}
- case 163: {
+ case 208: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumNoData>();
}
- case 164: {
+ case 209: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripEnumWithData>();
}
- case 165: {
+ case 210: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF32>();
}
- case 166: {
+ case 211: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripF64>();
}
- case 167: {
+ case 212: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripHashMap>();
}
- case 168: {
+ case 213: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI16>();
}
- case 169: {
+ case 214: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI32>();
}
- case 170: {
+ case 215: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI64>();
}
- case 171: {
+ case 216: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripI8>();
}
+ case 217: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripOption>();
+ }
+ case 218: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripSimpleRec>();
+ }
+ case 219: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripString>();
+ }
+ case 220: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalMs>();
+ }
+ case 221: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecDbl>();
+ }
+ case 222: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecFlt>();
+ }
+ case 223: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU16>();
+ }
+ case 224: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU32>();
+ }
+ case 225: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU64>();
+ }
+ case 226: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU8>();
+ }
+ case 227: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripUrl>();
+ }
+ case 228: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripVec>();
+ }
+ case 229: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSumWithManyTypes>();
+ }
+ case 230: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSwapTestInterfaces>();
+ }
+ case 231: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncTestFunc>();
+ }
+ case 232: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorTestinterfaceNew>();
+ }
+ case 233: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceGetValue>();
+ }
+ case 234: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceRefCount>();
+ }
+ case 235: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorAsyncinterfaceNew>();
+ }
+ case 241: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorComplexmethodsNew>();
+ }
+ case 242: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithDefault>();
+ }
+ case 243: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithMultiWordArg>();
+ }
+ case 244: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceNoop>();
+ }
+ case 245: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceGetValue>();
+ }
+ case 246: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceSetValue>();
+ }
+ case 247: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceThrowIfEqual>();
+ }
+ case 248: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsCollisionFnFuncInvokeCollisionCallback>();
+ }
+ case 249: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtCustomType>();
+ }
+ case 250: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtEnum>();
+ }
+ case 251: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtInterface>();
+ }
+ case 252: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtRecord>();
+ }
+#endif /* MOZ_UNIFFI_FIXTURES */
+
+ default:
+ return nullptr;
+ }
+}
+
+UniquePtr<UniffiAsyncCallHandler> GetAsyncCallHandler(uint64_t aId) {
+ switch (aId) {
+
+ case 48: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorGetPrimaryPassword>();
+ }
+ case 49: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationSuccess>();
+ }
+ case 50: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiLoginsFnMethodPrimarypasswordauthenticatorOnAuthenticationFailure>();
+ }
+ case 140: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest>();
+ }
+
+#ifdef MOZ_UNIFFI_FIXTURES
+ case 164: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32>();
+ }
+ case 165: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64>();
+ }
+ case 166: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16>();
+ }
+ case 167: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32>();
+ }
+ case 168: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64>();
+ }
+ case 169: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8>();
+ }
+ case 170: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap>();
+ }
+ case 171: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj>();
+ }
case 172: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripOption>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString>();
}
case 173: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripSimpleRec>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16>();
}
case 174: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripString>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32>();
}
case 175: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalMs>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64>();
}
case 176: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecDbl>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8>();
}
case 177: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripTimeIntervalSecFlt>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec>();
}
case 178: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU16>();
- }
- case 179: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU32>();
- }
- case 180: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU64>();
- }
- case 181: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripU8>();
- }
- case 182: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripUrl>();
- }
- case 183: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncRoundtripVec>();
- }
- case 184: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSumWithManyTypes>();
- }
- case 185: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncSwapTestInterfaces>();
- }
- case 186: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncTestFunc>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError>();
}
case 187: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorTestinterfaceNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue>();
}
case 188: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceGetValue>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop>();
}
case 189: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTestinterfaceRefCount>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue>();
}
case 190: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorAsyncinterfaceNew>();
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual>();
}
- case 196: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnConstructorComplexmethodsNew>();
+ case 191: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue>();
}
- case 197: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithDefault>();
+ case 192: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop>();
}
- case 198: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodComplexmethodsMethodWithMultiWordArg>();
+ case 193: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue>();
}
- case 199: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceNoop>();
+ case 194: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual>();
}
- case 200: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceGetValue>();
+ case 236: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName>();
}
- case 201: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceSetValue>();
+ case 237: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop>();
}
- case 202: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodTesttraitinterfaceThrowIfEqual>();
+ case 238: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue>();
}
- case 203: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsCollisionFnFuncInvokeCollisionCallback>();
+ case 239: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue>();
}
- case 204: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtCustomType>();
+ case 240: {
+ return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual>();
}
- case 205: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtEnum>();
+#endif /* MOZ_UNIFFI_FIXTURES */
+
+ default:
+ return nullptr;
+ }
+}
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+
+/**
+ * Handle callback interface return values for a single return type
+ */
+class CallbackLowerReturnVoid {
+public:
+ /**
+ * Lower return values
+ *
+ * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
+ * something that can be passed to Rust.
+ *
+ * - On success, it returns the FFI return value
+ * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
+ */
+ static void
+ Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ RustCallStatus* aOutCallStatus,
+ ErrorResult& aRv) {
+ aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
+ switch (aCallResult.mCode) {
+ case UniFFIScaffoldingCallCode::Success: {
+ aOutCallStatus->code = RUST_CALL_SUCCESS;
+ break;
+ }
+
+ case UniFFIScaffoldingCallCode::Error: {
+ if (!aCallResult.mData.WasPassed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] No data passed"));
+ break;
+ }
+ FfiValueRustBuffer errorBuf;
+ errorBuf.Lower(aCallResult.mData.Value(), aRv);
+ if (aRv.Failed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] Failed to lower error buffer"));
+ break;
+ }
+
+ aOutCallStatus->error_buf = errorBuf.IntoRust();
+ aOutCallStatus->code = RUST_CALL_ERROR;
+ break;
+ }
+
+ default: {
+ break;
+ }
}
- case 206: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtInterface>();
+
+ }
+};
+
+/**
+ * Handle callback interface return values for a single return type
+ */
+class CallbackLowerReturnRustBuffer {
+public:
+ /**
+ * Lower return values
+ *
+ * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
+ * something that can be passed to Rust.
+ *
+ * - On success, it returns the FFI return value
+ * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
+ */
+ static RustBuffer
+ Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ RustCallStatus* aOutCallStatus,
+ ErrorResult& aRv) {
+ aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
+ FfiValueRustBuffer returnValue;
+ switch (aCallResult.mCode) {
+ case UniFFIScaffoldingCallCode::Success: {
+ if (!aCallResult.mData.WasPassed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] No data passed"));
+ break;
+ }
+ returnValue.Lower(aCallResult.mData.Value(), aRv);
+ if (aRv.Failed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] Failed to lower return value"));
+ break;
+ }
+ aOutCallStatus->code = RUST_CALL_SUCCESS;
+ break;
+ }
+
+ case UniFFIScaffoldingCallCode::Error: {
+ if (!aCallResult.mData.WasPassed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] No data passed"));
+ break;
+ }
+ FfiValueRustBuffer errorBuf;
+ errorBuf.Lower(aCallResult.mData.Value(), aRv);
+ if (aRv.Failed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] Failed to lower error buffer"));
+ break;
+ }
+
+ aOutCallStatus->error_buf = errorBuf.IntoRust();
+ aOutCallStatus->code = RUST_CALL_ERROR;
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ return returnValue.IntoRust();
+ }
+};
+
+#ifdef MOZ_UNIFFI_FIXTURES
+
+/**
+ * Handle callback interface return values for a single return type
+ */
+class CallbackLowerReturnUInt32 {
+public:
+ /**
+ * Lower return values
+ *
+ * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
+ * something that can be passed to Rust.
+ *
+ * - On success, it returns the FFI return value
+ * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
+ */
+ static uint32_t
+ Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ RustCallStatus* aOutCallStatus,
+ ErrorResult& aRv) {
+ aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
+ FfiValueInt<uint32_t> returnValue;
+ switch (aCallResult.mCode) {
+ case UniFFIScaffoldingCallCode::Success: {
+ if (!aCallResult.mData.WasPassed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] No data passed"));
+ break;
+ }
+ returnValue.Lower(aCallResult.mData.Value(), aRv);
+ if (aRv.Failed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] Failed to lower return value"));
+ break;
+ }
+ aOutCallStatus->code = RUST_CALL_SUCCESS;
+ break;
+ }
+
+ case UniFFIScaffoldingCallCode::Error: {
+ if (!aCallResult.mData.WasPassed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] No data passed"));
+ break;
+ }
+ FfiValueRustBuffer errorBuf;
+ errorBuf.Lower(aCallResult.mData.Value(), aRv);
+ if (aRv.Failed()) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] Failed to lower error buffer"));
+ break;
+ }
+
+ aOutCallStatus->error_buf = errorBuf.IntoRust();
+ aOutCallStatus->code = RUST_CALL_ERROR;
+ break;
+ }
+
+ default: {
+ break;
+ }
}
- case 207: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsExternalTypesFnFuncRoundtripExtRecord>();
+
+ return returnValue.IntoRust();
}
+};
#endif /* MOZ_UNIFFI_FIXTURES */
- default:
- return nullptr;
- }
-}
+// Callback interface method handlers, vtables, etc.
-UniquePtr<UniffiAsyncCallHandler> GetAsyncCallHandler(uint64_t aId) {
- switch (aId) {
+static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerContextIdContextIdCallback;
+/**
+ * Callback method handler subclass for callback_interface_context_id_context_id_callback_persist
+ *
+ * This is like the handler for an async function except:
+ *
+ * - It doesn't input the complete callback function/data
+ * - It doesn't override HandleReturn and returns `nullptr` from MakeCall.
+ * This means ScheduleAsyncCall will schedule `MakeCall` and not do anything
+ * with the result, which is what we want.
+ */
+class CallbackInterfaceMethodContextIdContextIdCallbackPersist final : public AsyncCallbackMethodHandlerBase {
+private:
+ // Rust arguments
+ FfiValueRustBuffer mContextId{};
+ FfiValueInt<int64_t> mCreationDate{};
- case 95: {
- return MakeUnique<ScaffoldingCallHandlerUniffiViaductFnMethodBackendSendRequest>();
- }
+public:
+ CallbackInterfaceMethodContextIdContextIdCallbackPersist(
+ uint64_t aUniffiHandle,
+ RustBuffer aContextId,
+ int64_t aCreationDate
+ ) : AsyncCallbackMethodHandlerBase ("ContextIdCallback.callback_interface_context_id_context_id_callback_persist", aUniffiHandle),
+ mContextId(FfiValueRustBuffer::FromRust(aContextId)),
+ mCreationDate(FfiValueInt<int64_t>::FromRust(aCreationDate)){ }
-#ifdef MOZ_UNIFFI_FIXTURES
- case 119: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF32>();
- }
- case 120: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripF64>();
- }
- case 121: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI16>();
- }
- case 122: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI32>();
- }
- case 123: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI64>();
- }
- case 124: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripI8>();
- }
- case 125: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripMap>();
- }
- case 126: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripObj>();
- }
- case 127: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripString>();
- }
- case 128: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU16>();
- }
- case 129: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU32>();
- }
- case 130: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU64>();
- }
- case 131: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripU8>();
- }
- case 132: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncRoundtripVec>();
- }
- case 133: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncAsyncThrowError>();
- }
- case 142: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceGetValue>();
- }
- case 143: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceNoop>();
- }
- case 144: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceSetValue>();
- }
- case 145: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeAsyncTestTraitInterfaceThrowIfEqual>();
- }
- case 146: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceGetValue>();
- }
- case 147: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceNoop>();
- }
- case 148: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceSetValue>();
- }
- case 149: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnFuncInvokeTestAsyncCallbackInterfaceThrowIfEqual>();
- }
- case 191: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsyncinterfaceName>();
+ MOZ_CAN_RUN_SCRIPT
+ already_AddRefed<dom::Promise>
+ MakeCall(JSContext* aCx, dom::UniFFICallbackHandler* aJsHandler, ErrorResult& aError) override {
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(2, mozilla::fallible)) {
+ aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
}
- case 192: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceNoop>();
+ mContextId.Lift(aCx, &uniffiArgs[0], aError);
+ if (aError.Failed()) {
+ return nullptr;
}
- case 193: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceGetValue>();
+ mCreationDate.Lift(aCx, &uniffiArgs[1], aError);
+ if (aError.Failed()) {
+ return nullptr;
}
- case 194: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceSetValue>();
+
+ RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 0, uniffiArgs, aError);
+ return nullptr;
+ }
+};
+
+/**
+ * callback_interface_context_id_context_id_callback_persist -- C function to handle the callback method
+ *
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_context_id_context_id_callback_persist(
+ uint64_t aUniffiHandle,
+ RustBuffer aContextId,
+ int64_t aCreationDate,
+ void* aUniffiOutReturn,
+ RustCallStatus* uniffiOutStatus
+) {
+ UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodContextIdContextIdCallbackPersist>(aUniffiHandle, aContextId, aCreationDate);
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerContextIdContextIdCallback);
+}
+/**
+ * Callback method handler subclass for callback_interface_context_id_context_id_callback_rotated
+ *
+ * This is like the handler for an async function except:
+ *
+ * - It doesn't input the complete callback function/data
+ * - It doesn't override HandleReturn and returns `nullptr` from MakeCall.
+ * This means ScheduleAsyncCall will schedule `MakeCall` and not do anything
+ * with the result, which is what we want.
+ */
+class CallbackInterfaceMethodContextIdContextIdCallbackRotated final : public AsyncCallbackMethodHandlerBase {
+private:
+ // Rust arguments
+ FfiValueRustBuffer mOldContextId{};
+
+public:
+ CallbackInterfaceMethodContextIdContextIdCallbackRotated(
+ uint64_t aUniffiHandle,
+ RustBuffer aOldContextId
+ ) : AsyncCallbackMethodHandlerBase ("ContextIdCallback.callback_interface_context_id_context_id_callback_rotated", aUniffiHandle),
+ mOldContextId(FfiValueRustBuffer::FromRust(aOldContextId)){ }
+
+ MOZ_CAN_RUN_SCRIPT
+ already_AddRefed<dom::Promise>
+ MakeCall(JSContext* aCx, dom::UniFFICallbackHandler* aJsHandler, ErrorResult& aError) override {
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(1, mozilla::fallible)) {
+ aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
}
- case 195: {
- return MakeUnique<ScaffoldingCallHandlerUniffiUniffiBindingsTestsFnMethodAsynctesttraitinterfaceThrowIfEqual>();
+ mOldContextId.Lift(aCx, &uniffiArgs[0], aError);
+ if (aError.Failed()) {
+ return nullptr;
}
-#endif /* MOZ_UNIFFI_FIXTURES */
- default:
- return nullptr;
+ RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 1, uniffiArgs, aError);
+ return nullptr;
+ }
+};
+
+/**
+ * callback_interface_context_id_context_id_callback_rotated -- C function to handle the callback method
+ *
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_context_id_context_id_callback_rotated(
+ uint64_t aUniffiHandle,
+ RustBuffer aOldContextId,
+ void* aUniffiOutReturn,
+ RustCallStatus* uniffiOutStatus
+) {
+ UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodContextIdContextIdCallbackRotated>(aUniffiHandle, aOldContextId);
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerContextIdContextIdCallback);
+}
+
+extern "C" void callback_free_context_id_context_id_callback(uint64_t uniffiHandle) {
+ // Callback object handles are keys in a map stored in the JS handler. To
+ // handle the free call, schedule a fire-and-forget JS call to remove the key.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(
+ MakeUnique<CallbackFreeHandler>("ContextIdCallback.uniffi_free", uniffiHandle),
+ &gUniffiCallbackHandlerContextIdContextIdCallback);
+}
+
+static VTableCallbackInterfaceContextIdContextIdCallback kUniffiVtableContextIdContextIdCallback {
+ callback_interface_context_id_context_id_callback_persist,
+ callback_interface_context_id_context_id_callback_rotated,
+ callback_free_context_id_context_id_callback
+};
+static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerLoginsEncryptorDecryptor;
+/**
+ * callback_interface_logins_encryptor_decryptor_decrypt -- C function to handle the callback method
+ *
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_logins_encryptor_decryptor_decrypt(
+ uint64_t aUniffiHandle,
+ RustBuffer aCiphertext,
+ RustBuffer* aUniffiOutReturn,
+ RustCallStatus* aUniffiOutStatus
+) {
+ MOZ_RELEASE_ASSERT(NS_IsMainThread());
+ // Take our own reference to the callback handler to ensure that it
+ // stays alive for the duration of this call
+ RefPtr<dom::UniFFICallbackHandler> jsHandler = gUniffiCallbackHandlerLoginsEncryptorDecryptor;
+ // Create a JS context for the call
+ JSObject* global = jsHandler->CallbackGlobalOrNull();
+ if (!global) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_encryptor_decryptor_decrypt] JS handler has null global"));
+ return;
+ }
+ dom::AutoEntryScript aes(global, "callback_interface_logins_encryptor_decryptor_decrypt");
+
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(1, mozilla::fallible)) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_encryptor_decryptor_decrypt] Failed to allocate arguments"));
+ return;
+ }
+ IgnoredErrorResult error;
+ FfiValueRustBuffer ciphertext = FfiValueRustBuffer::FromRust(aCiphertext);
+ ciphertext.Lift(aes.cx(), &uniffiArgs[0], error);
+ if (error.Failed()) {
+ MOZ_LOG(
+ gUniffiLogger, LogLevel::Error,
+ ("[callback_interface_logins_encryptor_decryptor_decrypt] Failed to lift aCiphertext"));
+ return;
}
-}
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 https://mozilla.org/MPL/2.0/. */
-
+ RootedDictionary<UniFFIScaffoldingCallResult> callResult(aes.cx());
+ jsHandler->CallSync(aUniffiHandle, 0, uniffiArgs, callResult, error);
+ if (error.Failed()) {
+ MOZ_LOG(
+ gUniffiLogger, LogLevel::Error,
+ ("[callback_interface_logins_encryptor_decryptor_decrypt] Error invoking JS handler"));
+ return;
+ }
+ *aUniffiOutReturn = CallbackLowerReturnRustBuffer::Lower(callResult, aUniffiOutStatus, error);
+ }
/**
- * Handle callback interface return values for a single return type
- */
-class CallbackLowerReturnVoid {
-public:
- /**
- * Lower return values
- *
- * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
- * something that can be passed to Rust.
- *
- * - On success, it returns the FFI return value
- * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
- */
- static void
- Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
- RustCallStatus* aOutCallStatus,
- ErrorResult& aRv) {
- aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
- switch (aCallResult.mCode) {
- case UniFFIScaffoldingCallCode::Success: {
- aOutCallStatus->code = RUST_CALL_SUCCESS;
- break;
- }
+ * callback_interface_logins_encryptor_decryptor_encrypt -- C function to handle the callback method
+ *
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_logins_encryptor_decryptor_encrypt(
+ uint64_t aUniffiHandle,
+ RustBuffer aCleartext,
+ RustBuffer* aUniffiOutReturn,
+ RustCallStatus* aUniffiOutStatus
+) {
+ MOZ_RELEASE_ASSERT(NS_IsMainThread());
+ // Take our own reference to the callback handler to ensure that it
+ // stays alive for the duration of this call
+ RefPtr<dom::UniFFICallbackHandler> jsHandler = gUniffiCallbackHandlerLoginsEncryptorDecryptor;
+ // Create a JS context for the call
+ JSObject* global = jsHandler->CallbackGlobalOrNull();
+ if (!global) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_encryptor_decryptor_encrypt] JS handler has null global"));
+ return;
+ }
+ dom::AutoEntryScript aes(global, "callback_interface_logins_encryptor_decryptor_encrypt");
- case UniFFIScaffoldingCallCode::Error: {
- if (!aCallResult.mData.WasPassed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] No data passed"));
- break;
- }
- FfiValueRustBuffer errorBuf;
- errorBuf.Lower(aCallResult.mData.Value(), aRv);
- if (aRv.Failed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] Failed to lower error buffer"));
- break;
- }
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(1, mozilla::fallible)) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_encryptor_decryptor_encrypt] Failed to allocate arguments"));
+ return;
+ }
+ IgnoredErrorResult error;
+ FfiValueRustBuffer cleartext = FfiValueRustBuffer::FromRust(aCleartext);
+ cleartext.Lift(aes.cx(), &uniffiArgs[0], error);
+ if (error.Failed()) {
+ MOZ_LOG(
+ gUniffiLogger, LogLevel::Error,
+ ("[callback_interface_logins_encryptor_decryptor_encrypt] Failed to lift aCleartext"));
+ return;
+ }
- aOutCallStatus->error_buf = errorBuf.IntoRust();
- aOutCallStatus->code = RUST_CALL_ERROR;
- break;
- }
+ RootedDictionary<UniFFIScaffoldingCallResult> callResult(aes.cx());
+ jsHandler->CallSync(aUniffiHandle, 1, uniffiArgs, callResult, error);
+ if (error.Failed()) {
+ MOZ_LOG(
+ gUniffiLogger, LogLevel::Error,
+ ("[callback_interface_logins_encryptor_decryptor_encrypt] Error invoking JS handler"));
+ return;
+ }
+ *aUniffiOutReturn = CallbackLowerReturnRustBuffer::Lower(callResult, aUniffiOutStatus, error);
+ }
- default: {
- break;
- }
- }
+extern "C" void callback_free_logins_encryptor_decryptor(uint64_t uniffiHandle) {
+ // Callback object handles are keys in a map stored in the JS handler. To
+ // handle the free call, schedule a fire-and-forget JS call to remove the key.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(
+ MakeUnique<CallbackFreeHandler>("EncryptorDecryptor.uniffi_free", uniffiHandle),
+ &gUniffiCallbackHandlerLoginsEncryptorDecryptor);
+}
- }
+static VTableCallbackInterfaceLoginsEncryptorDecryptor kUniffiVtableLoginsEncryptorDecryptor {
+ callback_interface_logins_encryptor_decryptor_decrypt,
+ callback_interface_logins_encryptor_decryptor_encrypt,
+ callback_free_logins_encryptor_decryptor
};
-
+static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerLoginsKeyManager;
/**
- * Handle callback interface return values for a single return type
- */
-class CallbackLowerReturnRustBuffer {
-public:
- /**
- * Lower return values
- *
- * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
- * something that can be passed to Rust.
- *
- * - On success, it returns the FFI return value
- * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
- */
- static RustBuffer
- Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
- RustCallStatus* aOutCallStatus,
- ErrorResult& aRv) {
- aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
- FfiValueRustBuffer returnValue;
- switch (aCallResult.mCode) {
- case UniFFIScaffoldingCallCode::Success: {
- if (!aCallResult.mData.WasPassed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] No data passed"));
- break;
- }
- returnValue.Lower(aCallResult.mData.Value(), aRv);
- if (aRv.Failed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] Failed to lower return value"));
- break;
- }
- aOutCallStatus->code = RUST_CALL_SUCCESS;
- break;
- }
+ * callback_interface_logins_key_manager_get_key -- C function to handle the callback method
+ *
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_logins_key_manager_get_key(
+ uint64_t aUniffiHandle,
+ RustBuffer* aUniffiOutReturn,
+ RustCallStatus* aUniffiOutStatus
+) {
+ MOZ_RELEASE_ASSERT(NS_IsMainThread());
+ // Take our own reference to the callback handler to ensure that it
+ // stays alive for the duration of this call
+ RefPtr<dom::UniFFICallbackHandler> jsHandler = gUniffiCallbackHandlerLoginsKeyManager;
+ // Create a JS context for the call
+ JSObject* global = jsHandler->CallbackGlobalOrNull();
+ if (!global) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_key_manager_get_key] JS handler has null global"));
+ return;
+ }
+ dom::AutoEntryScript aes(global, "callback_interface_logins_key_manager_get_key");
- case UniFFIScaffoldingCallCode::Error: {
- if (!aCallResult.mData.WasPassed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] No data passed"));
- break;
- }
- FfiValueRustBuffer errorBuf;
- errorBuf.Lower(aCallResult.mData.Value(), aRv);
- if (aRv.Failed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] Failed to lower error buffer"));
- break;
- }
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(0, mozilla::fallible)) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[callback_interface_logins_key_manager_get_key] Failed to allocate arguments"));
+ return;
+ }
+ IgnoredErrorResult error;
- aOutCallStatus->error_buf = errorBuf.IntoRust();
- aOutCallStatus->code = RUST_CALL_ERROR;
- break;
- }
+ RootedDictionary<UniFFIScaffoldingCallResult> callResult(aes.cx());
+ jsHandler->CallSync(aUniffiHandle, 0, uniffiArgs, callResult, error);
+ if (error.Failed()) {
+ MOZ_LOG(
+ gUniffiLogger, LogLevel::Error,
+ ("[callback_interface_logins_key_manager_get_key] Error invoking JS handler"));
+ return;
+ }
+ *aUniffiOutReturn = CallbackLowerReturnRustBuffer::Lower(callResult, aUniffiOutStatus, error);
+ }
- default: {
- break;
- }
- }
+extern "C" void callback_free_logins_key_manager(uint64_t uniffiHandle) {
+ // Callback object handles are keys in a map stored in the JS handler. To
+ // handle the free call, schedule a fire-and-forget JS call to remove the key.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(
+ MakeUnique<CallbackFreeHandler>("KeyManager.uniffi_free", uniffiHandle),
+ &gUniffiCallbackHandlerLoginsKeyManager);
+}
- return returnValue.IntoRust();
- }
+static VTableCallbackInterfaceLoginsKeyManager kUniffiVtableLoginsKeyManager {
+ callback_interface_logins_key_manager_get_key,
+ callback_free_logins_key_manager
};
-
-#ifdef MOZ_UNIFFI_FIXTURES
-
+static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator;
/**
- * Handle callback interface return values for a single return type
- */
-class CallbackLowerReturnUInt32 {
+ * Callback method handler subclass for callback_interface_logins_primary_password_authenticator_get_primary_password
+ *
+ * This handles the specifics of the async call.
+ * AsyncCallbackMethodHandlerBase::ScheduleAsyncCall handles the general parts.
+ */
+class CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorGetPrimaryPassword final : public AsyncCallbackMethodHandlerBase {
+private:
+ // Rust arguments
+ ForeignFutureCompleterust_buffer mUniffiCompleteCallback;
+ uint64_t mUniffiCallbackData;
+
public:
- /**
- * Lower return values
- *
- * This inputs a UniFFIScaffoldingCallResult from JS and converts it to
- * something that can be passed to Rust.
- *
- * - On success, it returns the FFI return value
- * - On error, it updates the `RustCallStatus` struct and returns a default FFI value.
- */
- static uint32_t
- Lower(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
- RustCallStatus* aOutCallStatus,
- ErrorResult& aRv) {
- aOutCallStatus->code = RUST_CALL_INTERNAL_ERROR;
- FfiValueInt<uint32_t> returnValue;
- switch (aCallResult.mCode) {
- case UniFFIScaffoldingCallCode::Success: {
- if (!aCallResult.mData.WasPassed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] No data passed"));
- break;
- }
- returnValue.Lower(aCallResult.mData.Value(), aRv);
- if (aRv.Failed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] Failed to lower return value"));
- break;
- }
- aOutCallStatus->code = RUST_CALL_SUCCESS;
- break;
- }
+ CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorGetPrimaryPassword(
+ uint64_t aUniffiHandle,
+ ForeignFutureCompleterust_buffer aUniffiCompleteCallback,
+ uint64_t aUniffiCallbackData
+ ) : AsyncCallbackMethodHandlerBase ("PrimaryPasswordAuthenticator.callback_interface_logins_primary_password_authenticator_get_primary_password", aUniffiHandle),
+ mUniffiCompleteCallback(aUniffiCompleteCallback),
+ mUniffiCallbackData(aUniffiCallbackData) { }
- case UniFFIScaffoldingCallCode::Error: {
- if (!aCallResult.mData.WasPassed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] No data passed"));
- break;
- }
- FfiValueRustBuffer errorBuf;
- errorBuf.Lower(aCallResult.mData.Value(), aRv);
- if (aRv.Failed()) {
- MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnUInt32] Failed to lower error buffer"));
- break;
- }
+ MOZ_CAN_RUN_SCRIPT
+ already_AddRefed<dom::Promise>
+ MakeCall(JSContext* aCx, dom::UniFFICallbackHandler* aJsHandler, ErrorResult& aError) override {
+ // Convert arguments
+ nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
+ if (!uniffiArgs.AppendElements(0, mozilla::fallible)) {
+ aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
- aOutCallStatus->error_buf = errorBuf.IntoRust();
- aOutCallStatus->code = RUST_CALL_ERROR;
- break;
- }
+ RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 0, uniffiArgs, aError);
+ return result.forget();
+ }
- default: {
- break;
- }
+ void HandleReturn(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ ErrorResult& aRv) override {
+ if (!mUniffiCompleteCallback) {
+ MOZ_ASSERT_UNREACHABLE("HandleReturn called multiple times");
+ return;
}
- return returnValue.IntoRust();
+ ForeignFutureResultRustBuffer result{};
+ result.return_value = CallbackLowerReturnRustBuffer::Lower(aCallResult, &result.call_status, aRv);
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
+ mUniffiCompleteCallback = nullptr;
+ }
+
+ ~CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorGetPrimaryPassword() {
+ if (mUniffiCompleteCallback) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnRustBuffer] promise never completed"));
+ ForeignFutureResultRustBuffer result{};
+ result.call_status.code = RUST_CALL_INTERNAL_ERROR;
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
}
+ }
};
-#endif /* MOZ_UNIFFI_FIXTURES */
-
-// Callback interface method handlers, vtables, etc.
-static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerContextIdContextIdCallback;
/**
- * Callback method handler subclass for callback_interface_context_id_context_id_callback_persist
+ * callback_interface_logins_primary_password_authenticator_get_primary_password -- C function to handle the callback method
*
- * This is like the handler for an async function except:
+ * This is what Rust calls when it invokes a callback method.
+ */
+extern "C" void callback_interface_logins_primary_password_authenticator_get_primary_password(
+ uint64_t aUniffiHandle,
+ ForeignFutureCompleterust_buffer aUniffiForeignFutureCallback,
+ uint64_t aUniffiForeignFutureCallbackData,
+ // This can be used to detected when the future is dropped from the Rust side and cancel the
+ // async task on the foreign side. However, there's no way to do that in JS, so we just ignore
+ // it.
+ ForeignFuture *aUniffiOutForeignFuture
+) {
+ UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorGetPrimaryPassword>(
+ aUniffiHandle,
+ aUniffiForeignFutureCallback,
+ aUniffiForeignFutureCallbackData);
+ // Now that everything is set up, schedule the call in the JS main thread.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator);
+}
+/**
+ * Callback method handler subclass for callback_interface_logins_primary_password_authenticator_on_authentication_success
*
- * - It doesn't input the complete callback function/data
- * - It doesn't override HandleReturn and returns `nullptr` from MakeCall.
- * This means ScheduleAsyncCall will schedule `MakeCall` and not do anything
- * with the result, which is what we want.
+ * This handles the specifics of the async call.
+ * AsyncCallbackMethodHandlerBase::ScheduleAsyncCall handles the general parts.
*/
-class CallbackInterfaceMethodContextIdContextIdCallbackPersist final : public AsyncCallbackMethodHandlerBase {
+class CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationSuccess final : public AsyncCallbackMethodHandlerBase {
private:
// Rust arguments
- FfiValueRustBuffer mContextId{};
- FfiValueInt<int64_t> mCreationDate{};
+ ForeignFutureCompletevoid mUniffiCompleteCallback;
+ uint64_t mUniffiCallbackData;
public:
- CallbackInterfaceMethodContextIdContextIdCallbackPersist(
+ CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationSuccess(
uint64_t aUniffiHandle,
- RustBuffer aContextId,
- int64_t aCreationDate
- ) : AsyncCallbackMethodHandlerBase ("ContextIdCallback.callback_interface_context_id_context_id_callback_persist", aUniffiHandle),
- mContextId(FfiValueRustBuffer::FromRust(aContextId)),
- mCreationDate(FfiValueInt<int64_t>::FromRust(aCreationDate)){ }
+ ForeignFutureCompletevoid aUniffiCompleteCallback,
+ uint64_t aUniffiCallbackData
+ ) : AsyncCallbackMethodHandlerBase ("PrimaryPasswordAuthenticator.callback_interface_logins_primary_password_authenticator_on_authentication_success", aUniffiHandle),
+ mUniffiCompleteCallback(aUniffiCompleteCallback),
+ mUniffiCallbackData(aUniffiCallbackData) { }
MOZ_CAN_RUN_SCRIPT
already_AddRefed<dom::Promise>
MakeCall(JSContext* aCx, dom::UniFFICallbackHandler* aJsHandler, ErrorResult& aError) override {
// Convert arguments
nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
- if (!uniffiArgs.AppendElements(2, mozilla::fallible)) {
+ if (!uniffiArgs.AppendElements(0, mozilla::fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
- mContextId.Lift(aCx, &uniffiArgs[0], aError);
- if (aError.Failed()) {
- return nullptr;
- }
- mCreationDate.Lift(aCx, &uniffiArgs[1], aError);
- if (aError.Failed()) {
- return nullptr;
+
+ RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 1, uniffiArgs, aError);
+ return result.forget();
+ }
+
+ void HandleReturn(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ ErrorResult& aRv) override {
+ if (!mUniffiCompleteCallback) {
+ MOZ_ASSERT_UNREACHABLE("HandleReturn called multiple times");
+ return;
}
- RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 0, uniffiArgs, aError);
- return nullptr;
+ ForeignFutureResultVoid result{};
+ CallbackLowerReturnVoid::Lower(aCallResult, &result.call_status, aRv);
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
+ mUniffiCompleteCallback = nullptr;
+ }
+
+ ~CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationSuccess() {
+ if (mUniffiCompleteCallback) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] promise never completed"));
+ ForeignFutureResultVoid result{};
+ result.call_status.code = RUST_CALL_INTERNAL_ERROR;
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
+ }
}
};
/**
- * callback_interface_context_id_context_id_callback_persist -- C function to handle the callback method
+ * callback_interface_logins_primary_password_authenticator_on_authentication_success -- C function to handle the callback method
*
* This is what Rust calls when it invokes a callback method.
*/
-extern "C" void callback_interface_context_id_context_id_callback_persist(
+extern "C" void callback_interface_logins_primary_password_authenticator_on_authentication_success(
uint64_t aUniffiHandle,
- RustBuffer aContextId,
- int64_t aCreationDate,
- void* aUniffiOutReturn,
- RustCallStatus* uniffiOutStatus
+ ForeignFutureCompletevoid aUniffiForeignFutureCallback,
+ uint64_t aUniffiForeignFutureCallbackData,
+ // This can be used to detected when the future is dropped from the Rust side and cancel the
+ // async task on the foreign side. However, there's no way to do that in JS, so we just ignore
+ // it.
+ ForeignFuture *aUniffiOutForeignFuture
) {
- UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodContextIdContextIdCallbackPersist>(aUniffiHandle, aContextId, aCreationDate);
- AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerContextIdContextIdCallback);
+ UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationSuccess>(
+ aUniffiHandle,
+ aUniffiForeignFutureCallback,
+ aUniffiForeignFutureCallbackData);
+ // Now that everything is set up, schedule the call in the JS main thread.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator);
}
/**
- * Callback method handler subclass for callback_interface_context_id_context_id_callback_rotated
- *
- * This is like the handler for an async function except:
+ * Callback method handler subclass for callback_interface_logins_primary_password_authenticator_on_authentication_failure
*
- * - It doesn't input the complete callback function/data
- * - It doesn't override HandleReturn and returns `nullptr` from MakeCall.
- * This means ScheduleAsyncCall will schedule `MakeCall` and not do anything
- * with the result, which is what we want.
+ * This handles the specifics of the async call.
+ * AsyncCallbackMethodHandlerBase::ScheduleAsyncCall handles the general parts.
*/
-class CallbackInterfaceMethodContextIdContextIdCallbackRotated final : public AsyncCallbackMethodHandlerBase {
+class CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationFailure final : public AsyncCallbackMethodHandlerBase {
private:
// Rust arguments
- FfiValueRustBuffer mOldContextId{};
+ ForeignFutureCompletevoid mUniffiCompleteCallback;
+ uint64_t mUniffiCallbackData;
public:
- CallbackInterfaceMethodContextIdContextIdCallbackRotated(
+ CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationFailure(
uint64_t aUniffiHandle,
- RustBuffer aOldContextId
- ) : AsyncCallbackMethodHandlerBase ("ContextIdCallback.callback_interface_context_id_context_id_callback_rotated", aUniffiHandle),
- mOldContextId(FfiValueRustBuffer::FromRust(aOldContextId)){ }
+ ForeignFutureCompletevoid aUniffiCompleteCallback,
+ uint64_t aUniffiCallbackData
+ ) : AsyncCallbackMethodHandlerBase ("PrimaryPasswordAuthenticator.callback_interface_logins_primary_password_authenticator_on_authentication_failure", aUniffiHandle),
+ mUniffiCompleteCallback(aUniffiCompleteCallback),
+ mUniffiCallbackData(aUniffiCallbackData) { }
MOZ_CAN_RUN_SCRIPT
already_AddRefed<dom::Promise>
MakeCall(JSContext* aCx, dom::UniFFICallbackHandler* aJsHandler, ErrorResult& aError) override {
// Convert arguments
nsTArray<dom::OwningUniFFIScaffoldingValue> uniffiArgs;
- if (!uniffiArgs.AppendElements(1, mozilla::fallible)) {
+ if (!uniffiArgs.AppendElements(0, mozilla::fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
- mOldContextId.Lift(aCx, &uniffiArgs[0], aError);
- if (aError.Failed()) {
- return nullptr;
+
+ RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 2, uniffiArgs, aError);
+ return result.forget();
+ }
+
+ void HandleReturn(const RootedDictionary<UniFFIScaffoldingCallResult>& aCallResult,
+ ErrorResult& aRv) override {
+ if (!mUniffiCompleteCallback) {
+ MOZ_ASSERT_UNREACHABLE("HandleReturn called multiple times");
+ return;
}
- RefPtr<dom::Promise> result = aJsHandler->CallAsync(mUniffiHandle.IntoRust(), 1, uniffiArgs, aError);
- return nullptr;
+ ForeignFutureResultVoid result{};
+ CallbackLowerReturnVoid::Lower(aCallResult, &result.call_status, aRv);
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
+ mUniffiCompleteCallback = nullptr;
+ }
+
+ ~CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationFailure() {
+ if (mUniffiCompleteCallback) {
+ MOZ_LOG(gUniffiLogger, LogLevel::Error, ("[CallbackLowerReturnVoid] promise never completed"));
+ ForeignFutureResultVoid result{};
+ result.call_status.code = RUST_CALL_INTERNAL_ERROR;
+ mUniffiCompleteCallback(mUniffiCallbackData, result);
+ }
}
};
/**
- * callback_interface_context_id_context_id_callback_rotated -- C function to handle the callback method
+ * callback_interface_logins_primary_password_authenticator_on_authentication_failure -- C function to handle the callback method
*
* This is what Rust calls when it invokes a callback method.
*/
-extern "C" void callback_interface_context_id_context_id_callback_rotated(
+extern "C" void callback_interface_logins_primary_password_authenticator_on_authentication_failure(
uint64_t aUniffiHandle,
- RustBuffer aOldContextId,
- void* aUniffiOutReturn,
- RustCallStatus* uniffiOutStatus
+ ForeignFutureCompletevoid aUniffiForeignFutureCallback,
+ uint64_t aUniffiForeignFutureCallbackData,
+ // This can be used to detected when the future is dropped from the Rust side and cancel the
+ // async task on the foreign side. However, there's no way to do that in JS, so we just ignore
+ // it.
+ ForeignFuture *aUniffiOutForeignFuture
) {
- UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodContextIdContextIdCallbackRotated>(aUniffiHandle, aOldContextId);
- AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerContextIdContextIdCallback);
+ UniquePtr<AsyncCallbackMethodHandlerBase> handler = MakeUnique<CallbackInterfaceMethodLoginsPrimaryPasswordAuthenticatorOnAuthenticationFailure>(
+ aUniffiHandle,
+ aUniffiForeignFutureCallback,
+ aUniffiForeignFutureCallbackData);
+ // Now that everything is set up, schedule the call in the JS main thread.
+ AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(std::move(handler), &gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator);
}
-extern "C" void callback_free_context_id_context_id_callback(uint64_t uniffiHandle) {
+extern "C" void callback_free_logins_primary_password_authenticator(uint64_t uniffiHandle) {
// Callback object handles are keys in a map stored in the JS handler. To
// handle the free call, schedule a fire-and-forget JS call to remove the key.
AsyncCallbackMethodHandlerBase::ScheduleAsyncCall(
- MakeUnique<CallbackFreeHandler>("ContextIdCallback.uniffi_free", uniffiHandle),
- &gUniffiCallbackHandlerContextIdContextIdCallback);
+ MakeUnique<CallbackFreeHandler>("PrimaryPasswordAuthenticator.uniffi_free", uniffiHandle),
+ &gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator);
}
-static VTableCallbackInterfaceContextIdContextIdCallback kUniffiVtableContextIdContextIdCallback {
- callback_interface_context_id_context_id_callback_persist,
- callback_interface_context_id_context_id_callback_rotated,
- callback_free_context_id_context_id_callback
+static VTableCallbackInterfaceLoginsPrimaryPasswordAuthenticator kUniffiVtableLoginsPrimaryPasswordAuthenticator {
+ callback_interface_logins_primary_password_authenticator_get_primary_password,
+ callback_interface_logins_primary_password_authenticator_on_authentication_success,
+ callback_interface_logins_primary_password_authenticator_on_authentication_failure,
+ callback_free_logins_primary_password_authenticator
};
static StaticRefPtr<dom::UniFFICallbackHandler> gUniffiCallbackHandlerTracingEventSink;
/**
@@ -13892,6 +16996,36 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
break;
}
case 2: {
+ if (gUniffiCallbackHandlerLoginsEncryptorDecryptor) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler already registered for EncryptorDecryptor"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsEncryptorDecryptor = &aCallbackHandler;
+ uniffi_logins_fn_init_callback_vtable_encryptordecryptor(&kUniffiVtableLoginsEncryptorDecryptor);
+ break;
+ }
+ case 3: {
+ if (gUniffiCallbackHandlerLoginsKeyManager) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler already registered for KeyManager"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsKeyManager = &aCallbackHandler;
+ uniffi_logins_fn_init_callback_vtable_keymanager(&kUniffiVtableLoginsKeyManager);
+ break;
+ }
+ case 4: {
+ if (gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler already registered for PrimaryPasswordAuthenticator"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator = &aCallbackHandler;
+ uniffi_logins_fn_init_callback_vtable_primarypasswordauthenticator(&kUniffiVtableLoginsPrimaryPasswordAuthenticator);
+ break;
+ }
+ case 5: {
if (gUniffiCallbackHandlerTracingEventSink) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for EventSink"_ns);
return;
@@ -13901,7 +17035,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
uniffi_tracing_support_fn_init_callback_vtable_eventsink(&kUniffiVtableTracingEventSink);
break;
}
- case 3: {
+ case 6: {
if (gUniffiCallbackHandlerViaductBackend) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for Backend"_ns);
return;
@@ -13913,7 +17047,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
}
#ifdef MOZ_UNIFFI_FIXTURES
- case 4: {
+ case 7: {
if (gUniffiCallbackHandlerUniffiBindingsTestsTestAsyncCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for TestAsyncCallbackInterface"_ns);
return;
@@ -13923,7 +17057,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
uniffi_uniffi_bindings_tests_fn_init_callback_vtable_testasynccallbackinterface(&kUniffiVtableUniffiBindingsTestsTestAsyncCallbackInterface);
break;
}
- case 5: {
+ case 8: {
if (gUniffiCallbackHandlerUniffiBindingsTestsTestCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for TestCallbackInterface"_ns);
return;
@@ -13933,7 +17067,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
uniffi_uniffi_bindings_tests_fn_init_callback_vtable_testcallbackinterface(&kUniffiVtableUniffiBindingsTestsTestCallbackInterface);
break;
}
- case 6: {
+ case 9: {
if (gUniffiCallbackHandlerUniffiBindingsTestsAsyncTestTraitInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for AsyncTestTraitInterface"_ns);
return;
@@ -13943,7 +17077,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
uniffi_uniffi_bindings_tests_fn_init_callback_vtable_asynctesttraitinterface(&kUniffiVtableUniffiBindingsTestsAsyncTestTraitInterface);
break;
}
- case 7: {
+ case 10: {
if (gUniffiCallbackHandlerUniffiBindingsTestsTestTraitInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for TestTraitInterface"_ns);
return;
@@ -13953,7 +17087,7 @@ void RegisterCallbackHandler(uint64_t aInterfaceId, UniFFICallbackHandler& aCall
uniffi_uniffi_bindings_tests_fn_init_callback_vtable_testtraitinterface(&kUniffiVtableUniffiBindingsTestsTestTraitInterface);
break;
}
- case 8: {
+ case 11: {
if (gUniffiCallbackHandlerUniffiBindingsTestsCollisionTestCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler already registered for TestCallbackInterface"_ns);
return;
@@ -13984,6 +17118,33 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
break;
}
case 2: {
+ if (!gUniffiCallbackHandlerLoginsEncryptorDecryptor) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler not registered for EncryptorDecryptor"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsEncryptorDecryptor = nullptr;
+ break;
+ }
+ case 3: {
+ if (!gUniffiCallbackHandlerLoginsKeyManager) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler not registered for KeyManager"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsKeyManager = nullptr;
+ break;
+ }
+ case 4: {
+ if (!gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator) {
+ aError.ThrowUnknownError("[UniFFI] Callback handler not registered for PrimaryPasswordAuthenticator"_ns);
+ return;
+ }
+
+ gUniffiCallbackHandlerLoginsPrimaryPasswordAuthenticator = nullptr;
+ break;
+ }
+ case 5: {
if (!gUniffiCallbackHandlerTracingEventSink) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for EventSink"_ns);
return;
@@ -13992,7 +17153,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
gUniffiCallbackHandlerTracingEventSink = nullptr;
break;
}
- case 3: {
+ case 6: {
if (!gUniffiCallbackHandlerViaductBackend) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for Backend"_ns);
return;
@@ -14003,7 +17164,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
}
#ifdef MOZ_UNIFFI_FIXTURES
- case 4: {
+ case 7: {
if (!gUniffiCallbackHandlerUniffiBindingsTestsTestAsyncCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for TestAsyncCallbackInterface"_ns);
return;
@@ -14012,7 +17173,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
gUniffiCallbackHandlerUniffiBindingsTestsTestAsyncCallbackInterface = nullptr;
break;
}
- case 5: {
+ case 8: {
if (!gUniffiCallbackHandlerUniffiBindingsTestsTestCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for TestCallbackInterface"_ns);
return;
@@ -14021,7 +17182,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
gUniffiCallbackHandlerUniffiBindingsTestsTestCallbackInterface = nullptr;
break;
}
- case 6: {
+ case 9: {
if (!gUniffiCallbackHandlerUniffiBindingsTestsAsyncTestTraitInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for AsyncTestTraitInterface"_ns);
return;
@@ -14030,7 +17191,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
gUniffiCallbackHandlerUniffiBindingsTestsAsyncTestTraitInterface = nullptr;
break;
}
- case 7: {
+ case 10: {
if (!gUniffiCallbackHandlerUniffiBindingsTestsTestTraitInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for TestTraitInterface"_ns);
return;
@@ -14039,7 +17200,7 @@ void DeregisterCallbackHandler(uint64_t aInterfaceId, ErrorResult& aError) {
gUniffiCallbackHandlerUniffiBindingsTestsTestTraitInterface = nullptr;
break;
}
- case 8: {
+ case 11: {
if (!gUniffiCallbackHandlerUniffiBindingsTestsCollisionTestCallbackInterface) {
aError.ThrowUnknownError("[UniFFI] Callback handler not registered for TestCallbackInterface"_ns);
return;