Bug 1952712 - Vendor app-services f7947a60b3e9957b97229d6dd08b458532e79c1c. r=bdk

Also mark `SearchEngineSelector.set_config_overrides` as being a sync / main thread function.

Differential Revision: https://phabricator.services.mozilla.com/D240790
This commit is contained in:
Mark Banner
2025-03-10 13:25:22 +00:00
parent 50f816c3e3
commit fffd1a6e07
54 changed files with 7865 additions and 999 deletions

View File

@@ -70,9 +70,9 @@ git = "https://github.com/jfkthame/mapped_hyph.git"
rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7"]
[source."git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c"]
git = "https://github.com/mozilla/application-services"
rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7"
rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"]

65
Cargo.lock generated
View File

@@ -1795,7 +1795,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"error-support-macros",
"lazy_static",
@@ -1807,7 +1807,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"proc-macro2",
"quote",
@@ -1918,7 +1918,7 @@ dependencies = [
[[package]]
name = "firefox-versioning"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"serde_json",
"thiserror 1.999.999",
@@ -3195,7 +3195,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"lazy_static",
"parking_lot",
@@ -3281,6 +3281,29 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jexl-eval"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdd8dfc8744f1f59d47f7f3bc1378047ecc15fef5709942fbcc8d0d9f846e506"
dependencies = [
"anyhow",
"jexl-parser",
"serde",
"serde_json",
"thiserror 1.999.999",
]
[[package]]
name = "jexl-parser"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07cc5fb813f07eceed953a76345a8af76038ee4101c32dc3740e040595013a84"
dependencies = [
"lalrpop-util",
"regex",
]
[[package]]
name = "jobserver"
version = "0.1.32"
@@ -3426,6 +3449,15 @@ dependencies = [
"moz_task",
]
[[package]]
name = "lalrpop-util"
version = "0.19.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed"
dependencies = [
"regex",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -4860,7 +4892,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "payload-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"serde",
"serde_derive",
@@ -5355,7 +5387,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "relevancy"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"base64 0.21.3",
@@ -5380,12 +5412,13 @@ dependencies = [
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"camino",
"error-support",
"firefox-versioning",
"jexl-eval",
"log",
"parking_lot",
"regex",
@@ -5662,7 +5695,7 @@ dependencies = [
[[package]]
name = "search"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"error-support",
"firefox-versioning",
@@ -5952,7 +5985,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"interrupt-support",
"lazy_static",
@@ -6152,7 +6185,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"chrono",
@@ -6204,7 +6237,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"base64 0.21.3",
"rand",
@@ -6215,7 +6248,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"error-support",
@@ -6255,7 +6288,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"error-support",
@@ -6597,7 +6630,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "types"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"rusqlite",
"serde",
@@ -6977,7 +7010,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"ffi-support",
"log",
@@ -7136,7 +7169,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=d83fcd87f69a23930fed279ab5d2c56173a61db7#d83fcd87f69a23930fed279ab5d2c56173a61db7"
source = "git+https://github.com/mozilla/application-services?rev=f7947a60b3e9957b97229d6dd08b458532e79c1c#f7947a60b3e9957b97229d6dd08b458532e79c1c"
dependencies = [
"anyhow",
"error-support",

View File

@@ -228,14 +228,14 @@ malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" }
# application-services overrides to make updating them all simpler.
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
search = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "d83fcd87f69a23930fed279ab5d2c56173a61db7" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
search = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "f7947a60b3e9957b97229d6dd08b458532e79c1c" }
allocator-api2 = { path = "third_party/rust/allocator-api2" }

View File

@@ -0,0 +1 @@
{"files":{"Cargo.toml":"d0e09f44e8da86c16a9b4e474d3c9774d9a24090c0e7c0353e7857129b49b655","src/error.rs":"ead69d47bea7b9002942be057f842ce199a7a1bca04165a5d9a6bfeea8daa344","src/lib.rs":"447c26ed683add8ad7fe9b0cac03f7ece9d3d910bcdc60178876ddfc9b035482"},"package":"fdd8dfc8744f1f59d47f7f3bc1378047ecc15fef5709942fbcc8d0d9f846e506"}

48
third_party/rust/jexl-eval/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,48 @@
# 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 = "2018"
name = "jexl-eval"
version = "0.3.0"
authors = [
"Mike Cooper <mythmon@gmail.com>",
"The Sync Team <sync-team@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
]
build = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A JEXL evaluator written in Rust"
readme = false
license = "MPL-2.0"
repository = "https://github.com/mozilla/jexl-rs"
[lib]
name = "jexl_eval"
path = "src/lib.rs"
[dependencies.anyhow]
version = "1"
[dependencies.jexl-parser]
version = "^0.3.0"
[dependencies.serde]
version = "1"
[dependencies.serde_json]
version = "1"
[dependencies.thiserror]
version = "1"

42
third_party/rust/jexl-eval/src/error.rs vendored Normal file
View File

@@ -0,0 +1,42 @@
/* 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 jexl_parser::{ast::OpCode, ParseError, Token};
use serde_json::Value;
pub type Result<'a, T, E = EvaluationError<'a>> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
pub enum EvaluationError<'a> {
#[error("Parsing error: {0}")]
ParseError(Box<ParseError<usize, Token<'a>, &'a str>>),
#[error("Invalid binary operation, left: {left}, right: {right}, operation: {operation}")]
InvalidBinaryOp {
left: Value,
right: Value,
operation: OpCode,
},
#[error("Unknown transform: {0}")]
UnknownTransform(String),
#[error("Duplicate object key: {0}")]
DuplicateObjectKey(String),
#[error("Identifier '{0}' is undefined")]
UndefinedIdentifier(String),
#[error("Invalid context provided")]
InvalidContext,
#[error("Invalid index type")]
InvalidIndexType,
#[error("Invalid json: {0}")]
JSONError(#[from] serde_json::Error),
#[error("Custom error: {0}")]
CustomError(#[from] anyhow::Error),
#[error("Invalid filter")]
InvalidFilter,
}
impl<'a> From<ParseError<usize, Token<'a>, &'a str>> for EvaluationError<'a> {
fn from(cause: ParseError<usize, Token<'a>, &'a str>) -> Self {
EvaluationError::ParseError(Box::new(cause))
}
}

967
third_party/rust/jexl-eval/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,967 @@
/* 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 JEXL evaluator written in Rust
//! This crate depends on a JEXL parser crate that handles all the parsing
//! and is a part of the same workspace.
//! JEXL is an expression language used by Mozilla, you can find more information here: https://github.com/mozilla/mozjexl
//!
//! # How to use
//! The access point for this crate is the `eval` functions of the Evaluator Struct
//! You can use the `eval` function directly to evaluate standalone statements
//!
//! For example:
//! ```rust
//! use jexl_eval::Evaluator;
//! use serde_json::json as value;
//! let evaluator = Evaluator::new();
//! assert_eq!(evaluator.eval("'Hello ' + 'World'").unwrap(), value!("Hello World"));
//! ```
//!
//! You can also run the statements against a context using the `eval_in_context` function
//! The context can be any type that implements the `serde::Serializable` trait
//! and the function will return errors if the statement doesn't match the context
//!
//! For example:
//! ```rust
//! use jexl_eval::Evaluator;
//! use serde_json::json as value;
//! let context = value!({"a": {"b": 2.0}});
//! let evaluator = Evaluator::new();
//! assert_eq!(evaluator.eval_in_context("a.b", context).unwrap(), value!(2.0));
//! ```
//!
use jexl_parser::{
ast::{Expression, OpCode},
Parser,
};
use serde_json::{json as value, Value};
pub mod error;
use error::*;
use std::collections::HashMap;
const EPSILON: f64 = 0.000001f64;
trait Truthy {
fn is_truthy(&self) -> bool;
}
impl Truthy for Value {
fn is_truthy(&self) -> bool {
match self {
Value::Bool(b) => *b,
Value::Null => false,
Value::Number(f) => f.as_f64().unwrap() != 0.0,
Value::String(s) => !s.is_empty(),
// It would be better if these depended on the contents of the
// object (empty array/object is falsey, non-empty is truthy, like
// in Python) but this matches JS semantics. Is it worth changing?
Value::Array(_) => true,
Value::Object(_) => true,
}
}
}
impl<'b> Truthy for Result<'b, Value> {
fn is_truthy(&self) -> bool {
match self {
Ok(v) => v.is_truthy(),
_ => false,
}
}
}
type Context = Value;
/// TransformFn represents an arbitrary transform function
/// Transform functions take an arbitrary number of `serde_json::Value`to represent their arguments
/// and return a `serde_json::Value`.
/// the transform function itself is responsible for checking if the format and number of
/// the arguments is correct
///
/// Returns a Result with an `anyhow::Error`. This allows consumers to return their own custom errors
/// in the closure, and use `.into` to convert it into an `anyhow::Error`. The error message will be perserved
pub type TransformFn<'a> = Box<dyn Fn(&[Value]) -> Result<Value, anyhow::Error> + Send + Sync + 'a>;
#[derive(Default)]
pub struct Evaluator<'a> {
transforms: HashMap<String, TransformFn<'a>>,
}
impl<'a> Evaluator<'a> {
pub fn new() -> Self {
Self::default()
}
/// Adds a custom transform function
/// This is meant as a way to allow consumers to add their own custom functionality
/// to the expression language.
/// Note that the name added here has to match with
/// the name that the transform will have when it's a part of the expression statement
///
/// # Arguments:
/// - `name`: The name of the transfrom
/// - `transform`: The actual function. A closure the implements Fn(&[serde_json::Value]) -> Result<Value, anyhow::Error>
///
/// # Example:
///
/// ```rust
/// use jexl_eval::Evaluator;
/// use serde_json::{json as value, Value};
///
/// let mut evaluator = Evaluator::new().with_transform("lower", |v: &[Value]| {
/// let s = v
/// .first()
/// .expect("Should have 1 argument!")
/// .as_str()
/// .expect("Should be a string!");
/// Ok(value!(s.to_lowercase()))
/// });
///
/// assert_eq!(evaluator.eval("'JOHN DOe'|lower").unwrap(), value!("john doe"))
/// ```
pub fn with_transform<F>(mut self, name: &str, transform: F) -> Self
where
F: Fn(&[Value]) -> Result<Value, anyhow::Error> + Send + Sync + 'a,
{
self.transforms
.insert(name.to_string(), Box::new(transform));
self
}
pub fn eval<'b>(&self, input: &'b str) -> Result<'b, Value> {
let context = value!({});
self.eval_in_context(input, &context)
}
pub fn eval_in_context<'b, T: serde::Serialize>(
&self,
input: &'b str,
context: T,
) -> Result<'b, Value> {
let tree = Parser::parse(input)?;
let context = serde_json::to_value(context)?;
if !context.is_object() {
return Err(EvaluationError::InvalidContext);
}
self.eval_ast(tree, &context)
}
fn eval_ast<'b>(&self, ast: Expression, context: &Context) -> Result<'b, Value> {
match ast {
Expression::Number(n) => Ok(value!(n)),
Expression::Boolean(b) => Ok(value!(b)),
Expression::String(s) => Ok(value!(s)),
Expression::Array(xs) => xs.into_iter().map(|x| self.eval_ast(*x, context)).collect(),
Expression::Null => Ok(Value::Null),
Expression::Object(items) => {
let mut map = serde_json::Map::with_capacity(items.len());
for (key, expr) in items.into_iter() {
if map.contains_key(&key) {
return Err(EvaluationError::DuplicateObjectKey(key));
}
let value = self.eval_ast(*expr, context)?;
map.insert(key, value);
}
Ok(Value::Object(map))
}
Expression::Identifier(inner) => match context.get(&inner) {
Some(v) => Ok(v.clone()),
_ => Err(EvaluationError::UndefinedIdentifier(inner.clone())),
},
Expression::DotOperation { subject, ident } => {
let subject = self.eval_ast(*subject, context)?;
Ok(subject.get(&ident).unwrap_or(&value!(null)).clone())
}
Expression::IndexOperation { subject, index } => {
let subject = self.eval_ast(*subject, context)?;
if let Expression::Filter { ident, op, right } = *index {
let subject_arr = subject.as_array().ok_or(EvaluationError::InvalidFilter)?;
let right = self.eval_ast(*right, context)?;
let filtered = subject_arr
.iter()
.filter(|e| {
let left = e.get(&ident).unwrap_or(&value!(null));
// returns false if any members fail the op, could happen if array members are missing the identifier
Self::apply_op(op, left.clone(), right.clone())
.unwrap_or(value!(false))
.is_truthy()
})
.collect::<Vec<_>>();
return Ok(value!(filtered));
}
let index = self.eval_ast(*index, context)?;
match index {
Value::String(inner) => {
Ok(subject.get(&inner).unwrap_or(&value!(null)).clone())
}
Value::Number(inner) => Ok(subject
.get(inner.as_f64().unwrap().floor() as usize)
.unwrap_or(&value!(null))
.clone()),
_ => Err(EvaluationError::InvalidIndexType),
}
}
Expression::BinaryOperation {
left,
right,
operation,
} => self.eval_op(operation, left, right, context),
Expression::Transform {
name,
subject,
args,
} => {
let subject = self.eval_ast(*subject, context)?;
let mut args_arr = Vec::new();
args_arr.push(subject);
if let Some(args) = args {
for arg in args {
args_arr.push(self.eval_ast(*arg, context)?);
}
}
let f = self
.transforms
.get(&name)
.ok_or(EvaluationError::UnknownTransform(name))?;
f(&args_arr).map_err(|e| e.into())
}
Expression::Conditional {
left,
truthy,
falsy,
} => {
if self.eval_ast(*left, context).is_truthy() {
self.eval_ast(*truthy, context)
} else {
self.eval_ast(*falsy, context)
}
}
Expression::Filter {
ident: _,
op: _,
right: _,
} => {
// Filters shouldn't be evaluated individually
// instead, they are evaluated as a part of an IndexOperation
return Err(EvaluationError::InvalidFilter);
}
}
}
fn eval_op<'b>(
&self,
operation: OpCode,
left: Box<Expression>,
right: Box<Expression>,
context: &Context,
) -> Result<'b, Value> {
let left = self.eval_ast(*left, context);
// We want to delay evaluating the right hand side in the cases of AND and OR.
let eval_right = || self.eval_ast(*right, context);
Ok(match operation {
OpCode::Or => {
if left.is_truthy() {
left?
} else {
eval_right()?
}
}
OpCode::And => {
if left.is_truthy() {
eval_right()?
} else {
left?
}
}
_ => Self::apply_op(operation, left?, eval_right()?)?,
})
}
fn apply_op<'b>(operation: OpCode, left: Value, right: Value) -> Result<'b, Value> {
match (operation, left, right) {
(OpCode::NotEqual, a, b) => {
// Implement NotEquals as the inverse of Equals.
let value = Self::apply_op(OpCode::Equal, a, b)?;
let equality = value
.as_bool()
.unwrap_or_else(|| unreachable!("Equality always returns a bool"));
Ok(value!(!equality))
}
(OpCode::And, a, b) => Ok(if a.is_truthy() { b } else { a }),
(OpCode::Or, a, b) => Ok(if a.is_truthy() { a } else { b }),
(op, Value::Number(a), Value::Number(b)) => {
let left = a.as_f64().unwrap();
let right = b.as_f64().unwrap();
Ok(match op {
OpCode::Add => value!(left + right),
OpCode::Subtract => value!(left - right),
OpCode::Multiply => value!(left * right),
OpCode::Divide => value!(left / right),
OpCode::FloorDivide => value!((left / right).floor()),
OpCode::Modulus => value!(left % right),
OpCode::Exponent => value!(left.powf(right)),
OpCode::Less => value!(left < right),
OpCode::Greater => value!(left > right),
OpCode::LessEqual => value!(left <= right),
OpCode::GreaterEqual => value!(left >= right),
OpCode::Equal => value!((left - right).abs() < EPSILON),
OpCode::NotEqual => value!((left - right).abs() >= EPSILON),
OpCode::In => value!(false),
OpCode::And | OpCode::Or => {
unreachable!("Covered by previous case in parent match")
}
})
}
(op, Value::String(a), Value::String(b)) => match op {
OpCode::Equal => Ok(value!(a == b)),
OpCode::Add => Ok(value!(format!("{}{}", a, b))),
OpCode::In => Ok(value!(b.contains(&a))),
OpCode::Less => Ok(value!(a < b)),
OpCode::Greater => Ok(value!(a > b)),
OpCode::LessEqual => Ok(value!(a <= b)),
OpCode::GreaterEqual => Ok(value!(a >= b)),
_ => Err(EvaluationError::InvalidBinaryOp {
operation,
left: value!(a),
right: value!(b),
}),
},
(OpCode::In, left, Value::Array(v)) => Ok(value!(v.contains(&left))),
(OpCode::In, Value::String(left), Value::Object(v)) => {
Ok(value!(v.contains_key(&left)))
}
(OpCode::Equal, a, b) => match (a, b) {
// Number == Number is handled above
// String == String is handled above
(Value::Bool(a), Value::Bool(b)) => Ok(value!(a == b)),
(Value::Null, Value::Null) => Ok(value!(true)),
(Value::Array(a), Value::Array(b)) => Ok(value!(a == b)),
(Value::Object(a), Value::Object(b)) => Ok(value!(a == b)),
// If the types don't match, it's always false
_ => Ok(value!(false)),
},
(operation, left, right) => Err(EvaluationError::InvalidBinaryOp {
operation,
left,
right,
}),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json as value;
#[test]
fn test_literal() {
assert_eq!(Evaluator::new().eval("1").unwrap(), value!(1.0));
}
#[test]
fn test_binary_expression_addition() {
assert_eq!(Evaluator::new().eval("1 + 2").unwrap(), value!(3.0));
}
#[test]
fn test_binary_expression_multiplication() {
assert_eq!(Evaluator::new().eval("2 * 3").unwrap(), value!(6.0));
}
#[test]
fn test_precedence() {
assert_eq!(Evaluator::new().eval("2 + 3 * 4").unwrap(), value!(14.0));
}
#[test]
fn test_parenthesis() {
assert_eq!(Evaluator::new().eval("(2 + 3) * 4").unwrap(), value!(20.0));
}
#[test]
fn test_string_concat() {
assert_eq!(
Evaluator::new().eval("'Hello ' + 'World'").unwrap(),
value!("Hello World")
);
}
#[test]
fn test_true_comparison() {
assert_eq!(Evaluator::new().eval("2 > 1").unwrap(), value!(true));
}
#[test]
fn test_false_comparison() {
assert_eq!(Evaluator::new().eval("2 <= 1").unwrap(), value!(false));
}
#[test]
fn test_boolean_logic() {
assert_eq!(
Evaluator::new()
.eval("'foo' && 6 >= 6 && 0 + 1 && true")
.unwrap(),
value!(true)
);
}
#[test]
fn test_identifier() {
let context = value!({"a": 1.0});
assert_eq!(
Evaluator::new().eval_in_context("a", context).unwrap(),
value!(1.0)
);
}
#[test]
fn test_identifier_chain() {
let context = value!({"a": {"b": 2.0}});
assert_eq!(
Evaluator::new().eval_in_context("a.b", context).unwrap(),
value!(2.0)
);
}
#[test]
fn test_context_filter_arrays() {
let context = value!({
"foo": {
"bar": [
{"tek": "hello"},
{"tek": "baz"},
{"tok": "baz"},
]
}
});
assert_eq!(
Evaluator::new()
.eval_in_context("foo.bar[.tek == 'baz']", &context)
.unwrap(),
value!([{"tek": "baz"}])
);
}
#[test]
fn test_context_array_index() {
let context = value!({
"foo": {
"bar": [
{"tek": "hello"},
{"tek": "baz"},
{"tok": "baz"},
]
}
});
assert_eq!(
Evaluator::new()
.eval_in_context("foo.bar[1].tek", context)
.unwrap(),
value!("baz")
);
}
#[test]
fn test_object_expression_properties() {
let context = value!({"foo": {"baz": {"bar": "tek"}}});
assert_eq!(
Evaluator::new()
.eval_in_context("foo['ba' + 'z'].bar", &context)
.unwrap(),
value!("tek")
);
}
#[test]
fn test_divfloor() {
assert_eq!(Evaluator::new().eval("7 // 2").unwrap(), value!(3.0));
}
#[test]
fn test_empty_object_literal() {
assert_eq!(Evaluator::new().eval("{}").unwrap(), value!({}));
}
#[test]
fn test_object_literal_strings() {
assert_eq!(
Evaluator::new().eval("{'foo': {'bar': 'tek'}}").unwrap(),
value!({"foo": {"bar": "tek"}})
);
}
#[test]
fn test_object_literal_identifiers() {
assert_eq!(
Evaluator::new().eval("{foo: {bar: 'tek'}}").unwrap(),
value!({"foo": {"bar": "tek"}})
);
}
#[test]
fn test_object_literal_properties() {
assert_eq!(
Evaluator::new().eval("{foo: 'bar'}.foo").unwrap(),
value!("bar")
);
}
#[test]
fn test_array_literal() {
assert_eq!(
Evaluator::new().eval("['foo', 1+2]").unwrap(),
value!(["foo", 3.0])
);
}
#[test]
fn test_array_literal_indexing() {
assert_eq!(Evaluator::new().eval("[1, 2, 3][1]").unwrap(), value!(2.0));
}
#[test]
fn test_in_operator_string() {
assert_eq!(
Evaluator::new().eval("'bar' in 'foobartek'").unwrap(),
value!(true)
);
assert_eq!(
Evaluator::new().eval("'baz' in 'foobartek'").unwrap(),
value!(false)
);
}
#[test]
fn test_in_operator_array() {
assert_eq!(
Evaluator::new()
.eval("'bar' in ['foo', 'bar', 'tek']")
.unwrap(),
value!(true)
);
assert_eq!(
Evaluator::new()
.eval("'baz' in ['foo', 'bar', 'tek']")
.unwrap(),
value!(false)
);
}
#[test]
fn test_in_operator_object() {
assert_eq!(
Evaluator::new()
.eval("'bar' in {foo: 1, bar: 2, tek: 3}")
.unwrap(),
value!(true)
);
assert_eq!(
Evaluator::new()
.eval("'baz' in {foo: 1, bar: 2, tek: 3}")
.unwrap(),
value!(false)
);
}
#[test]
fn test_conditional_expression() {
assert_eq!(
Evaluator::new().eval("'foo' ? 1 : 2").unwrap(),
value!(1f64)
);
assert_eq!(Evaluator::new().eval("'' ? 1 : 2").unwrap(), value!(2f64));
}
#[test]
fn test_arbitrary_whitespace() {
assert_eq!(
Evaluator::new().eval("(\t2\n+\n3) *\n4\n\r\n").unwrap(),
value!(20.0)
);
}
#[test]
fn test_non_integer() {
assert_eq!(Evaluator::new().eval("1.5 * 3.0").unwrap(), value!(4.5));
}
#[test]
fn test_string_literal() {
assert_eq!(
Evaluator::new().eval("'hello world'").unwrap(),
value!("hello world")
);
assert_eq!(
Evaluator::new().eval("\"hello world\"").unwrap(),
value!("hello world")
);
}
#[test]
fn test_string_escapes() {
assert_eq!(Evaluator::new().eval("'a\\'b'").unwrap(), value!("a'b"));
assert_eq!(Evaluator::new().eval("\"a\\\"b\"").unwrap(), value!("a\"b"));
}
#[test]
// Test a very simple transform that applies to_lowercase to a string
fn test_simple_transform() {
let evaluator = Evaluator::new().with_transform("lower", |v: &[Value]| {
let s = v
.get(0)
.expect("There should be one argument!")
.as_str()
.expect("Should be a string!");
Ok(value!(s.to_lowercase()))
});
assert_eq!(evaluator.eval("'T_T'|lower").unwrap(), value!("t_t"));
}
#[test]
// Test returning an UnknownTransform error if a transform is unknown
fn test_missing_transform() {
let err = Evaluator::new().eval("'hello'|world").unwrap_err();
if let EvaluationError::UnknownTransform(transform) = err {
assert_eq!(transform, "world")
} else {
panic!("Should have thrown an unknown transform error")
}
}
#[test]
// Test returning an UndefinedIdentifier error if an identifier is unknown
fn test_undefined_identifier() {
let err = Evaluator::new().eval("not_defined").unwrap_err();
if let EvaluationError::UndefinedIdentifier(id) = err {
assert_eq!(id, "not_defined")
} else {
panic!("Should have thrown an undefined identifier error")
}
}
#[test]
// Test returning an UndefinedIdentifier error if an identifier is unknown
fn test_undefined_identifier_truthy_ops() {
let err = Evaluator::new().eval("not_defined").unwrap_err();
if let EvaluationError::UndefinedIdentifier(id) = err {
assert_eq!(id, "not_defined")
} else {
panic!("Should have thrown an undefined identifier error")
}
let evaluator = Evaluator::new();
let context = value!({
"NULL": null,
"DEFINED": "string",
});
let test = |expr: &str, is_ok: bool, exp: Value| {
let obs = evaluator.eval_in_context(&expr, context.clone());
if !is_ok {
assert!(obs.is_err());
assert!(matches!(
obs.unwrap_err(),
EvaluationError::UndefinedIdentifier(_)
));
} else {
assert_eq!(obs.unwrap(), exp,);
}
};
test("UNDEFINED", false, value!(null));
test("UNDEFINED == 'string'", false, value!(null));
test("'string' == UNDEFINED", false, value!(null));
test("UNDEFINED ? 'WRONG' : 'RIGHT'", true, value!("RIGHT"));
test("DEFINED ? UNDEFINED : 'WRONG'", false, value!(null));
test("UNDEFINED || 'RIGHT'", true, value!("RIGHT"));
test("'RIGHT' || UNDEFINED", true, value!("RIGHT"));
test("'WRONG' && UNDEFINED", false, value!(null));
test("UNDEFINED && 'WRONG'", false, value!(null));
test("UNDEFINED && 'WRONG'", false, value!(null));
test(
"(UNDEFINED && UNDEFINED == 'string') || (DEFINED && DEFINED == 'string')",
true,
value!(true),
);
}
#[test]
fn test_add_multiple_transforms() {
let evaluator = Evaluator::new()
.with_transform("sqrt", |v: &[Value]| {
let num = v
.first()
.expect("There should be one argument!")
.as_f64()
.expect("Should be a valid number!");
Ok(value!(num.sqrt() as u64))
})
.with_transform("square", |v: &[Value]| {
let num = v
.first()
.expect("There should be one argument!")
.as_f64()
.expect("Should be a valid number!");
Ok(value!((num as u64).pow(2)))
});
assert_eq!(evaluator.eval("4|square").unwrap(), value!(16));
assert_eq!(evaluator.eval("4|sqrt").unwrap(), value!(2));
assert_eq!(evaluator.eval("4|square|sqrt").unwrap(), value!(4));
}
#[test]
fn test_transform_with_argument() {
let evaluator = Evaluator::new().with_transform("split", |args: &[Value]| {
let s = args
.first()
.expect("Should be a first argument!")
.as_str()
.expect("Should be a string!");
let c = args
.get(1)
.expect("There should be a second argument!")
.as_str()
.expect("Should be a string");
let res: Vec<&str> = s.split_terminator(c).collect();
Ok(value!(res))
});
assert_eq!(
evaluator.eval("'John Doe'|split(' ')").unwrap(),
value!(vec!["John", "Doe"])
);
}
#[derive(Debug, thiserror::Error)]
enum CustomError {
#[error("Invalid argument in transform!")]
InvalidArgument,
}
#[test]
fn test_custom_error_message() {
let evaluator = Evaluator::new().with_transform("error", |_: &[Value]| {
Err(CustomError::InvalidArgument.into())
});
let res = evaluator.eval("1234|error");
assert!(res.is_err());
if let EvaluationError::CustomError(e) = res.unwrap_err() {
assert_eq!(e.to_string(), "Invalid argument in transform!")
} else {
panic!("Should have returned a Custom error!")
}
}
#[test]
fn test_filter_collections_many_returned() {
let evaluator = Evaluator::new();
let context = value!({
"foo": [
{"bobo": 50, "fofo": 100},
{"bobo": 60, "baz": 90},
{"bobo": 10, "bar": 83},
{"bobo": 20, "yam": 12},
]
});
let exp = "foo[.bobo >= 50]";
assert_eq!(
evaluator.eval_in_context(exp, context).unwrap(),
value!([{"bobo": 50, "fofo": 100}, {"bobo": 60, "baz": 90}])
);
}
#[test]
fn test_binary_op_eq_ne() {
let evaluator = Evaluator::new();
let context = value!({
"NULL": null,
"STRING": "string",
"BOOLEAN": true,
"NUMBER": 42,
"OBJECT": { "x": 1, "y": 2 },
"ARRAY": [ "string" ]
});
let test = |l: &str, r: &str, exp: bool| {
let expr = format!("{} == {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(exp)
);
let expr = format!("{} != {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(!exp)
);
};
test("STRING", "'string'", true);
test("NUMBER", "42", true);
test("BOOLEAN", "true", true);
test("OBJECT", "OBJECT", true);
test("ARRAY", "[ 'string' ]", true);
test("NULL", "null", true);
test("OBJECT", "{ 'x': 1, 'y': 2 }", false);
test("STRING", "NULL", false);
test("NUMBER", "NULL", false);
test("BOOLEAN", "NULL", false);
// test("NULL", "NULL", false);
test("OBJECT", "NULL", false);
test("ARRAY", "NULL", false);
// test("STRING", "STRING", false);
test("NUMBER", "STRING", false);
test("BOOLEAN", "STRING", false);
test("NULL", "STRING", false);
test("OBJECT", "STRING", false);
test("ARRAY", "STRING", false);
test("STRING", "NUMBER", false);
// test("NUMBER", "NUMBER", false);
test("BOOLEAN", "NUMBER", false);
test("NULL", "NUMBER", false);
test("OBJECT", "NUMBER", false);
test("ARRAY", "NUMBER", false);
test("STRING", "BOOLEAN", false);
test("NUMBER", "BOOLEAN", false);
// test("BOOLEAN", "BOOLEAN", false);
test("NULL", "BOOLEAN", false);
test("OBJECT", "BOOLEAN", false);
test("ARRAY", "BOOLEAN", false);
test("STRING", "OBJECT", false);
test("NUMBER", "OBJECT", false);
test("BOOLEAN", "OBJECT", false);
test("NULL", "OBJECT", false);
// test("OBJECT", "OBJECT", false);
test("ARRAY", "OBJECT", false);
test("STRING", "ARRAY", false);
test("NUMBER", "ARRAY", false);
test("BOOLEAN", "ARRAY", false);
test("NULL", "ARRAY", false);
test("OBJECT", "ARRAY", false);
// test("ARRAY", "ARRAY", false);
}
#[test]
fn test_binary_op_string_gt_lt_gte_lte() {
let evaluator = Evaluator::new();
let context = value!({
"A": "A string",
"B": "B string",
});
let test = |l: &str, r: &str, is_gt: bool| {
let expr = format!("{} > {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(is_gt)
);
let expr = format!("{} <= {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(!is_gt)
);
// we test equality in another test
let expr = format!("{} == {}", l, r);
let is_eq = evaluator
.eval_in_context(&expr, context.clone())
.unwrap()
.as_bool()
.unwrap();
if is_eq {
let expr = format!("{} >= {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(true)
);
} else {
let expr = format!("{} < {}", l, r);
assert_eq!(
evaluator.eval_in_context(&expr, context.clone()).unwrap(),
value!(!is_gt)
);
}
};
test("A", "B", false);
test("B", "A", true);
test("A", "A", false);
}
#[test]
fn test_lazy_eval_binary_op_and_or() {
let evaluator = Evaluator::new();
// error is a missing transform
let res = evaluator.eval("42 || 0|error");
assert!(res.is_ok());
assert_eq!(res.unwrap(), value!(42.0));
let res = evaluator.eval("false || 0|error");
assert!(res.is_err());
let res = evaluator.eval("42 && 0|error");
assert!(res.is_err());
let res = evaluator.eval("false && 0|error");
assert!(res.is_ok());
assert_eq!(res.unwrap(), value!(false));
}
#[test]
fn test_lazy_eval_trinary_op() {
let evaluator = Evaluator::new();
// error is a missing transform
let res = evaluator.eval("true ? 42 : 0|error");
assert!(res.is_ok());
assert_eq!(res.unwrap(), value!(42.0));
let res = evaluator.eval("true ? 0|error : 42");
assert!(res.is_err());
let res = evaluator.eval("true ? 0|error : 42");
assert!(res.is_err());
let res = evaluator.eval("false ? 0|error : 42");
assert!(res.is_ok());
assert_eq!(res.unwrap(), value!(42.0));
}
}

View File

@@ -0,0 +1 @@
{"files":{"Cargo.toml":"0790ec7308b52d99cea53519647fe27ec5c2f0d6329acdec4d810a959878404d","src/ast.rs":"90f6b08e7234033583663a61b1662ec3e9a0a5ef757926af0e0e2a1a703f1fa7","src/lib.rs":"d511dac8488b24e713343cfb6d202d954e48f3c98a375dbd57b7bd29e6b630aa","src/parser.lalrpop":"5c90e7d458c48bafd19cdf4190d2f1362744f5c9cf9294e907819d215d56bcfa","src/parser.rs":"147294fd2854a06e223064f09b46ad608f58dca858c569bff629347068daf1a6"},"package":"07cc5fb813f07eceed953a76345a8af76038ee4101c32dc3740e040595013a84"}

40
third_party/rust/jexl-parser/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,40 @@
# 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 = "2018"
name = "jexl-parser"
version = "0.3.0"
authors = [
"Mike Cooper <mythmon@gmail.com>",
"The Sync Team <sync-team@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
]
build = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A JEXL parser written in Rust"
readme = false
license = "MPL-2.0"
repository = "https://github.com/mozilla/jexl-rs"
[lib]
name = "jexl_parser"
path = "src/lib.rs"
[dependencies.lalrpop-util]
version = "0.19"
features = ["lexer"]
[dependencies.regex]
version = "1.3"

92
third_party/rust/jexl-parser/src/ast.rs vendored Normal file
View File

@@ -0,0 +1,92 @@
/* 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, PartialEq)]
pub enum Expression {
Number(f64),
String(String),
Boolean(bool),
Array(Vec<Box<Expression>>),
Object(Vec<(String, Box<Expression>)>),
Identifier(String),
Null,
BinaryOperation {
operation: OpCode,
left: Box<Expression>,
right: Box<Expression>,
},
Transform {
name: String,
subject: Box<Expression>,
args: Option<Vec<Box<Expression>>>,
},
DotOperation {
subject: Box<Expression>,
ident: String,
},
IndexOperation {
subject: Box<Expression>,
index: Box<Expression>,
},
Conditional {
left: Box<Expression>,
truthy: Box<Expression>,
falsy: Box<Expression>,
},
Filter {
ident: String,
op: OpCode,
right: Box<Expression>,
},
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum OpCode {
Add,
Subtract,
Multiply,
Divide,
FloorDivide,
Less,
LessEqual,
Greater,
GreaterEqual,
Equal,
NotEqual,
And,
Or,
Modulus,
Exponent,
In,
}
impl std::fmt::Display for OpCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
OpCode::Add => "Add",
OpCode::Subtract => "Subtract",
OpCode::Multiply => "Multiply",
OpCode::Divide => "Divide",
OpCode::FloorDivide => "Floor division",
OpCode::Less => "Less than",
OpCode::LessEqual => "Less than or equal to",
OpCode::Greater => "Greater than",
OpCode::GreaterEqual => "Greater than or equal to",
OpCode::Equal => "Equal",
OpCode::NotEqual => "Not equal",
OpCode::And => "Bitwise And",
OpCode::Or => "Bitwise Or",
OpCode::Modulus => "Modulus",
OpCode::Exponent => "Exponent",
OpCode::In => "In",
}
)
}
}

176
third_party/rust/jexl-parser/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,176 @@
/* 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 ast;
#[rustfmt::skip]
mod parser;
pub use lalrpop_util::ParseError;
pub use crate::parser::Token;
pub struct Parser {}
impl Parser {
pub fn parse(input: &str) -> Result<ast::Expression, ParseError<usize, Token, &str>> {
Ok(*parser::ExpressionParser::new().parse(input)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::{Expression, OpCode};
#[test]
fn literal() {
assert_eq!(Parser::parse("1"), Ok(Expression::Number(1.0)));
}
#[test]
fn binary_expression() {
assert_eq!(
Parser::parse("1+2"),
Ok(Expression::BinaryOperation {
operation: OpCode::Add,
left: Box::new(Expression::Number(1.0)),
right: Box::new(Expression::Number(2.0)),
}),
);
}
#[test]
fn binary_expression_whitespace() {
assert_eq!(Parser::parse("1 + 2 "), Parser::parse("1+2"),);
}
#[test]
fn transform_simple_no_args() {
let exp = "'T_T'|lower";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::Transform {
name: "lower".to_string(),
subject: Box::new(Expression::String("T_T".to_string())),
args: None
}
);
}
#[test]
fn transform_multiple_args() {
let exp = "'John Doe'|split(' ')";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::Transform {
name: "split".to_string(),
subject: Box::new(Expression::String("John Doe".to_string())),
args: Some(vec![Box::new(Expression::String(" ".to_string()))])
}
);
}
#[test]
fn trasform_way_too_many_args() {
let exp = "123456|math(12, 35, 100, 31, 90)";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::Transform {
name: "math".to_string(),
subject: Box::new(Expression::Number(123_456f64)),
args: Some(vec![
Box::new(Expression::Number(12f64)),
Box::new(Expression::Number(35f64)),
Box::new(Expression::Number(100f64)),
Box::new(Expression::Number(31f64)),
Box::new(Expression::Number(90f64)),
])
}
);
}
#[test]
fn test_index_op_ident() {
let exp = "foo[0]";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::IndexOperation {
subject: Box::new(Expression::Identifier("foo".to_string())),
index: Box::new(Expression::Number(0f64))
}
);
}
#[test]
fn test_index_op_array_literal() {
let exp = "[1, 2, 3][0]";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::IndexOperation {
subject: Box::new(Expression::Array(vec![
Box::new(Expression::Number(1f64)),
Box::new(Expression::Number(2f64)),
Box::new(Expression::Number(3f64)),
])),
index: Box::new(Expression::Number(0f64))
}
);
}
#[test]
fn test_dot_op_ident() {
let exp = "foo.bar";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::DotOperation {
subject: Box::new(Expression::Identifier("foo".to_string())),
ident: "bar".to_string()
}
);
}
#[test]
fn test_dot_op_equality_with_null() {
let exp = "foo.bar == null";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::BinaryOperation {
operation: OpCode::Equal,
left: Box::new(Expression::DotOperation {
subject: Box::new(Expression::Identifier("foo".to_string())),
ident: "bar".to_string()
}),
right: Box::new(Expression::Null),
}
);
}
#[test]
fn test_dot_op_object_literal() {
let exp = "{'foo': 1}.foo";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::DotOperation {
subject: Box::new(Expression::Object(vec![(
"foo".to_string(),
Box::new(Expression::Number(1f64))
)])),
ident: "foo".to_string()
}
);
}
#[test]
fn test_parsing_null() {
assert_eq!(Parser::parse("null"), Ok(Expression::Null));
}
}

View File

@@ -0,0 +1,172 @@
use std::str::FromStr;
use crate::ast::{Expression, OpCode};
grammar;
pub Expression: Box<Expression> = Expr00;
Expr00: Box<Expression> = {
<left: Expression> <operation: Op10> <right: Expr10> => Box::new(Expression::BinaryOperation { left, right, operation }),
Expr10,
};
Expr10: Box<Expression> = {
<left: Expr10> <operation: Op20> <right: Expr20> => Box::new(Expression::BinaryOperation { left, right, operation }),
Expr20,
};
Expr20: Box<Expression> = {
<left: Expr20> <operation: Op30> <right: Expr30> => Box::new(Expression::BinaryOperation { left, right, operation }),
Expr30,
};
Expr30: Box<Expression> = {
<left: Expr30> <operation: Op40> <right: Expr40> => Box::new(Expression::BinaryOperation { left, right, operation }),
Expr40,
};
Expr40: Box<Expression> = {
<left: Expr40> <operation: Op50> <right: Expr50> => Box::new(Expression::BinaryOperation { left, right, operation }),
Expr50,
};
Expr50: Box<Expression> = {
<left: Expr50> "?" <truthy: Expr60> ":" <falsy: Expr60> => Box::new(Expression::Conditional {left, truthy, falsy}),
Expr60,
}
Expr60: Box<Expression> = {
<subject: Expr60> "|" <name: Identifier> <args: Args?> => Box::new(Expression::Transform{name, subject, args}),
Expr70
};
/// Expression for dereferencing.
/// Used for dereferencing object literals, array literals, and the context
/// There are two types of operations here:
/// - Either a `dot` operation, taking an expression on the left hand side, and an identifier on the right hand side (a string without the quotations)
/// - Or an `index` operation, taking an expression on the left hand side, and another expression inside square ("[]") brackets.
///
/// # Examples:
///
/// Assume our context is the following
/// ```
///{
/// "foo":
/// {
/// "bar": [{"baz": 1}, {"bobo": [13, 12]}]
// }
// }
/// ```
///
/// `foo.bar == [{"baz": 1}, {"bobo": [13, 12]]`
/// `foo.bar[0] == {"baz": 1}`
/// `foo.bar[1].bobo[0] == 13`
/// `[1, 2, 3][1] == 2`
Expr70: Box<Expression> = {
<subject: Expr70> <index: Index> => Box::new(Expression::IndexOperation{subject, index}),
<subject: Expr70> "." <ident: Identifier> => Box::new(Expression::DotOperation{subject, ident}),
Expr80
};
Expr80: Box<Expression> = {
Number => Box::new(Expression::Number(<>)),
Boolean => Box::new(Expression::Boolean(<>)),
String => Box::new(Expression::String(<>)),
Array => Box::new(Expression::Array(<>)),
Object => Box::new(Expression::Object(<>)),
Null => Box::new(Expression::Null),
Identifier => Box::new(Expression::Identifier(<>)),
"(" <Expression> ")",
};
Args: Vec<Box<Expression>> = {
"(" <Comma<Expression>> ")"
};
Op10: OpCode = {
"&&" => OpCode::And,
"||" => OpCode::Or,
};
Op20: OpCode = {
"==" => OpCode::Equal,
"!=" => OpCode::NotEqual,
">=" => OpCode::GreaterEqual,
"<=" => OpCode::LessEqual,
">" => OpCode::Greater,
"<" => OpCode::Less,
"in" => OpCode::In,
};
Op30: OpCode = {
"+" => OpCode::Add,
"-" => OpCode::Subtract,
};
Op40: OpCode = {
"*" => OpCode::Multiply,
"//" => OpCode::FloorDivide,
"/" => OpCode::Divide,
};
Op50: OpCode = {
"%" => OpCode::Modulus,
"^" => OpCode::Exponent,
};
Number: f64 = {
r"[0-9]+" => f64::from_str(<>).unwrap(),
r"[0-9]+\.[0-9]*" => f64::from_str(<>).unwrap(),
r"\.[0-9]+" => f64::from_str(<>).unwrap(),
};
String: String = {
<s: r#""([^"\\]*(\\")?)*""#> => s[1..s.len() - 1].to_string().replace("\\\"", "\""),
<s: r#"'([^'\\]*(\\')?)*'"#> => s[1..s.len() - 1].to_string().replace("\\'", "'"),
};
Null: Option<Box<Expression>> = {
"null" => None,
}
Identifier: String = {
r#"[a-zA-Z_][a-zA-Z0-9_]*"# => <>.to_string()
}
Index: Box<Expression> = {
"[" "." <ident: Identifier> <op: Op20> <right: Expr80> "]" => Box::new(Expression::Filter {ident, op, right}),
"[" <Expression> "]",
}
Boolean: bool = {
"true" => true,
"false" => false,
}
Comma<T>: Vec<T> = {
<v: (<T> ",")*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
};
Array: Vec<Box<Expression>> = {
"[" <Comma<Expression>> "]"
}
Object: Vec<(String, Box<Expression>)> = {
"{" <Comma<(<ObjectIdentifier> ":" <Expression>)>> "}",
"{}" => vec![],
}
ObjectIdentifier: String = {
String,
Identifier
}

3837
third_party/rust/jexl-parser/src/parser.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
{"files":{"Cargo.toml":"8036c8e62e906ae0283522596e7feea227003a2e24ec9d50c43d56cfd009e84e","src/lexer.rs":"4ee17af37b6485a6e9ab0b62f3b2a235f891fd29dcc8351ab9205fb094d76298","src/lib.rs":"00f382b59f3a7d12e32062dcdce123a748c68cd29c8213fd0abfcbb87cb34d27","src/state_machine.rs":"2cea04bbd84eabc807956fca779eb054596b0fd23e3c8edab41f7cfc9276b821"},"package":"d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed"}

View File

@@ -0,0 +1,34 @@
# 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 = "2018"
name = "lalrpop-util"
version = "0.19.12"
authors = ["Niko Matsakis <niko@alum.mit.edu>"]
description = "Runtime library for parsers generated by LALRPOP"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/lalrpop/lalrpop"
[package.metadata.docs.rs]
features = ["lexer"]
[dependencies.regex]
version = "1"
optional = true
[features]
default = ["std"]
lexer = [
"regex/std",
"std",
]
std = []

View File

@@ -0,0 +1,128 @@
use std::{fmt, marker::PhantomData};
use crate::ParseError;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Token<'input>(pub usize, pub &'input str);
impl<'a> fmt::Display for Token<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fmt::Display::fmt(self.1, formatter)
}
}
struct RegexEntry {
regex: regex::Regex,
skip: bool,
}
pub struct MatcherBuilder {
regex_set: regex::RegexSet,
regex_vec: Vec<RegexEntry>,
}
impl MatcherBuilder {
pub fn new<S>(
exprs: impl IntoIterator<Item = (S, bool)>,
) -> Result<MatcherBuilder, regex::Error>
where
S: AsRef<str>,
{
let exprs = exprs.into_iter();
let mut regex_vec = Vec::with_capacity(exprs.size_hint().0);
let mut first_error = None;
let regex_set_result = regex::RegexSet::new(exprs.scan((), |_, (s, skip)| {
regex_vec.push(match regex::Regex::new(s.as_ref()) {
Ok(regex) => RegexEntry { regex, skip },
Err(err) => {
first_error = Some(err);
return None;
}
});
Some(s)
}));
if let Some(err) = first_error {
return Err(err);
}
let regex_set = regex_set_result?;
Ok(MatcherBuilder {
regex_set,
regex_vec,
})
}
pub fn matcher<'input, 'builder, E>(
&'builder self,
s: &'input str,
) -> Matcher<'input, 'builder, E> {
Matcher {
text: s,
consumed: 0,
regex_set: &self.regex_set,
regex_vec: &self.regex_vec,
_marker: PhantomData,
}
}
}
pub struct Matcher<'input, 'builder, E> {
text: &'input str,
consumed: usize,
regex_set: &'builder regex::RegexSet,
regex_vec: &'builder Vec<RegexEntry>,
_marker: PhantomData<fn() -> E>,
}
impl<'input, 'builder, E> Iterator for Matcher<'input, 'builder, E> {
type Item = Result<(usize, Token<'input>, usize), ParseError<usize, Token<'input>, E>>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let text = self.text;
let start_offset = self.consumed;
if text.is_empty() {
self.consumed = start_offset;
return None;
} else {
let matches = self.regex_set.matches(text);
if !matches.matched_any() {
return Some(Err(ParseError::InvalidToken {
location: start_offset,
}));
} else {
let mut longest_match = 0;
let mut index = 0;
let mut skip = false;
for i in matches.iter() {
let entry = &self.regex_vec[i];
let match_ = entry.regex.find(text).unwrap();
let len = match_.end();
if len >= longest_match {
longest_match = len;
index = i;
skip = entry.skip;
}
}
let result = &text[..longest_match];
let remaining = &text[longest_match..];
let end_offset = start_offset + longest_match;
self.text = remaining;
self.consumed = end_offset;
// Skip any whitespace matches
if skip {
if longest_match == 0 {
return Some(Err(ParseError::InvalidToken {
location: start_offset,
}));
}
continue;
}
return Some(Ok((start_offset, Token(index, result), end_offset)));
}
}
}
}
}

217
third_party/rust/lalrpop-util/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,217 @@
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::{string::String, vec::Vec};
use core::fmt;
#[cfg(feature = "std")]
use std::error::Error;
#[cfg(feature = "lexer")]
pub mod lexer;
pub mod state_machine;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ParseError<L, T, E> {
/// Generated by the parser when it encounters a token (or EOF) it did not
/// expect.
InvalidToken { location: L },
/// Generated by the parser when it encounters an EOF it did not expect.
UnrecognizedEOF {
/// The end of the final token
location: L,
/// The set of expected tokens: these names are taken from the
/// grammar and hence may not necessarily be suitable for
/// presenting to the user.
expected: Vec<String>,
},
/// Generated by the parser when it encounters a token it did not expect.
UnrecognizedToken {
/// The unexpected token of type `T` with a span given by the two `L` values.
token: (L, T, L),
/// The set of expected tokens: these names are taken from the
/// grammar and hence may not necessarily be suitable for
/// presenting to the user.
expected: Vec<String>,
},
/// Generated by the parser when it encounters additional, unexpected tokens.
ExtraToken { token: (L, T, L) },
/// Custom error type.
User { error: E },
}
impl<L, T, E> ParseError<L, T, E> {
fn map_intern<LL, TT, EE>(
self,
mut loc_op: impl FnMut(L) -> LL,
tok_op: impl FnOnce(T) -> TT,
err_op: impl FnOnce(E) -> EE,
) -> ParseError<LL, TT, EE> {
let maptok = |(s, t, e): (L, T, L)| (loc_op(s), tok_op(t), loc_op(e));
match self {
ParseError::InvalidToken { location } => ParseError::InvalidToken {
location: loc_op(location),
},
ParseError::UnrecognizedEOF { location, expected } => ParseError::UnrecognizedEOF {
location: loc_op(location),
expected,
},
ParseError::UnrecognizedToken { token, expected } => ParseError::UnrecognizedToken {
token: maptok(token),
expected,
},
ParseError::ExtraToken { token } => ParseError::ExtraToken {
token: maptok(token),
},
ParseError::User { error } => ParseError::User {
error: err_op(error),
},
}
}
pub fn map_location<LL>(self, op: impl FnMut(L) -> LL) -> ParseError<LL, T, E> {
self.map_intern(op, |x| x, |x| x)
}
pub fn map_token<TT>(self, op: impl FnOnce(T) -> TT) -> ParseError<L, TT, E> {
self.map_intern(|x| x, op, |x| x)
}
pub fn map_error<EE>(self, op: impl FnOnce(E) -> EE) -> ParseError<L, T, EE> {
self.map_intern(|x| x, |x| x, op)
}
}
/// Format a list of expected tokens.
fn fmt_expected(f: &mut fmt::Formatter<'_>, expected: &[String]) -> fmt::Result {
if !expected.is_empty() {
writeln!(f)?;
for (i, e) in expected.iter().enumerate() {
let sep = match i {
0 => "Expected one of",
_ if i < expected.len() - 1 => ",",
// Last expected message to be written
_ => " or",
};
write!(f, "{} {}", sep, e)?;
}
}
Ok(())
}
impl<L, T, E> fmt::Display for ParseError<L, T, E>
where
L: fmt::Display,
T: fmt::Display,
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::ParseError::*;
match *self {
User { ref error } => write!(f, "{}", error),
InvalidToken { ref location } => write!(f, "Invalid token at {}", location),
UnrecognizedEOF {
ref location,
ref expected,
} => {
write!(f, "Unrecognized EOF found at {}", location)?;
fmt_expected(f, expected)
}
UnrecognizedToken {
token: (ref start, ref token, ref end),
ref expected,
} => {
write!(
f,
"Unrecognized token `{}` found at {}:{}",
token, start, end
)?;
fmt_expected(f, expected)
}
ExtraToken {
token: (ref start, ref token, ref end),
} => write!(f, "Extra token {} found at {}:{}", token, start, end),
}
}
}
impl<L, T, E> From<E> for ParseError<L, T, E> {
fn from(error: E) -> Self {
ParseError::User { error }
}
}
#[cfg(feature = "std")]
impl<L, T, E> Error for ParseError<L, T, E>
where
L: fmt::Debug + fmt::Display,
T: fmt::Debug + fmt::Display,
E: fmt::Debug + fmt::Display,
{
fn description(&self) -> &str {
"parse error"
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ErrorRecovery<L, T, E> {
pub error: ParseError<L, T, E>,
pub dropped_tokens: Vec<(L, T, L)>,
}
/// Define a module using the generated parse from a `.lalrpop` file.
///
/// You have to specify the name of the module and the path of the file
/// generated by LALRPOP. If the input is in the root directory, you can
/// omit it.
///
/// # Example
/// ```ignore
/// // load parser in src/parser.lalrpop
/// lalrpop_mod!(parser);
///
/// // load parser in src/lex/parser.lalrpop
/// lalrpop_mod!(parser, "/lex/parser.rs");
///
/// // define a public module
/// lalrpop_mod!(pub parser);
/// ```
#[macro_export]
macro_rules! lalrpop_mod {
($(#[$attr:meta])* $vis:vis $modname:ident) => {
lalrpop_mod!($(#[$attr])* $vis $modname, concat!("/", stringify!($modname), ".rs"));
};
($(#[$attr:meta])* $vis:vis $modname:ident, $source:expr) => {
$(#[$attr])* $vis mod $modname { include!(concat!(env!("OUT_DIR"), $source)); }
};
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::{format, vec, string::ToString};
#[test]
fn test() {
let err = ParseError::UnrecognizedToken::<i32, &str, &str> {
token: (1, "t0", 2),
expected: vec!["t1", "t2", "t3"]
.into_iter()
.map(|s| s.to_string())
.collect(),
};
assert_eq!(
format!("{}", err),
"Unrecognized token `t0` found at 1:2\n\
Expected one of t1, t2 or t3"
);
}
}

View File

@@ -0,0 +1,673 @@
#![allow(dead_code)]
use alloc::{string::String, vec, vec::Vec};
use core::fmt::Debug;
#[cfg(feature = "std")]
const DEBUG_ENABLED: bool = false;
macro_rules! debug {
($($args:expr),* $(,)*) => {
#[cfg(feature = "std")]
if DEBUG_ENABLED {
eprintln!($($args),*);
}
}
}
pub trait ParserDefinition: Sized {
/// Represents a location in the input text. If you are using the
/// default tokenizer, this will be a `usize`.
type Location: Clone + Debug;
/// Represents a "user error" -- this can get produced by
/// `reduce()` if the grammar includes `=>?` actions.
type Error;
/// The type emitted by the user's tokenizer (excluding the
/// location information).
type Token: Clone + Debug;
/// We assign a unique index to each token in the grammar, which
/// we call its *index*. When we pull in a new `Token` from the
/// input, we then match against it to determine its index. Note
/// that the actual `Token` is retained too, as it may carry
/// additional information (e.g., an `ID` terminal often has a
/// string value associated with it; this is not important to the
/// parser, but the semantic analyzer will want it).
type TokenIndex: Copy + Clone + Debug;
/// The type representing things on the LALRPOP stack. Represents
/// the union of terminals and nonterminals.
type Symbol;
/// Type produced by reducing the start symbol.
type Success;
/// Identifies a state. Typically an i8, i16, or i32 (depending on
/// how many states you have).
type StateIndex: Copy + Clone + Debug;
/// Identifies an action.
type Action: ParserAction<Self>;
/// Identifies a reduction.
type ReduceIndex: Copy + Clone + Debug;
/// Identifies a nonterminal.
type NonterminalIndex: Copy + Clone + Debug;
/// Returns a location representing the "start of the input".
fn start_location(&self) -> Self::Location;
/// Returns the initial state.
fn start_state(&self) -> Self::StateIndex;
/// Converts the user's tokens into an internal index; this index
/// is then used to index into actions and the like. When using an
/// internal tokenizer, these indices are directly produced. When
/// using an **external** tokenier, however, this function matches
/// against the patterns given by the user: it is fallible
/// therefore as these patterns may not be exhaustive. If a token
/// value is found that doesn't match any of the patterns the user
/// supplied, then this function returns `None`, which is
/// translated into a parse error by LALRPOP ("unrecognized
/// token").
fn token_to_index(&self, token: &Self::Token) -> Option<Self::TokenIndex>;
/// Given the top-most state and the pending terminal, returns an
/// action. This can be either SHIFT(state), REDUCE(action), or
/// ERROR.
fn action(&self, state: Self::StateIndex, token_index: Self::TokenIndex) -> Self::Action;
/// Returns the action to take if an error occurs in the given
/// state. This function is the same as the ordinary `action`,
/// except that it applies not to the user's terminals but to the
/// "special terminal" `!`.
fn error_action(&self, state: Self::StateIndex) -> Self::Action;
/// Action to take if EOF occurs in the given state. This function
/// is the same as the ordinary `action`, except that it applies
/// not to the user's terminals but to the "special terminal" `$`.
fn eof_action(&self, state: Self::StateIndex) -> Self::Action;
/// If we reduce to a nonterminal in the given state, what state
/// do we go to? This is infallible due to the nature of LR(1)
/// grammars.
fn goto(&self, state: Self::StateIndex, nt: Self::NonterminalIndex) -> Self::StateIndex;
/// "Upcast" a terminal into a symbol so we can push it onto the
/// parser stack.
fn token_to_symbol(&self, token_index: Self::TokenIndex, token: Self::Token) -> Self::Symbol;
/// Returns the expected tokens in a given state. This is used for
/// error reporting.
fn expected_tokens(&self, state: Self::StateIndex) -> Vec<String>;
/// True if this grammar supports error recovery.
fn uses_error_recovery(&self) -> bool;
/// Given error information, creates an error recovery symbol that
/// we push onto the stack (and supply to user actions).
fn error_recovery_symbol(&self, recovery: ErrorRecovery<Self>) -> Self::Symbol;
/// Execute a reduction in the given state: that is, execute user
/// code. The start location indicates the "starting point" of the
/// current lookahead that is triggering the reduction (it is
/// `None` for EOF).
///
/// The `states` and `symbols` vectors represent the internal
/// state machine vectors; they are given to `reduce` so that it
/// can pop off states that no longer apply (and consume their
/// symbols). At the end, it should also push the new state and
/// symbol produced.
///
/// Returns a `Some` if we reduced the start state and hence
/// parsing is complete, or if we encountered an irrecoverable
/// error.
///
/// FIXME. It would be nice to not have so much logic live in
/// reduce. It should just be given an iterator of popped symbols
/// and return the newly produced symbol (or error). We can use
/// `simulate_reduce` and our own information to drive the rest,
/// right? This would also allow us -- I think -- to extend error
/// recovery to cover user-produced errors.
fn reduce(
&mut self,
reduce_index: Self::ReduceIndex,
start_location: Option<&Self::Location>,
states: &mut Vec<Self::StateIndex>,
symbols: &mut Vec<SymbolTriple<Self>>,
) -> Option<ParseResult<Self>>;
/// Returns information about how many states will be popped
/// during a reduction, and what nonterminal would be produced as
/// a result.
fn simulate_reduce(&self, action: Self::ReduceIndex) -> SimulatedReduce<Self>;
}
pub trait ParserAction<D: ParserDefinition>: Copy + Clone + Debug {
fn as_shift(self) -> Option<D::StateIndex>;
fn as_reduce(self) -> Option<D::ReduceIndex>;
fn is_shift(self) -> bool;
fn is_reduce(self) -> bool;
fn is_error(self) -> bool;
}
pub enum SimulatedReduce<D: ParserDefinition> {
Reduce {
states_to_pop: usize,
nonterminal_produced: D::NonterminalIndex,
},
// This reduce is the "start" fn, so the parse is done.
Accept,
}
// These aliases are an elaborate hack to get around
// the warnings when you define a type alias like `type Foo<D: Trait>`
#[doc(hidden)]
pub type Location<D> = <D as ParserDefinition>::Location;
#[doc(hidden)]
pub type Token<D> = <D as ParserDefinition>::Token;
#[doc(hidden)]
pub type Error<D> = <D as ParserDefinition>::Error;
#[doc(hidden)]
pub type Success<D> = <D as ParserDefinition>::Success;
#[doc(hidden)]
pub type Symbol<D> = <D as ParserDefinition>::Symbol;
pub type ParseError<D> = crate::ParseError<Location<D>, Token<D>, Error<D>>;
pub type ParseResult<D> = Result<Success<D>, ParseError<D>>;
pub type TokenTriple<D> = (Location<D>, Token<D>, Location<D>);
pub type SymbolTriple<D> = (Location<D>, Symbol<D>, Location<D>);
pub type ErrorRecovery<D> = crate::ErrorRecovery<Location<D>, Token<D>, Error<D>>;
pub struct Parser<D, I>
where
D: ParserDefinition,
I: Iterator<Item = Result<TokenTriple<D>, ParseError<D>>>,
{
definition: D,
tokens: I,
states: Vec<D::StateIndex>,
symbols: Vec<SymbolTriple<D>>,
last_location: D::Location,
}
enum NextToken<D: ParserDefinition> {
FoundToken(TokenTriple<D>, D::TokenIndex),
EOF,
Done(ParseResult<D>),
}
impl<D, I> Parser<D, I>
where
D: ParserDefinition,
I: Iterator<Item = Result<TokenTriple<D>, ParseError<D>>>,
{
pub fn drive(definition: D, tokens: I) -> ParseResult<D> {
let last_location = definition.start_location();
let start_state = definition.start_state();
Parser {
definition,
tokens,
states: vec![start_state],
symbols: vec![],
last_location,
}
.parse()
}
fn top_state(&self) -> D::StateIndex {
*self.states.last().unwrap()
}
fn parse(&mut self) -> ParseResult<D> {
// Outer loop: each time we continue around this loop, we
// shift a new token from the input. We break from the loop
// when the end of the input is reached (we return early if an
// error occurs).
'shift: loop {
let (mut lookahead, mut token_index) = match self.next_token() {
NextToken::FoundToken(l, i) => (l, i),
NextToken::EOF => return self.parse_eof(),
NextToken::Done(e) => return e,
};
debug!("+ SHIFT: {:?}", lookahead);
debug!("\\ token_index: {:?}", token_index);
'inner: loop {
let top_state = self.top_state();
let action = self.definition.action(top_state, token_index);
debug!("\\ action: {:?}", action);
if let Some(target_state) = action.as_shift() {
debug!("\\ shift to: {:?}", target_state);
// Shift and transition to state `action - 1`
let symbol = self.definition.token_to_symbol(token_index, lookahead.1);
self.states.push(target_state);
self.symbols.push((lookahead.0, symbol, lookahead.2));
continue 'shift;
} else if let Some(reduce_index) = action.as_reduce() {
debug!("\\ reduce to: {:?}", reduce_index);
if let Some(r) = self.reduce(reduce_index, Some(&lookahead.0)) {
return match r {
// we reached eof, but still have lookahead
Ok(_) => Err(crate::ParseError::ExtraToken { token: lookahead }),
Err(e) => Err(e),
};
}
} else {
debug!("\\ error -- initiating error recovery!");
match self.error_recovery(Some(lookahead), Some(token_index)) {
NextToken::FoundToken(l, i) => {
lookahead = l;
token_index = i;
continue 'inner;
}
NextToken::EOF => return self.parse_eof(),
NextToken::Done(e) => return e,
}
}
}
}
}
/// Invoked when we have no more tokens to consume.
fn parse_eof(&mut self) -> ParseResult<D> {
loop {
let top_state = self.top_state();
let action = self.definition.eof_action(top_state);
if let Some(reduce_index) = action.as_reduce() {
if let Some(result) =
self.definition
.reduce(reduce_index, None, &mut self.states, &mut self.symbols)
{
return result;
}
} else {
match self.error_recovery(None, None) {
NextToken::FoundToken(..) => panic!("cannot find token at EOF"),
NextToken::Done(e) => return e,
NextToken::EOF => continue,
}
}
}
}
fn error_recovery(
&mut self,
mut opt_lookahead: Option<TokenTriple<D>>,
mut opt_token_index: Option<D::TokenIndex>,
) -> NextToken<D> {
debug!(
"\\+ error_recovery(opt_lookahead={:?}, opt_token_index={:?})",
opt_lookahead, opt_token_index,
);
if !self.definition.uses_error_recovery() {
debug!("\\ error -- no error recovery!");
return NextToken::Done(Err(
self.unrecognized_token_error(opt_lookahead, self.top_state())
));
}
let error = self.unrecognized_token_error(opt_lookahead.clone(), self.top_state());
let mut dropped_tokens = vec![];
// We are going to insert ERROR into the lookahead. So, first,
// perform all reductions from current state triggered by having
// ERROR in the lookahead.
loop {
let state = self.top_state();
let action = self.definition.error_action(state);
if let Some(reduce_index) = action.as_reduce() {
debug!("\\\\ reducing: {:?}", reduce_index);
if let Some(result) =
self.reduce(reduce_index, opt_lookahead.as_ref().map(|l| &l.0))
{
debug!("\\\\ reduced to a result");
return NextToken::Done(result);
}
} else {
break;
}
}
// Now try to find the recovery state.
let states_len = self.states.len();
let top = 'find_state: loop {
// Go backwards through the states...
debug!(
"\\\\+ error_recovery: find_state loop, {:?} states = {:?}",
self.states.len(),
self.states,
);
for top in (0..states_len).rev() {
let state = self.states[top];
debug!("\\\\\\ top = {:?}, state = {:?}", top, state);
// ...fetch action for error token...
let action = self.definition.error_action(state);
debug!("\\\\\\ action = {:?}", action);
if let Some(error_state) = action.as_shift() {
// If action is a shift that takes us into `error_state`,
// and `error_state` can accept this lookahead, we are done.
if self.accepts(error_state, &self.states[..=top], opt_token_index) {
debug!("\\\\\\ accepted!");
break 'find_state top;
}
} else {
// ...else, if action is error or reduce, go to next state.
continue;
}
}
// Otherwise, if we couldn't find a state that would --
// after shifting the error token -- accept the lookahead,
// then drop the lookahead and advance to next token in
// the input.
match opt_lookahead.take() {
// If the lookahead is EOF, we can't drop any more
// tokens, abort error recovery and just report the
// original error (it might be nice if we would
// propagate back the dropped tokens, though).
None => {
debug!("\\\\\\ no more lookahead, report error");
return NextToken::Done(Err(error));
}
// Else, drop the current token and shift to the
// next. If there is a next token, we will `continue`
// to the start of the `'find_state` loop.
Some(lookahead) => {
debug!("\\\\\\ dropping lookahead token");
dropped_tokens.push(lookahead);
match self.next_token() {
NextToken::FoundToken(next_lookahead, next_token_index) => {
opt_lookahead = Some(next_lookahead);
opt_token_index = Some(next_token_index);
}
NextToken::EOF => {
debug!("\\\\\\ reached EOF");
opt_lookahead = None;
opt_token_index = None;
}
NextToken::Done(e) => {
debug!("\\\\\\ no more tokens");
return NextToken::Done(e);
}
}
}
}
};
// If we get here, we are ready to push the error recovery state.
// We have to compute the span for the error recovery
// token. We do this first, before we pop any symbols off the
// stack. There are several possibilities, in order of
// preference.
//
// For the **start** of the message, we prefer to use the start of any
// popped states. This represents parts of the input we had consumed but
// had to roll back and ignore.
//
// Example:
//
// a + (b + /)
// ^ start point is here, since this `+` will be popped off
//
// If there are no popped states, but there *are* dropped tokens, we can use
// the start of those.
//
// Example:
//
// a + (b + c e)
// ^ start point would be here
//
// Finally, if there are no popped states *nor* dropped tokens, we can use
// the end of the top-most state.
let start = if let Some(popped_sym) = self.symbols.get(top) {
popped_sym.0.clone()
} else if let Some(dropped_token) = dropped_tokens.first() {
dropped_token.0.clone()
} else if top > 0 {
self.symbols[top - 1].2.clone()
} else {
self.definition.start_location()
};
// For the end span, here are the possibilities:
//
// We prefer to use the end of the last dropped token.
//
// Examples:
//
// a + (b + /)
// ---
// a + (b c)
// -
//
// But, if there are no dropped tokens, we will use the end of the popped states,
// if any:
//
// a + /
// -
//
// If there are neither dropped tokens *or* popped states,
// then the user is simulating insertion of an operator. In
// this case, we prefer the start of the lookahead, but
// fallback to the start if we are at EOF.
//
// Examples:
//
// a + (b c)
// -
let end = if let Some(dropped_token) = dropped_tokens.last() {
dropped_token.2.clone()
} else if states_len - 1 > top {
self.symbols.last().unwrap().2.clone()
} else if let Some(lookahead) = opt_lookahead.as_ref() {
lookahead.0.clone()
} else {
start.clone()
};
self.states.truncate(top + 1);
self.symbols.truncate(top);
let recover_state = self.states[top];
let error_action = self.definition.error_action(recover_state);
let error_state = error_action.as_shift().unwrap();
self.states.push(error_state);
let recovery = self.definition.error_recovery_symbol(crate::ErrorRecovery {
error,
dropped_tokens,
});
self.symbols.push((start, recovery, end));
match (opt_lookahead, opt_token_index) {
(Some(l), Some(i)) => NextToken::FoundToken(l, i),
(None, None) => NextToken::EOF,
(l, i) => panic!("lookahead and token_index mismatched: {:?}, {:?}", l, i),
}
}
/// The `accepts` function has the job of figuring out whether the
/// given error state would "accept" the given lookahead. We
/// basically trace through the LR automaton looking for one of
/// two outcomes:
///
/// - the lookahead is eventually shifted
/// - we reduce to the end state successfully (in the case of EOF).
///
/// If we used the pure LR(1) algorithm, we wouldn't need this
/// function, because we would be guaranteed to error immediately
/// (and not after some number of reductions). But with an LALR
/// (or Lane Table) generated automaton, it is possible to reduce
/// some number of times before encountering an error. Failing to
/// take this into account can lead error recovery into an
/// infinite loop (see the `error_recovery_lalr_loop` test) or
/// produce crappy results (see `error_recovery_lock_in`).
fn accepts(
&self,
error_state: D::StateIndex,
states: &[D::StateIndex],
opt_token_index: Option<D::TokenIndex>,
) -> bool {
debug!(
"\\\\\\+ accepts(error_state={:?}, states={:?}, opt_token_index={:?})",
error_state, states, opt_token_index,
);
let mut states = states.to_vec();
states.push(error_state);
loop {
let mut states_len = states.len();
let top = states[states_len - 1];
let action = match opt_token_index {
None => self.definition.eof_action(top),
Some(i) => self.definition.action(top, i),
};
// If we encounter an error action, we do **not** accept.
if action.is_error() {
debug!("\\\\\\\\ accepts: error");
return false;
}
// If we encounter a reduce action, we need to simulate its
// effect on the state stack.
if let Some(reduce_action) = action.as_reduce() {
match self.definition.simulate_reduce(reduce_action) {
SimulatedReduce::Reduce {
states_to_pop,
nonterminal_produced,
} => {
states_len -= states_to_pop;
states.truncate(states_len);
let top = states[states_len - 1];
let next_state = self.definition.goto(top, nonterminal_produced);
states.push(next_state);
}
SimulatedReduce::Accept => {
debug!("\\\\\\\\ accepts: reduce accepts!");
return true;
}
}
} else {
// If we encounter a shift action, we DO accept.
debug!("\\\\\\\\ accepts: shift accepts!");
assert!(action.is_shift());
return true;
}
}
}
fn reduce(
&mut self,
action: D::ReduceIndex,
lookahead_start: Option<&D::Location>,
) -> Option<ParseResult<D>> {
self.definition
.reduce(action, lookahead_start, &mut self.states, &mut self.symbols)
}
fn unrecognized_token_error(
&self,
token: Option<TokenTriple<D>>,
top_state: D::StateIndex,
) -> ParseError<D> {
match token {
Some(token) => crate::ParseError::UnrecognizedToken {
token,
expected: self.definition.expected_tokens(top_state),
},
None => crate::ParseError::UnrecognizedEOF {
location: self.last_location.clone(),
expected: self.definition.expected_tokens(top_state),
},
}
}
/// Consume the next token from the input and classify it into a
/// token index. Classification can fail with an error. If there
/// are no more tokens, signal EOF.
fn next_token(&mut self) -> NextToken<D> {
let token = match self.tokens.next() {
Some(Ok(v)) => v,
Some(Err(e)) => return NextToken::Done(Err(e)),
None => return NextToken::EOF,
};
self.last_location = token.2.clone();
let token_index = match self.definition.token_to_index(&token.1) {
Some(i) => i,
None => {
return NextToken::Done(Err(
self.unrecognized_token_error(Some(token), self.top_state())
))
}
};
NextToken::FoundToken(token, token_index)
}
}
/// In LALRPOP generated rules, we actually use `i32`, `i16`, or `i8`
/// to represent all of the various indices (we use the smallest one
/// that will fit). So implement `ParserAction` for each of those.
macro_rules! integral_indices {
($t:ty) => {
impl<D: ParserDefinition<StateIndex = $t, ReduceIndex = $t>> ParserAction<D> for $t {
fn as_shift(self) -> Option<D::StateIndex> {
if self > 0 {
Some(self - 1)
} else {
None
}
}
fn as_reduce(self) -> Option<D::ReduceIndex> {
if self < 0 {
Some(-(self + 1))
} else {
None
}
}
fn is_shift(self) -> bool {
self > 0
}
fn is_reduce(self) -> bool {
self < 0
}
fn is_error(self) -> bool {
self == 0
}
}
};
}
integral_indices!(i32);
integral_indices!(i16);
integral_indices!(i8);

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"d9eb25783f4d9983b705ded68b5fedf39d73257b19bbf688a5c969c49ebd675f","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-v2.json":"c33698dd66ed7f9dbbda857cad4f890455189e932e24c0d3b335e3e95b65239f","dumps/main/search-telemetry-v2.json":"140b3d322d6e317d97542725920be9f29c6b1d9c5f224e8c31995dddfec6bf1b","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"386a8cf39bda555f042ace8454651c912525ba957f947a2e0bf91a731c62687b","src/config.rs":"603c7241483861a8c690464f4b50dd3dc281da7edf8aa522f90f175b85a7fa5f","src/error.rs":"20e40a0229842e12888bc43c4159e078f1d09272a43c51dae87989f76952f93b","src/jexl_filter.rs":"e085f92b0ef9031106cf5d4999dbb19f467494c029f324b25d0098506b37b2e1","src/lib.rs":"890d7f5f5493ea6cfed101dc7cca934522b0de37eafad542123b5cb6ccce7f9e","src/macros.rs":"19735d74b6ce8d1fc21a85c39787a271f09a849a310db16ba36219aba9106736","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"73da6cecc8c804b8e55d35ea3c71c1dd1e4099ad60532b7b0da153f9cde1eb21","src/signatures.rs":"5946518b69265be9da908097c0e994df24c77a36e5881eb29bb0f4107018279d","src/storage.rs":"5ae489964d82a0305a6b250d92f4c1925cc722e44890c24f681dd97b0258b9f4","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null}
{"files":{"Cargo.toml":"5d106662de7bd8f65f1c50edb46a11f54f38a91e08ccf57521978d42086fb53e","dumps/main/attachments/regions/world":"00b308033d44f61612b962f572765d14a3999586d92fc8b9fff2217a1ae070e8","dumps/main/attachments/regions/world-buffered":"1d3ed6954fac2a5b31302f5d3e8186c5fa08a20239afc0643ca5dfbb4d8a86fc","dumps/main/attachments/regions/world-buffered.meta.json":"914a71376a152036aceccb6877e079fbb9e3373c6219f24f00dd30e901a72cce","dumps/main/attachments/regions/world.meta.json":"2a47d77834997b98e563265d299723e7f7fd64c8c7a5731afc722862333d6fbd","dumps/main/regions.json":"e8990158373f82d3f89fed5089cf29e4177cc85904479128728e05025e9a0c0c","dumps/main/search-config-v2.json":"c33698dd66ed7f9dbbda857cad4f890455189e932e24c0d3b335e3e95b65239f","dumps/main/search-telemetry-v2.json":"140b3d322d6e317d97542725920be9f29c6b1d9c5f224e8c31995dddfec6bf1b","src/cache.rs":"c6179802017b43885136e7d64004890cc13e8c2d4742e04073cf404b578f63db","src/client.rs":"875a0bc5c8b3572ed86cd4b43277a715f95592c3d8ab1dd6528394ab6ad71ec3","src/config.rs":"603c7241483861a8c690464f4b50dd3dc281da7edf8aa522f90f175b85a7fa5f","src/error.rs":"20e40a0229842e12888bc43c4159e078f1d09272a43c51dae87989f76952f93b","src/jexl_filter.rs":"e4a9e29a80b216d777771434aaa6c58f627288e4b59ffa11c83dbd8e37889aa5","src/lib.rs":"fbf4e1f270380af00747294ec77ab6bfb724aa38e83bcb8d33fac3f1107850d5","src/macros.rs":"6b06d0ba42ee95235bfd71bac1a0eed02f60c894775ebee64165648b10e932c4","src/schema.rs":"348e0d5ad1840aaae796b537d21381ef91bd75be262138bfec376d9f88d205b3","src/service.rs":"73da6cecc8c804b8e55d35ea3c71c1dd1e4099ad60532b7b0da153f9cde1eb21","src/signatures.rs":"baa2dae76abd8166158fea4676e67e17c17b65af6968de52768350409dbd7092","src/storage.rs":"5ae489964d82a0305a6b250d92f4c1925cc722e44890c24f681dd97b0258b9f4","uniffi.toml":"bd7cc0e7c1981f53938f429c4f2541ac454ed4160a8a0b4670659e38acd23ee5"},"package":null}

View File

@@ -33,7 +33,6 @@ license = "MPL-2.0"
[features]
default = []
jexl = ["dep:jexl-eval"]
signatures = [
"dep:canonical_json",
"dep:rc_crypto",
@@ -66,7 +65,6 @@ path = "../support/firefox-versioning"
[dependencies.jexl-eval]
version = "0.3.0"
optional = true
[dependencies.rc_crypto]
path = "../support/rc_crypto"

View File

@@ -4,12 +4,10 @@
use crate::config::RemoteSettingsConfig;
use crate::error::{Error, Result};
#[cfg(feature = "jexl")]
use crate::jexl_filter::JexlFilter;
#[cfg(feature = "signatures")]
use crate::signatures;
use crate::storage::Storage;
#[cfg(feature = "jexl")]
use crate::RemoteSettingsContext;
use crate::{
packaged_attachments, packaged_collections, RemoteSettingsServer, UniffiCustomTypeConverter,
@@ -80,7 +78,6 @@ pub struct RemoteSettingsClient<C = ViaductApiClient> {
struct RemoteSettingsClientInner<C> {
storage: Storage,
api_client: C,
#[cfg(feature = "jexl")]
jexl_filter: JexlFilter,
}
@@ -118,7 +115,7 @@ impl<C: ApiClient> RemoteSettingsClient<C> {
pub fn new_from_parts(
collection_name: String,
storage: Storage,
#[cfg(feature = "jexl")] jexl_filter: JexlFilter,
jexl_filter: JexlFilter,
api_client: C,
) -> Self {
Self {
@@ -126,7 +123,6 @@ impl<C: ApiClient> RemoteSettingsClient<C> {
inner: Mutex::new(RemoteSettingsClientInner {
storage,
api_client,
#[cfg(feature = "jexl")]
jexl_filter,
}),
}
@@ -148,7 +144,6 @@ impl<C: ApiClient> RemoteSettingsClient<C> {
}
/// Filters records based on the presence and evaluation of `filter_expression`.
#[cfg(feature = "jexl")]
fn filter_records(
&self,
records: Vec<RemoteSettingsRecord>,
@@ -165,15 +160,6 @@ impl<C: ApiClient> RemoteSettingsClient<C> {
.collect()
}
#[cfg(not(feature = "jexl"))]
fn filter_records(
&self,
records: Vec<RemoteSettingsRecord>,
_inner: &RemoteSettingsClientInner<C>,
) -> Vec<RemoteSettingsRecord> {
records
}
/// Get the current set of records.
///
/// If records are not present in storage this will normally return None. Use `sync_if_empty =
@@ -435,17 +421,15 @@ impl RemoteSettingsClient<ViaductApiClient> {
server_url: Url,
bucket_name: String,
collection_name: String,
#[cfg(feature = "jexl")] context: Option<RemoteSettingsContext>,
context: Option<RemoteSettingsContext>,
storage: Storage,
) -> Result<Self> {
let api_client = ViaductApiClient::new(server_url, &bucket_name, &collection_name)?;
#[cfg(feature = "jexl")]
let jexl_filter = JexlFilter::new(context);
Ok(Self::new_from_parts(
collection_name,
storage,
#[cfg(feature = "jexl")]
jexl_filter,
api_client,
))
@@ -1857,9 +1841,6 @@ mod test {
mod test_new_client {
use super::*;
#[cfg(not(feature = "jexl"))]
use serde_json::json;
#[test]
fn test_endpoints() {
let endpoints = RemoteSettingsEndpoints::new(
@@ -1882,73 +1863,8 @@ mod test_new_client {
"http://rs.example.com/v1/buckets/main/collections/test-collection/changeset",
);
}
#[test]
#[cfg(not(feature = "jexl"))]
fn test_get_records_none_cached() {
let mut api_client = MockApiClient::new();
api_client.expect_collection_url().returning(|| {
"http://rs.example.com/v1/buckets/main/collections/test-collection".into()
});
api_client.expect_is_prod_server().returning(|| Ok(false));
// Note, don't make any api_client.expect_*() calls, the RemoteSettingsClient should not
// attempt to make any requests for this scenario
let storage = Storage::new(":memory:".into()).expect("Error creating storage");
let rs_client =
RemoteSettingsClient::new_from_parts("test-collection".into(), storage, api_client);
assert_eq!(
rs_client.get_records(false).expect("Error getting records"),
None
);
}
#[test]
#[cfg(not(feature = "jexl"))]
fn test_get_records_none_cached_sync_with_empty() {
let mut api_client = MockApiClient::new();
let records = vec![RemoteSettingsRecord {
id: "record-0001".into(),
last_modified: 100,
deleted: false,
attachment: None,
fields: json!({"foo": "bar"}).as_object().unwrap().clone(),
}];
let changeset = ChangesetResponse {
changes: records.clone(),
timestamp: 42,
metadata: CollectionMetadata {
bucket: "main".into(),
signature: CollectionSignature {
signature: "b64sig".into(),
x5u: "http://x5u.com".into(),
},
},
};
api_client.expect_collection_url().returning(|| {
"http://rs.example.com/v1/buckets/main/collections/test-collection".into()
});
api_client.expect_fetch_changeset().returning({
move |timestamp| {
assert_eq!(timestamp, None);
Ok(changeset.clone())
}
});
api_client.expect_is_prod_server().returning(|| Ok(false));
let storage = Storage::new(":memory:".into()).expect("Error creating storage");
let rs_client =
RemoteSettingsClient::new_from_parts("test-collection".into(), storage, api_client);
assert_eq!(
rs_client.get_records(true).expect("Error getting records"),
Some(records)
);
}
}
#[cfg(feature = "jexl")]
#[cfg(test)]
mod jexl_tests {
use super::*;
@@ -2070,431 +1986,7 @@ mod jexl_tests {
}
}
#[cfg(not(feature = "jexl"))]
#[cfg(test)]
mod cached_data_tests {
use super::*;
#[test]
fn test_no_cached_data_use_packaged_data() -> Result<()> {
let collection_name = "search-telemetry-v2";
let file_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("dumps")
.join("main")
.join(format!("{}.json", collection_name));
assert!(
file_path.exists(),
"Packaged data should exist for this test"
);
let mut api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
let records = rs_client.get_records(false)?;
assert!(records.is_some(), "Records should exist from packaged data");
Ok(())
}
#[test]
fn test_packaged_data_newer_than_cached() -> Result<()> {
let api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = "https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-telemetry-v2";
// First get the packaged data to know its timestamp
let rs_client =
RemoteSettingsClient::new_from_parts("search-telemetry-v2".into(), storage, api_client);
let packaged_data = rs_client
.load_packaged_data()
.expect("Packaged data should exist");
// Setup older cached data
let old_record = RemoteSettingsRecord {
id: "old".to_string(),
last_modified: packaged_data.timestamp - 1000, // Ensure it's older
deleted: false,
attachment: None,
fields: serde_json::Map::new(),
};
let mut api_client = MockApiClient::new();
let mut storage = Storage::new(":memory:".into())?;
storage.insert_collection_content(
collection_url,
&vec![old_record.clone()],
42,
CollectionMetadata::default(),
)?;
api_client
.expect_collection_url()
.returning(|| collection_url.to_string());
api_client.expect_is_prod_server().returning(|| Ok(true));
let rs_client =
RemoteSettingsClient::new_from_parts("search-telemetry-v2".into(), storage, api_client);
let records = rs_client.get_records(false)?;
assert!(records.is_some());
let records = records.unwrap();
assert!(!records.is_empty());
// Verify the new records replaced old ones
let mut inner = rs_client.inner.lock();
let cached = inner.storage.get_records(collection_url)?.unwrap();
assert!(cached[0].last_modified > old_record.last_modified);
assert_eq!(cached.len(), packaged_data.data.len());
Ok(())
}
#[test]
fn test_no_cached_data_no_packaged_data_sync_if_empty_true() -> Result<()> {
let collection_name = "nonexistent-collection"; // A collection without packaged data
// Verify the packaged data file does not exist
let file_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("dumps")
.join("main")
.join(format!("{}.json", collection_name));
assert!(
!file_path.exists(),
"Packaged data should not exist for this test"
);
let mut api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
// Mock get_records to return some data
let expected_records = vec![RemoteSettingsRecord {
id: "remote".to_string(),
last_modified: 1000,
deleted: false,
attachment: None,
fields: serde_json::Map::new(),
}];
let changeset = ChangesetResponse {
changes: expected_records.clone(),
timestamp: 42,
metadata: CollectionMetadata {
bucket: "main".into(),
signature: CollectionSignature {
signature: "b64sig".into(),
x5u: "http://x5u.com".into(),
},
},
};
api_client
.expect_fetch_changeset()
.withf(|timestamp| timestamp.is_none())
.returning(move |_| Ok(changeset.clone()));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
// Call get_records with sync_if_empty = true
let records = rs_client.get_records(true)?;
assert!(
records.is_some(),
"Records should be fetched from the remote server"
);
let records = records.unwrap();
assert_eq!(records.len(), 1);
assert_eq!(records[0].id, "remote");
Ok(())
}
#[test]
fn test_no_cached_data_no_packaged_data_sync_if_empty_false() -> Result<()> {
let collection_name = "nonexistent-collection"; // A collection without packaged data
// Verify the packaged data file does not exist
let file_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("dumps")
.join("main")
.join(format!("{}.json", collection_name));
assert!(
!file_path.exists(),
"Packaged data should not exist for this test"
);
let mut api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
// Since sync_if_empty is false, get_records should not be called
// No need to set expectation for api_client.fetch_changeset
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
// Call get_records with sync_if_empty = false
let records = rs_client.get_records(false)?;
assert!(
records.is_none(),
"Records should be None when no cache, no packaged data, and sync_if_empty is false"
);
Ok(())
}
#[test]
fn test_cached_data_exists_and_not_empty() -> Result<()> {
let collection_name = "test-collection";
let mut api_client = MockApiClient::new();
let mut storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
// Set up cached records
let cached_records = vec![RemoteSettingsRecord {
id: "cached1".to_string(),
last_modified: 500,
deleted: false,
attachment: None,
fields: serde_json::Map::new(),
}];
storage.insert_collection_content(
&collection_url,
&cached_records,
42,
CollectionMetadata::default(),
)?;
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
// Call get_records with any sync_if_empty value
let records = rs_client.get_records(true)?;
assert!(
records.is_some(),
"Records should be returned from the cached data"
);
let records = records.unwrap();
assert_eq!(records.len(), 1);
assert_eq!(records[0].id, "cached1");
Ok(())
}
#[test]
fn test_cached_data_empty_sync_if_empty_false() -> Result<()> {
let collection_name = "test-collection";
let mut api_client = MockApiClient::new();
let mut storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
// Set up empty cached records
let cached_records: Vec<RemoteSettingsRecord> = vec![];
storage.insert_collection_content(
&collection_url,
&cached_records,
42,
CollectionMetadata::default(),
)?;
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
// Call get_records with sync_if_empty = false
let records = rs_client.get_records(false)?;
assert!(records.is_some(), "Empty cached records should be returned");
let records = records.unwrap();
assert!(records.is_empty(), "Cached records should be empty");
Ok(())
}
}
#[cfg(not(feature = "jexl"))]
#[cfg(test)]
mod test_packaged_metadata {
use super::*;
use std::path::PathBuf;
#[test]
fn test_no_cached_data_use_packaged_attachment() -> Result<()> {
let collection_name = "regions";
let attachment_name = "world";
// Verify our packaged attachment exists with its manifest
let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("dumps")
.join("main")
.join("attachments")
.join(collection_name);
let file_path = base_path.join(attachment_name);
let manifest_path = base_path.join(format!("{}.meta.json", attachment_name));
assert!(
file_path.exists(),
"Packaged attachment should exist for this test"
);
assert!(
manifest_path.exists(),
"Manifest file should exist for this test"
);
let manifest_content = std::fs::read_to_string(manifest_path)?;
let manifest: serde_json::Value = serde_json::from_str(&manifest_content)?;
let mut api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
// Create record with metadata from manifest
let attachment_metadata = Attachment {
filename: attachment_name.to_string(),
mimetype: "application/octet-stream".to_string(),
location: attachment_name.to_string(),
size: manifest["size"].as_u64().unwrap(),
hash: manifest["hash"].as_str().unwrap().to_string(),
};
let record = RemoteSettingsRecord {
id: "test-record".to_string(),
last_modified: 12345,
deleted: false,
attachment: Some(attachment_metadata),
fields: serde_json::json!({}).as_object().unwrap().clone(),
};
let attachment_data = rs_client.get_attachment(&record)?;
// Verify we got the expected data
let expected_data = std::fs::read(file_path)?;
assert_eq!(attachment_data, expected_data);
Ok(())
}
#[test]
fn test_packaged_attachment_outdated_fetch_from_api() -> Result<()> {
let collection_name = "regions";
let attachment_name = "world";
let mut api_client = MockApiClient::new();
let storage = Storage::new(":memory:".into())?;
let collection_url = format!(
"https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/{}",
collection_name
);
// Prepare mock data
let mock_api_data = vec![1, 2, 3, 4, 5];
// Create metadata that doesn't match our packaged data
let attachment_metadata = Attachment {
filename: attachment_name.to_string(),
mimetype: "application/octet-stream".to_string(),
location: attachment_name.to_string(),
size: mock_api_data.len() as u64,
hash: {
use sha2::{Digest, Sha256};
format!("{:x}", Sha256::digest(&mock_api_data))
},
};
api_client
.expect_collection_url()
.returning(move || collection_url.clone());
api_client.expect_is_prod_server().returning(|| Ok(true));
api_client
.expect_fetch_attachment()
.returning(move |_| Ok(mock_api_data.clone()));
let rs_client =
RemoteSettingsClient::new_from_parts(collection_name.to_string(), storage, api_client);
let record = RemoteSettingsRecord {
id: "test-record".to_string(),
last_modified: 12345,
deleted: false,
attachment: Some(attachment_metadata),
fields: serde_json::json!({}).as_object().unwrap().clone(),
};
let attachment_data = rs_client.get_attachment(&record)?;
// Verify we got the mock API data, not the packaged data
assert_eq!(attachment_data, vec![1, 2, 3, 4, 5]);
Ok(())
}
}
#[cfg(feature = "signatures")]
#[cfg(feature = "jexl")] // Assuming tests are run with `--all-features`
#[cfg(test)]
mod test_signatures {
use core::assert_eq;

View File

@@ -1,3 +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/. */
use crate::RemoteSettingsContext;
use firefox_versioning::compare::version_compare;
use jexl_eval::Evaluator;

View File

@@ -19,7 +19,6 @@ pub mod service;
pub(crate) mod signatures;
pub mod storage;
#[cfg(feature = "jexl")]
pub(crate) mod jexl_filter;
mod macros;
@@ -216,7 +215,6 @@ impl RemoteSettingsClient {
base_url,
bucket_name,
collection_name,
#[cfg(feature = "jexl")]
context,
storage,
)?,

View File

@@ -1,3 +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/. */
#[macro_export]
macro_rules! packaged_collections {
($(($bucket:expr, $collection:expr)),* $(,)?) => {

View File

@@ -1,3 +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/. */
use core::clone::Clone;
use crate::{RemoteSettingsRecord, Result};

View File

@@ -1 +1 @@
{"files":{"Cargo.toml":"2794ef52bbf75b7abc5cebb1d301103be984a7dcd0f90be0bf3e675aae5c3cee","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","src/configuration_types.rs":"baea920438a87499791b33177c28b690356da24be13223f9113f40e43cb787d4","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d4da34f51a6d229ffe707acce0aa8a87384de37fd1ec20f121026b077cc9169c","src/filter.rs":"34ca0fdc311f002a6134f896aa040870780f91ad626a129429c2e840b9b1ed7a","src/lib.rs":"eb0102461edbcf2425e2f46c1677a52634d1c001480d1c6694dc3c8add39a350","src/selector.rs":"456c9bcea4643d19347c62a75e2a2770d6158c008ebc2b66f8a550df0d0b5d97","src/sort_helpers.rs":"12d41c34fc2ca5387edc248189335fb11702618b7253f8b486f0c84576084faa","src/types.rs":"c35e70ed9bed63636aa7f6cb4bdc5898c9f3a3f7382a8d6d13aa008ee597d6af"},"package":null}
{"files":{"Cargo.toml":"1d1e0b89d251c7cde75d9a31ae87e21a31c6b8e0a6ea525442dd9af989d42b1e","README.md":"d59a6ad6232a86a7bd3632ca62c44ba8bd466615c5d47ce0d836b270bac5562c","android/build.gradle":"e3b617d653aa0221f2229bb16c2fd635003fe82d0274c4b9a6f2d8154851985a","android/proguard-rules.pro":"1cf8c57e8f79c250b0af9c1a5a4edad71a5c348a79ab70243b6bae086c150ad2","android/src/main/AndroidManifest.xml":"108cabbbdc93da70e1da3e60b74171580872017d996c20e37946c27aaa078031","src/configuration_overrides_types.rs":"220a5e12ee3deb309a1571c5820ec5132c959f56667c4c48f997bbe2be0c7eeb","src/configuration_types.rs":"baea920438a87499791b33177c28b690356da24be13223f9113f40e43cb787d4","src/environment_matching.rs":"5a1ade9a900942c62e8740597528a34df6fb3fdb72c801a647a3386acd42fcc8","src/error.rs":"d3c1eda7a8da15446a321139d4d29dd9ceee99e916519690d5eb2d45ed628598","src/filter.rs":"2872eb2c965bdffdebf89936b3e7c80702c8d43e946da81ee093639ba8021f3b","src/lib.rs":"9c83780a74048fbbc7bbba5706067b9dc5db2ae25a0cc751687d2738903723b4","src/selector.rs":"5c4290f2f7220e6f62a8dec3a51f7f69df210c09f4224799de5073e280c6a879","src/sort_helpers.rs":"12d41c34fc2ca5387edc248189335fb11702618b7253f8b486f0c84576084faa","src/types.rs":"2dc1339a5a49bc32dc9252d2fe1c179eb7b3d55f091d6ed2537262573e6d80db","uniffi.toml":"646df75630776abb4bad6d3b39ee5c687052c21afbfffe851110770da350d5ea"},"package":null}

View File

@@ -14,6 +14,7 @@ edition = "2021"
name = "search"
version = "0.1.0"
build = false
exclude = ["/ios"]
autolib = false
autobins = false
autoexamples = false

View File

@@ -0,0 +1,14 @@
apply from: "$appServicesRootDir/build-scripts/component-common.gradle"
apply from: "$appServicesRootDir/publish.gradle"
android {
namespace 'org.mozilla.appservices.search'
}
dependencies {
api project(":remotesettings")
}
ext.configureUniFFIBindgen("search")
ext.dependsOnTheMegazord()
ext.configurePublish()

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"/>

View File

@@ -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/. */
//! This module defines the structures that we use for serde_json to parse
//! the search configuration overrides.
use crate::JSONEngineUrls;
use serde::Deserialize;
/// Represents search configuration overrides record.
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct JSONOverridesRecord {
/// This is the identifier of the search engine in search-config-v2 that this
/// record will override. It may be extended by telemetry_suffix.
pub identifier: String,
/// The partner code for the engine or variant. This will be inserted into
/// parameters which include '{partnerCode}
pub partner_code: String,
/// Suffix that is appended to the search engine identifier following a
/// dash, i.e. `<identifier>-<suffix>`. There should always be a suffix
/// supplied if the partner code is different.
pub telemetry_suffix: Option<String>,
/// The url used for reporting clicks.
pub click_url: String,
/// The URLs associated with the search engine.
//pub urls: JSONOverrideEngineUrls,
pub urls: JSONEngineUrls,
}
/// Represents the search configuration overrides as received from remote settings.
#[derive(Debug, Deserialize)]
pub(crate) struct JSONSearchConfigurationOverrides {
pub data: Vec<JSONOverridesRecord>,
}

View File

@@ -17,8 +17,12 @@ use remote_settings::RemoteSettingsError;
pub enum Error {
#[error("Search configuration not specified")]
SearchConfigNotSpecified,
#[error("No records received from remote settings")]
#[error("Search configuration overrides not specified")]
SearchConfigOverridesNotSpecified,
#[error("No search config v2 records received from remote settings")]
SearchConfigNoRecords,
#[error("No search config overrides v2 records received from remote settings")]
SearchConfigOverridesNoRecords,
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Remote Settings error: {0}")]

View File

@@ -4,6 +4,7 @@
//! This module defines the functions for managing the filtering of the configuration.
use crate::configuration_overrides_types::JSONOverridesRecord;
use crate::environment_matching::matches_user_environment;
use crate::{
error::Error, JSONDefaultEnginesRecord, JSONEngineBase, JSONEngineRecord, JSONEngineUrl,
@@ -94,6 +95,16 @@ impl SearchEngineDefinition {
}
}
fn merge_override(&mut self, override_record: &JSONOverridesRecord) {
self.partner_code = override_record.partner_code.clone();
self.urls.merge(&override_record.urls);
self.click_url = Some(override_record.click_url.clone());
if let Some(telemetry_suffix) = &override_record.telemetry_suffix {
self.telemetry_suffix = telemetry_suffix.clone();
}
}
pub(crate) fn from_configuration_details(
identifier: &str,
base: JSONEngineBase,
@@ -111,6 +122,7 @@ impl SearchEngineDefinition {
partner_code: base.partner_code.unwrap_or_default(),
telemetry_suffix: String::new(),
urls: base.urls.into(),
click_url: None,
};
engine_definition.merge_variant(variant);
@@ -132,13 +144,25 @@ pub(crate) trait Filter {
fn filter_records(
&self,
user_environment: &SearchUserEnvironment,
overrides: Option<Vec<JSONOverridesRecord>>,
) -> Result<FilterRecordsResult, Error>;
}
fn apply_overrides(engines: &mut [SearchEngineDefinition], overrides: &[JSONOverridesRecord]) {
for override_record in overrides {
for engine in engines.iter_mut() {
if engine.identifier == override_record.identifier {
engine.merge_override(override_record);
}
}
}
}
impl Filter for Vec<RemoteSettingsRecord> {
fn filter_records(
&self,
user_environment: &SearchUserEnvironment,
overrides: Option<Vec<JSONOverridesRecord>>,
) -> Result<FilterRecordsResult, Error> {
let mut engines = Vec::new();
let mut default_engines_record = None;
@@ -146,7 +170,7 @@ impl Filter for Vec<RemoteSettingsRecord> {
for record in self {
// TODO: Bug 1947241 - Find a way to avoid having to serialise the records
// back to strings and then deserilise them into the records that we want.
// back to strings and then deserialise them into the records that we want.
let stringified = serde_json::to_string(&record.fields)?;
match record.fields.get("recordType") {
Some(val) if *val == "engine" => {
@@ -171,6 +195,10 @@ impl Filter for Vec<RemoteSettingsRecord> {
}
}
if let Some(overrides_data) = &overrides {
apply_overrides(&mut engines, overrides_data);
}
Ok(FilterRecordsResult {
engines,
default_engines_record,
@@ -183,6 +211,7 @@ impl Filter for Vec<JSONSearchConfigurationRecords> {
fn filter_records(
&self,
user_environment: &SearchUserEnvironment,
overrides: Option<Vec<JSONOverridesRecord>>,
) -> Result<FilterRecordsResult, Error> {
let mut engines = Vec::new();
let mut default_engines_record = None;
@@ -206,6 +235,10 @@ impl Filter for Vec<JSONSearchConfigurationRecords> {
}
}
if let Some(overrides_data) = &overrides {
apply_overrides(&mut engines, overrides_data);
}
Ok(FilterRecordsResult {
engines,
default_engines_record: default_engines_record.cloned(),
@@ -213,17 +246,17 @@ impl Filter for Vec<JSONSearchConfigurationRecords> {
})
}
}
pub(crate) fn filter_engine_configuration_impl(
user_environment: SearchUserEnvironment,
configuration: &impl Filter,
overrides: Option<Vec<JSONOverridesRecord>>,
) -> Result<RefinedSearchConfig, Error> {
let mut user_environment = user_environment.clone();
user_environment.locale = user_environment.locale.to_lowercase();
user_environment.region = user_environment.region.to_lowercase();
user_environment.version = user_environment.version.to_lowercase();
let filtered_result = configuration.filter_records(&user_environment);
let filtered_result = configuration.filter_records(&user_environment, overrides);
filtered_result.map(|result| {
let (default_engine_id, default_private_engine_id) = determine_default_engines(
@@ -381,6 +414,52 @@ mod tests {
use once_cell::sync::Lazy;
use pretty_assertions::assert_eq;
#[test]
fn test_merge_override() {
let mut test_engine = SearchEngineDefinition {
identifier: "test".to_string(),
partner_code: "partner-code".to_string(),
telemetry_suffix: "original-telemetry-suffix".to_string(),
..Default::default()
};
let override_record = JSONOverridesRecord {
identifier: "test".to_string(),
partner_code: "override-partner-code".to_string(),
click_url: "https://example.com/click-url".to_string(),
telemetry_suffix: None,
urls: JSONEngineUrls {
search: Some(JSONEngineUrl {
base: Some("https://example.com/override-search".to_string()),
method: None,
params: None,
search_term_param_name: None,
}),
..Default::default()
},
};
test_engine.merge_override(&override_record);
assert_eq!(
test_engine.partner_code, "override-partner-code",
"Should override the partner code"
);
assert_eq!(
test_engine.click_url,
Some("https://example.com/click-url".to_string()),
"Should override the click url"
);
assert_eq!(
test_engine.urls.search.base, "https://example.com/override-search",
"Should override search url"
);
assert_eq!(
test_engine.telemetry_suffix, "original-telemetry-suffix",
"Should not override telemetry suffix when telemetry suffix is supplied as None"
);
}
#[test]
fn test_from_configuration_details_fallsback_to_defaults() {
// This test doesn't use `..Default::default()` as we want to
@@ -442,7 +521,8 @@ mod tests {
suggestions: None,
trending: None,
search_form: None
}
},
click_url: None
}
)
}
@@ -593,7 +673,8 @@ mod tests {
}],
search_term_param_name: None,
}),
}
},
click_url: None
}
)
}
@@ -719,7 +800,8 @@ mod tests {
}],
search_term_param_name: None,
}),
}
},
click_url: None
}
)
}
@@ -904,7 +986,8 @@ mod tests {
}],
search_term_param_name: None,
}),
}
},
click_url: None
}
)
}

View File

@@ -2,6 +2,7 @@
* 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 configuration_overrides_types;
mod configuration_types;
mod environment_matching;
mod error;
@@ -17,4 +18,4 @@ pub use crate::types::*;
pub use selector::SearchEngineSelector;
pub type SearchApiResult<T> = std::result::Result<T, error::SearchApiError>;
uniffi::setup_scaffolding!();
uniffi::setup_scaffolding!("search");

View File

@@ -4,6 +4,8 @@
//! This module defines the main `SearchEngineSelector`.
use crate::configuration_overrides_types::JSONOverridesRecord;
use crate::configuration_overrides_types::JSONSearchConfigurationOverrides;
use crate::filter::filter_engine_configuration_impl;
use crate::{
error::Error, JSONSearchConfiguration, RefinedSearchConfig, SearchApiResult,
@@ -17,7 +19,9 @@ use std::sync::Arc;
#[derive(Default)]
pub(crate) struct SearchEngineSelectorInner {
configuration: Option<JSONSearchConfiguration>,
configuration_overrides: Option<JSONSearchConfigurationOverrides>,
search_config_client: Option<Arc<RemoteSettingsClient>>,
search_config_overrides_client: Option<Arc<RemoteSettingsClient>>,
}
/// SearchEngineSelector parses the JSON configuration for
@@ -47,10 +51,15 @@ impl SearchEngineSelector {
pub fn use_remote_settings_server(
self: Arc<Self>,
service: &Arc<RemoteSettingsService>,
#[allow(unused_variables)] apply_engine_overrides: bool,
apply_engine_overrides: bool,
) -> SearchApiResult<()> {
self.0.lock().search_config_client =
Some(service.make_client("search-config-v2".to_string())?);
let mut inner = self.0.lock();
inner.search_config_client = Some(service.make_client("search-config-v2".to_string())?);
if apply_engine_overrides {
inner.search_config_overrides_client =
Some(service.make_client("search-config-overrides-v2".to_string())?);
}
Ok(())
}
@@ -68,6 +77,15 @@ impl SearchEngineSelector {
Ok(())
}
#[handle_error(Error)]
pub fn set_config_overrides(self: Arc<Self>, overrides: String) -> SearchApiResult<()> {
if overrides.is_empty() {
return Err(Error::SearchConfigOverridesNotSpecified);
}
self.0.lock().configuration_overrides = serde_json::from_str(&overrides)?;
Ok(())
}
/// Clears the search configuration from memory if it is known that it is
/// not required for a time, e.g. if the configuration will only be re-filtered
/// after an app/environment update.
@@ -81,27 +99,62 @@ impl SearchEngineSelector {
self: Arc<Self>,
user_environment: SearchUserEnvironment,
) -> SearchApiResult<RefinedSearchConfig> {
if let Some(client) = &self.0.lock().search_config_client {
let inner = self.0.lock();
if let Some(client) = &inner.search_config_client {
// Remote settings ships dumps of the collections, so it is highly
// unlikely that we'll ever hit the case where we have no records.
// However, just in case of an issue that does causes us to receive
// no records, we will raise an error so that the application can
// handle or record it appropriately.
let records = client.get_records(false);
if let Some(records) = records {
if records.is_empty() {
return Err(Error::SearchConfigNoRecords);
}
return filter_engine_configuration_impl(user_environment, &records);
if let Some(overrides_client) = &inner.search_config_overrides_client {
let overrides_records = overrides_client.get_records(false);
if let Some(overrides_records) = overrides_records {
if overrides_records.is_empty() {
return filter_engine_configuration_impl(
user_environment,
&records,
None,
);
}
// TODO: Bug 1947241 - Find a way to avoid having to serialise the records
// back to strings and then deserialise them into the records that we want.
let stringified = serde_json::to_string(&overrides_records)?;
let json_overrides: Vec<JSONOverridesRecord> =
serde_json::from_str(&stringified)?;
return filter_engine_configuration_impl(
user_environment,
&records,
Some(json_overrides),
);
} else {
return Err(Error::SearchConfigOverridesNoRecords);
}
}
return filter_engine_configuration_impl(user_environment, &records, None);
} else {
return Err(Error::SearchConfigNoRecords);
}
}
let data = match &self.0.lock().configuration {
let config = match &inner.configuration {
None => return Err(Error::SearchConfigNotSpecified),
Some(configuration) => configuration.data.clone(),
};
return filter_engine_configuration_impl(user_environment, &data);
let config_overrides = match &inner.configuration_overrides {
None => return Err(Error::SearchConfigOverridesNotSpecified),
Some(overrides) => overrides.data.clone(),
};
return filter_engine_configuration_impl(user_environment, &config, Some(config_overrides));
}
}
@@ -266,10 +319,75 @@ mod tests {
.contains("Search configuration not specified"))
}
#[test]
fn test_filter_engine_configuration_throws_without_config_overrides() {
let selector = Arc::new(SearchEngineSelector::new());
let _ = Arc::clone(&selector).set_search_config(
json!({
"data": [
{
"recordType": "engine",
"identifier": "test",
"base": {
"name": "Test",
"classification": "general",
"urls": {
"search": {
"base": "https://example.com",
"method": "GET",
}
}
},
"variants": [{
"environment": {
"allRegionsAndLocales": true
}
}],
},
]
})
.to_string(),
);
let result = selector.filter_engine_configuration(SearchUserEnvironment {
..Default::default()
});
assert!(
result.is_err(),
"Should throw an error when a configuration overrides has not been specified before filtering"
);
assert!(result
.unwrap_err()
.to_string()
.contains("Search configuration overrides not specified"))
}
#[test]
fn test_filter_engine_configuration_returns_basic_engines() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -356,6 +474,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let result = selector.filter_engine_configuration(SearchUserEnvironment {
..Default::default()
@@ -445,7 +568,8 @@ mod tests {
suggestions: None,
trending: None,
search_form: None
}
},
click_url: None,
}
),
app_default_engine_id: Some("test1".to_string()),
@@ -458,6 +582,26 @@ mod tests {
fn test_filter_engine_configuration_handles_basic_variants() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -558,6 +702,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let result = selector.filter_engine_configuration(SearchUserEnvironment {
region: "FR".into(),
@@ -657,6 +806,26 @@ mod tests {
fn test_filter_engine_configuration_handles_basic_subvariants() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -755,6 +924,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let mut result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
region: "FR".into(),
@@ -908,6 +1082,26 @@ mod tests {
fn test_filter_engine_configuration_handles_environments() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -984,6 +1178,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let mut result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: String::new(),
@@ -1134,6 +1333,26 @@ mod tests {
fn test_set_config_should_handle_default_engines() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -1218,6 +1437,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let test_engine = SearchEngineDefinition {
charset: "UTF-8".to_string(),
@@ -1320,6 +1544,26 @@ mod tests {
fn test_filter_engine_orders() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "overrides-engine",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": []
}
}
}
]
})
.to_string(),
);
let engine_order_config = Arc::clone(&selector).set_search_config(
json!({
"data": [
@@ -1444,6 +1688,11 @@ mod tests {
"Should have set the configuration successfully. {:?}",
engine_order_config
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
fn assert_actual_engines_equals_expected(
result: Result<RefinedSearchConfig, SearchApiError>,
@@ -1621,7 +1870,15 @@ mod tests {
);
}
fn setup_remote_settings_test() -> Arc<SearchEngineSelector> {
const APPLY_OVERRIDES: bool = true;
const DO_NOT_APPLY_OVERRIDES: bool = false;
const RECORDS_MISSING: bool = false;
const RECORDS_PRESENT: bool = true;
fn setup_remote_settings_test(
should_apply_overrides: bool,
expect_sync_successful: bool,
) -> Arc<SearchEngineSelector> {
let _ = env_logger::builder().try_init();
viaduct_reqwest::use_reqwest_backend();
@@ -1637,7 +1894,8 @@ mod tests {
let selector = Arc::new(SearchEngineSelector::new());
let settings_result = Arc::clone(&selector).use_remote_settings_server(&service, false);
let settings_result =
Arc::clone(&selector).use_remote_settings_server(&service, should_apply_overrides);
assert!(
settings_result.is_ok(),
"Should have set the client successfully. {:?}",
@@ -1646,7 +1904,11 @@ mod tests {
let sync_result = Arc::clone(&service).sync();
assert!(
sync_result.is_ok(),
if expect_sync_successful {
sync_result.is_ok()
} else {
sync_result.is_err()
},
"Should have completed the sync successfully. {:?}",
sync_result
);
@@ -1654,50 +1916,6 @@ mod tests {
selector
}
#[test]
fn test_remote_settings_no_records_throws_error() {
let m = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(
json!({
"metadata": {
"id": "search-config-v2",
"last_modified": 1000,
"bucket": "main",
"signature": {
"x5u": "fake",
"signature": "fake",
},
},
"timestamp": 1000,
"changes": [
]})
.to_string(),
)
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test();
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: "test-distro".to_string(),
..Default::default()
});
assert!(
result.is_err(),
"Should throw an error when a configuration has not been specified before filtering"
);
assert!(result
.unwrap_err()
.to_string()
.contains("No records received from remote settings"));
m.expect(1).assert();
}
fn response_body() -> String {
json!({
"metadata": {
@@ -1800,6 +2018,275 @@ mod tests {
.to_string()
}
fn response_body_overrides() -> String {
json!({
"metadata": {
"id": "search-config-overrides-v2",
"last_modified": 1000,
"bucket": "main",
"signature": {
"x5u": "fake",
"signature": "fake",
},
},
"timestamp": 1000,
"changes": [
{
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": [{
"name": "overrides-name",
"value": "overrides-value",
}],
}
},
"identifier": "test",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"partnerCode": "overrides-partner-code",
"id": "c5dcd1da-7126-4abb-846b-ec85b0d4d0d7",
"schema": 1001,
"last_modified": 1000
},
]
})
.to_string()
}
#[test]
fn test_remote_settings_empty_search_config_records_throws_error() {
let m = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(
json!({
"metadata": {
"id": "search-config-v2",
"last_modified": 1000,
"bucket": "main",
"signature": {
"x5u": "fake",
"signature": "fake",
},
},
"timestamp": 1000,
"changes": [
]})
.to_string(),
)
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test(DO_NOT_APPLY_OVERRIDES, RECORDS_PRESENT);
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: "test-distro".to_string(),
..Default::default()
});
assert!(
result.is_err(),
"Should throw an error when a configuration has not been specified before filtering"
);
assert!(result
.unwrap_err()
.to_string()
.contains("No search config v2 records received from remote settings"));
m.expect(1).assert();
}
#[test]
fn test_remote_settings_search_config_records_is_none_throws_error() {
let m1 = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(response_body())
.with_status(501)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test(DO_NOT_APPLY_OVERRIDES, RECORDS_MISSING);
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: "test-distro".to_string(),
..Default::default()
});
assert!(
result.is_err(),
"Should throw an error when a configuration has not been specified before filtering"
);
assert!(result
.unwrap_err()
.to_string()
.contains("No search config v2 records received from remote settings"));
m1.expect(1).assert();
}
#[test]
fn test_remote_settings_empty_search_config_overrides_filtered_without_error() {
let m1 = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(response_body())
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let m2 = mock(
"GET",
"/v1/buckets/main/collections/search-config-overrides-v2/changeset?_expected=0",
)
.with_body(
json!({
"metadata": {
"id": "search-config-overrides-v2",
"last_modified": 1000,
"bucket": "main",
"signature": {
"x5u": "fake",
"signature": "fake",
},
},
"timestamp": 1000,
"changes": [
]})
.to_string(),
)
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test(APPLY_OVERRIDES, RECORDS_PRESENT);
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: "test-distro".to_string(),
..Default::default()
});
assert!(
result.is_ok(),
"Should have filtered the configuration using an empty search config overrides without causing an error. {:?}",
result
);
m1.expect(1).assert();
m2.expect(1).assert();
}
#[test]
fn test_remote_settings_search_config_overrides_records_is_none_throws_error() {
let m1 = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(response_body())
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let m2 = mock(
"GET",
"/v1/buckets/main/collections/search-config-overrides-v2/changeset?_expected=0",
)
.with_body(response_body_overrides())
.with_status(501)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test(APPLY_OVERRIDES, RECORDS_MISSING);
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
distribution_id: "test-distro".to_string(),
..Default::default()
});
assert!(
result.is_err(),
"Should throw an error when a configuration overrides has not been specified before filtering"
);
assert!(result
.unwrap_err()
.to_string()
.contains("No search config overrides v2 records received from remote settings"));
m1.expect(1).assert();
m2.expect(1).assert();
}
#[test]
fn test_filter_with_remote_settings_overrides() {
let m1 = mock(
"GET",
"/v1/buckets/main/collections/search-config-v2/changeset?_expected=0",
)
.with_body(response_body())
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let m2 = mock(
"GET",
"/v1/buckets/main/collections/search-config-overrides-v2/changeset?_expected=0",
)
.with_body(response_body_overrides())
.with_status(200)
.with_header("content-type", "application/json")
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test(APPLY_OVERRIDES, RECORDS_PRESENT);
let test_engine = SearchEngineDefinition {
charset: "UTF-8".to_string(),
classification: SearchEngineClassification::General,
identifier: "test".to_string(),
name: "Test".to_string(),
partner_code: "overrides-partner-code".to_string(),
telemetry_suffix: "overrides-telemetry-suffix".to_string(),
click_url: Some("https://example.com/click-url".to_string()),
urls: SearchEngineUrls {
search: SearchEngineUrl {
base: "https://example.com/search-overrides".to_string(),
method: "GET".to_string(),
params: vec![SearchUrlParam {
name: "overrides-name".to_string(),
value: Some("overrides-value".to_string()),
enterprise_value: None,
experiment_config: None,
}],
search_term_param_name: None,
},
..Default::default()
},
..Default::default()
};
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
..Default::default()
});
assert!(
result.is_ok(),
"Should have filtered the configuration without error. {:?}",
result
);
assert_eq!(
result.unwrap().engines[0],
test_engine.clone(),
"Should have applied the overrides to the matching engine"
);
m1.expect(1).assert();
m2.expect(1).assert();
}
#[test]
fn test_filter_with_remote_settings() {
let m = mock(
@@ -1812,7 +2299,7 @@ mod tests {
.with_header("etag", "\"1000\"")
.create();
let selector = setup_remote_settings_test();
let selector = setup_remote_settings_test(DO_NOT_APPLY_OVERRIDES, RECORDS_PRESENT);
let test_engine = SearchEngineDefinition {
charset: "UTF-8".to_string(),
@@ -1911,4 +2398,162 @@ mod tests {
);
m.expect(1).assert();
}
#[test]
fn test_configuration_overrides_applied() {
let selector = Arc::new(SearchEngineSelector::new());
let config_overrides_result = Arc::clone(&selector).set_config_overrides(
json!({
"data": [
{
"identifier": "test",
"partnerCode": "overrides-partner-code",
"clickUrl": "https://example.com/click-url",
"telemetrySuffix": "overrides-telemetry-suffix",
"urls": {
"search": {
"base": "https://example.com/search-overrides",
"method": "GET",
"params": [{
"name": "overrides-name",
"value": "overrides-value",
}],
}
},
},
{ // Test partial override with some missing fields
"identifier": "distro-default",
"partnerCode": "distro-overrides-partner-code",
"clickUrl": "https://example.com/click-url-distro",
"urls": {
"search": {
"base": "https://example.com/search-distro",
},
},
}
]
})
.to_string(),
);
let config_result = Arc::clone(&selector).set_search_config(
json!({
"data": [
{
"recordType": "engine",
"identifier": "test",
"base": {
"name": "Test",
"classification": "general",
"urls": {
"search": {
"base": "https://example.com",
"method": "GET",
}
}
},
"variants": [{
"environment": {
"allRegionsAndLocales": true
}
}],
},
{
"recordType": "engine",
"identifier": "distro-default",
"base": {
"name": "Distribution Default",
"classification": "general",
"urls": {
"search": {
"base": "https://example.com",
"method": "GET"
}
}
},
"variants": [{
"environment": {
"allRegionsAndLocales": true
},
"telemetrySuffix": "distro-telemetry-suffix",
}],
},
]
})
.to_string(),
);
assert!(
config_result.is_ok(),
"Should have set the configuration successfully. {:?}",
config_result
);
assert!(
config_overrides_result.is_ok(),
"Should have set the configuration overrides successfully. {:?}",
config_overrides_result
);
let test_engine = SearchEngineDefinition {
charset: "UTF-8".to_string(),
classification: SearchEngineClassification::General,
identifier: "test".to_string(),
name: "Test".to_string(),
partner_code: "overrides-partner-code".to_string(),
telemetry_suffix: "overrides-telemetry-suffix".to_string(),
click_url: Some("https://example.com/click-url".to_string()),
urls: SearchEngineUrls {
search: SearchEngineUrl {
base: "https://example.com/search-overrides".to_string(),
method: "GET".to_string(),
params: vec![SearchUrlParam {
name: "overrides-name".to_string(),
value: Some("overrides-value".to_string()),
enterprise_value: None,
experiment_config: None,
}],
search_term_param_name: None,
},
..Default::default()
},
..Default::default()
};
let distro_default_engine = SearchEngineDefinition {
charset: "UTF-8".to_string(),
classification: SearchEngineClassification::General,
identifier: "distro-default".to_string(),
name: "Distribution Default".to_string(),
partner_code: "distro-overrides-partner-code".to_string(),
telemetry_suffix: "distro-telemetry-suffix".to_string(),
click_url: Some("https://example.com/click-url-distro".to_string()),
urls: SearchEngineUrls {
search: SearchEngineUrl {
base: "https://example.com/search-distro".to_string(),
method: "GET".to_string(),
params: Vec::new(),
search_term_param_name: None,
},
..Default::default()
},
..Default::default()
};
let result = Arc::clone(&selector).filter_engine_configuration(SearchUserEnvironment {
..Default::default()
});
assert!(
result.is_ok(),
"Should have filtered the configuration without error. {:?}",
result
);
assert_eq!(
result.unwrap(),
RefinedSearchConfig {
engines: vec![distro_default_engine.clone(), test_engine.clone(),],
app_default_engine_id: None,
app_private_default_engine_id: None
},
"Should have applied the overrides to the matching engine."
);
}
}

View File

@@ -209,6 +209,9 @@ pub struct SearchEngineDefinition {
/// If the number is not specified, other methods of sorting may be relied
/// upon (e.g. alphabetical).
pub order_hint: Option<u32>,
/// The url used for reporting clicks.
pub click_url: Option<String>,
}
/// Details of the search engines to display to the user, generated as a result

5
third_party/rust/search/uniffi.toml vendored Normal file
View File

@@ -0,0 +1,5 @@
[bindings.swift]
ffi_module_name = "MozillaRustComponents"
ffi_module_filename = "searchFFI"
[bindings.kotlin]
package_name = "mozilla.appservices.search"

View File

@@ -396,7 +396,7 @@ export class SearchEngineSelector {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
29, // search:uniffi_search_fn_constructor_searchengineselector_new
30, // search:uniffi_search_fn_constructor_searchengineselector_new
)
}
return handleRustResult(functionCall(), liftResult, liftError);}
@@ -445,6 +445,30 @@ export class SearchEngineSelector {
return handleRustResult(functionCall(), liftResult, liftError);
}
/**
* setConfigOverrides
*/
setConfigOverrides(overrides) {
const liftResult = (result) => undefined;
const liftError = (data) => FfiConverterTypeSearchApiError.lift(data);
const functionCall = () => {
try {
FfiConverterString.checkType(overrides)
} catch (e) {
if (e instanceof UniFFITypeError) {
e.addItemDescriptionPart("overrides");
}
throw e;
}
return UniFFIScaffolding.callSync(
27, // search:uniffi_search_fn_method_searchengineselector_set_config_overrides
FfiConverterTypeSearchEngineSelector.lower(this),
FfiConverterString.lower(overrides),
)
}
return handleRustResult(functionCall(), liftResult, liftError);
}
/**
* Sets the search configuration from the given string. If the configuration
* string is unchanged since the last update, the cached configuration is
@@ -465,7 +489,7 @@ export class SearchEngineSelector {
throw e;
}
return UniFFIScaffolding.callSync(
27, // search:uniffi_search_fn_method_searchengineselector_set_search_config
28, // search:uniffi_search_fn_method_searchengineselector_set_search_config
FfiConverterTypeSearchEngineSelector.lower(this),
FfiConverterString.lower(configuration),
)
@@ -506,7 +530,7 @@ export class SearchEngineSelector {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
28, // search:uniffi_search_fn_method_searchengineselector_use_remote_settings_server
29, // search:uniffi_search_fn_method_searchengineselector_use_remote_settings_server
FfiConverterTypeSearchEngineSelector.lower(this),
FfiConverterTypeRemoteSettingsService.lower(service),
FfiConverterBool.lower(applyEngineOverrides),
@@ -959,7 +983,7 @@ export class FfiConverterTypeRefinedSearchConfig extends FfiConverterArrayBuffer
* A definition for an individual search engine to be presented to the user.
*/
export class SearchEngineDefinition {
constructor({ aliases, charset, classification, identifier, name, optional, partnerCode, telemetrySuffix, urls, orderHint } = { aliases: undefined, charset: undefined, classification: undefined, identifier: undefined, name: undefined, optional: undefined, partnerCode: undefined, telemetrySuffix: undefined, urls: undefined, orderHint: undefined }) {
constructor({ aliases, charset, classification, identifier, name, optional, partnerCode, telemetrySuffix, urls, orderHint, clickUrl } = { aliases: undefined, charset: undefined, classification: undefined, identifier: undefined, name: undefined, optional: undefined, partnerCode: undefined, telemetrySuffix: undefined, urls: undefined, orderHint: undefined, clickUrl: undefined }) {
try {
FfiConverterSequencestring.checkType(aliases)
} catch (e) {
@@ -1040,6 +1064,14 @@ export class SearchEngineDefinition {
}
throw e;
}
try {
FfiConverterOptionalstring.checkType(clickUrl)
} catch (e) {
if (e instanceof UniFFITypeError) {
e.addItemDescriptionPart("clickUrl");
}
throw e;
}
/**
* A list of aliases for this engine.
* @type {Array.<string>}
@@ -1105,6 +1137,11 @@ export class SearchEngineDefinition {
* @type {?number}
*/
this.orderHint = orderHint;
/**
* The url used for reporting clicks.
* @type {?string}
*/
this.clickUrl = clickUrl;
}
equals(other) {
@@ -1118,7 +1155,8 @@ export class SearchEngineDefinition {
this.partnerCode == other.partnerCode &&
this.telemetrySuffix == other.telemetrySuffix &&
this.urls.equals(other.urls) &&
this.orderHint == other.orderHint
this.orderHint == other.orderHint &&
this.clickUrl == other.clickUrl
)
}
}
@@ -1137,6 +1175,7 @@ export class FfiConverterTypeSearchEngineDefinition extends FfiConverterArrayBuf
telemetrySuffix: FfiConverterString.read(dataStream),
urls: FfiConverterTypeSearchEngineUrls.read(dataStream),
orderHint: FfiConverterOptionalu32.read(dataStream),
clickUrl: FfiConverterOptionalstring.read(dataStream),
});
}
static write(dataStream, value) {
@@ -1150,6 +1189,7 @@ export class FfiConverterTypeSearchEngineDefinition extends FfiConverterArrayBuf
FfiConverterString.write(dataStream, value.telemetrySuffix);
FfiConverterTypeSearchEngineUrls.write(dataStream, value.urls);
FfiConverterOptionalu32.write(dataStream, value.orderHint);
FfiConverterOptionalstring.write(dataStream, value.clickUrl);
}
static computeSize(value) {
@@ -1164,6 +1204,7 @@ export class FfiConverterTypeSearchEngineDefinition extends FfiConverterArrayBuf
totalSize += FfiConverterString.computeSize(value.telemetrySuffix);
totalSize += FfiConverterTypeSearchEngineUrls.computeSize(value.urls);
totalSize += FfiConverterOptionalu32.computeSize(value.orderHint);
totalSize += FfiConverterOptionalstring.computeSize(value.clickUrl);
return totalSize
}
@@ -1252,6 +1293,14 @@ export class FfiConverterTypeSearchEngineDefinition extends FfiConverterArrayBuf
}
throw e;
}
try {
FfiConverterOptionalstring.checkType(value.clickUrl);
} catch (e) {
if (e instanceof UniFFITypeError) {
e.addItemDescriptionPart(".clickUrl");
}
throw e;
}
}
}

View File

@@ -551,7 +551,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callSync(
41, // suggest:uniffi_suggest_fn_constructor_suggeststore_new
42, // suggest:uniffi_suggest_fn_constructor_suggeststore_new
FfiConverterString.lower(path),
FfiConverterOptionalTypeRemoteSettingsConfig.lower(settingsConfig),
)
@@ -566,7 +566,7 @@ export class SuggestStore {
const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
31, // suggest:uniffi_suggest_fn_method_suggeststore_clear
32, // suggest:uniffi_suggest_fn_method_suggeststore_clear
FfiConverterTypeSuggestStore.lower(this),
)
}
@@ -585,7 +585,7 @@ export class SuggestStore {
const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
32, // suggest:uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions
33, // suggest:uniffi_suggest_fn_method_suggeststore_clear_dismissed_suggestions
FfiConverterTypeSuggestStore.lower(this),
)
}
@@ -616,7 +616,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
33, // suggest:uniffi_suggest_fn_method_suggeststore_dismiss_suggestion
34, // suggest:uniffi_suggest_fn_method_suggeststore_dismiss_suggestion
FfiConverterTypeSuggestStore.lower(this),
FfiConverterString.lower(suggestionUrl),
)
@@ -691,7 +691,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
34, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_geonames
35, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_geonames
FfiConverterTypeSuggestStore.lower(this),
FfiConverterString.lower(query),
FfiConverterBool.lower(matchNamePrefix),
@@ -715,7 +715,7 @@ export class SuggestStore {
const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
35, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_global_config
36, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_global_config
FfiConverterTypeSuggestStore.lower(this),
)
}
@@ -743,7 +743,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
36, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_provider_config
37, // suggest:uniffi_suggest_fn_method_suggeststore_fetch_provider_config
FfiConverterTypeSuggestStore.lower(this),
FfiConverterTypeSuggestionProvider.lower(provider),
)
@@ -772,7 +772,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
37, // suggest:uniffi_suggest_fn_method_suggeststore_ingest
38, // suggest:uniffi_suggest_fn_method_suggeststore_ingest
FfiConverterTypeSuggestStore.lower(this),
FfiConverterTypeSuggestIngestionConstraints.lower(constraints),
)
@@ -804,7 +804,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callSync(
38, // suggest:uniffi_suggest_fn_method_suggeststore_interrupt
39, // suggest:uniffi_suggest_fn_method_suggeststore_interrupt
FfiConverterTypeSuggestStore.lower(this),
FfiConverterOptionalTypeInterruptKind.lower(kind),
)
@@ -829,7 +829,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
39, // suggest:uniffi_suggest_fn_method_suggeststore_query
40, // suggest:uniffi_suggest_fn_method_suggeststore_query
FfiConverterTypeSuggestStore.lower(this),
FfiConverterTypeSuggestionQuery.lower(query),
)
@@ -858,7 +858,7 @@ export class SuggestStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
40, // suggest:uniffi_suggest_fn_method_suggeststore_query_with_metrics
41, // suggest:uniffi_suggest_fn_method_suggeststore_query_with_metrics
FfiConverterTypeSuggestStore.lower(this),
FfiConverterTypeSuggestionQuery.lower(query),
)
@@ -929,7 +929,7 @@ export class SuggestStoreBuilder {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
49, // suggest:uniffi_suggest_fn_constructor_suggeststorebuilder_new
50, // suggest:uniffi_suggest_fn_constructor_suggeststorebuilder_new
)
}
return handleRustResult(functionCall(), liftResult, liftError);}
@@ -943,7 +943,7 @@ export class SuggestStoreBuilder {
const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callSync(
42, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_build
43, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_build
FfiConverterTypeSuggestStoreBuilder.lower(this),
)
}
@@ -967,7 +967,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
43, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_cache_path
44, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_cache_path
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterString.lower(path),
)
@@ -996,7 +996,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callSync(
44, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_data_path
45, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_data_path
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterString.lower(path),
)
@@ -1033,7 +1033,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callSync(
45, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_load_extension
46, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_load_extension
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterString.lower(library),
FfiConverterOptionalstring.lower(entryPoint),
@@ -1059,7 +1059,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callSync(
46, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
47, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterString.lower(bucketName),
)
@@ -1084,7 +1084,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callSync(
47, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
48, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterTypeRemoteSettingsServer.lower(server),
)
@@ -1109,7 +1109,7 @@ export class SuggestStoreBuilder {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
48, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service
49, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_service
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterTypeRemoteSettingsService.lower(rsService),
)
@@ -4146,7 +4146,7 @@ export function rawSuggestionUrlMatches(rawUrl,cookedUrl) {
throw e;
}
return UniFFIScaffolding.callSync(
30, // suggest:uniffi_suggest_fn_func_raw_suggestion_url_matches
31, // suggest:uniffi_suggest_fn_func_raw_suggestion_url_matches
FfiConverterString.lower(rawUrl),
FfiConverterString.lower(cookedUrl),
)

View File

@@ -448,7 +448,7 @@ export class RemoteCommandStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
50, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command
51, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command
FfiConverterTypeRemoteCommandStore.lower(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -494,7 +494,7 @@ export class RemoteCommandStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
51, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at
52, // tabs:uniffi_tabs_fn_method_remotecommandstore_add_remote_command_at
FfiConverterTypeRemoteCommandStore.lower(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -517,7 +517,7 @@ export class RemoteCommandStore {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
52, // tabs:uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands
53, // tabs:uniffi_tabs_fn_method_remotecommandstore_get_unsent_commands
FfiConverterTypeRemoteCommandStore.lower(this),
)
}
@@ -554,7 +554,7 @@ export class RemoteCommandStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
53, // tabs:uniffi_tabs_fn_method_remotecommandstore_remove_remote_command
54, // tabs:uniffi_tabs_fn_method_remotecommandstore_remove_remote_command
FfiConverterTypeRemoteCommandStore.lower(this),
FfiConverterString.lower(deviceId),
FfiConverterTypeRemoteCommand.lower(command),
@@ -584,7 +584,7 @@ export class RemoteCommandStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
54, // tabs:uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent
55, // tabs:uniffi_tabs_fn_method_remotecommandstore_set_pending_command_sent
FfiConverterTypeRemoteCommandStore.lower(this),
FfiConverterTypePendingCommand.lower(command),
)
@@ -655,7 +655,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
55, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_apply
56, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_apply
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -683,7 +683,7 @@ export class TabsBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
56, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id
57, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_ensure_current_sync_id
FfiConverterTypeTabsBridgedEngine.lower(this),
FfiConverterString.lower(newSyncId),
)
@@ -704,7 +704,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
57, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_last_sync
58, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_last_sync
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -731,7 +731,7 @@ export class TabsBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
58, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync
59, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_prepare_for_sync
FfiConverterTypeTabsBridgedEngine.lower(this),
FfiConverterString.lower(clientData),
)
@@ -751,7 +751,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
59, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset
60, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -771,7 +771,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
60, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id
61, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_reset_sync_id
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -798,7 +798,7 @@ export class TabsBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
61, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync
62, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_last_sync
FfiConverterTypeTabsBridgedEngine.lower(this),
FfiConverterI64.lower(lastSync),
)
@@ -834,7 +834,7 @@ export class TabsBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
62, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded
63, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_set_uploaded
FfiConverterTypeTabsBridgedEngine.lower(this),
FfiConverterI64.lower(newTimestamp),
FfiConverterSequenceTypeTabsGuid.lower(uploadedIds),
@@ -863,7 +863,7 @@ export class TabsBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
63, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_store_incoming
64, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_store_incoming
FfiConverterTypeTabsBridgedEngine.lower(this),
FfiConverterSequencestring.lower(incomingEnvelopesAsJson),
)
@@ -883,7 +883,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
64, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_finished
65, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_finished
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -903,7 +903,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
65, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_id
66, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_id
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -922,7 +922,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
66, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_started
67, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_sync_started
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -941,7 +941,7 @@ export class TabsBridgedEngine {
const liftError = (data) => FfiConverterTypeTabsApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
67, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_wipe
68, // tabs:uniffi_tabs_fn_method_tabsbridgedengine_wipe
FfiConverterTypeTabsBridgedEngine.lower(this),
)
}
@@ -1016,7 +1016,7 @@ export class TabsStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
74, // tabs:uniffi_tabs_fn_constructor_tabsstore_new
75, // tabs:uniffi_tabs_fn_constructor_tabsstore_new
FfiConverterString.lower(path),
)
}
@@ -1035,7 +1035,7 @@ export class TabsStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
68, // tabs:uniffi_tabs_fn_method_tabsstore_bridged_engine
69, // tabs:uniffi_tabs_fn_method_tabsstore_bridged_engine
FfiConverterTypeTabsStore.lower(this),
)
}
@@ -1054,7 +1054,7 @@ export class TabsStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
69, // tabs:uniffi_tabs_fn_method_tabsstore_close_connection
70, // tabs:uniffi_tabs_fn_method_tabsstore_close_connection
FfiConverterTypeTabsStore.lower(this),
)
}
@@ -1074,7 +1074,7 @@ export class TabsStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
70, // tabs:uniffi_tabs_fn_method_tabsstore_get_all
71, // tabs:uniffi_tabs_fn_method_tabsstore_get_all
FfiConverterTypeTabsStore.lower(this),
)
}
@@ -1094,7 +1094,7 @@ export class TabsStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
71, // tabs:uniffi_tabs_fn_method_tabsstore_new_remote_command_store
72, // tabs:uniffi_tabs_fn_method_tabsstore_new_remote_command_store
FfiConverterTypeTabsStore.lower(this),
)
}
@@ -1113,7 +1113,7 @@ export class TabsStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
72, // tabs:uniffi_tabs_fn_method_tabsstore_register_with_sync_manager
73, // tabs:uniffi_tabs_fn_method_tabsstore_register_with_sync_manager
FfiConverterTypeTabsStore.lower(this),
)
}
@@ -1140,7 +1140,7 @@ export class TabsStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
73, // tabs:uniffi_tabs_fn_method_tabsstore_set_local_tabs
74, // tabs:uniffi_tabs_fn_method_tabsstore_set_local_tabs
FfiConverterTypeTabsStore.lower(this),
FfiConverterSequenceTypeRemoteTabRecord.lower(remoteTabs),
)

View File

@@ -417,7 +417,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
75, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply
76, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_apply
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -445,7 +445,7 @@ export class WebExtStorageBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
76, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id
77, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_ensure_current_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
FfiConverterString.lower(newSyncId),
)
@@ -466,7 +466,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
77, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync
78, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_last_sync
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -493,7 +493,7 @@ export class WebExtStorageBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
78, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync
79, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_prepare_for_sync
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
FfiConverterString.lower(clientData),
)
@@ -513,7 +513,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
79, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset
80, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -533,7 +533,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
80, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id
81, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_reset_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -560,7 +560,7 @@ export class WebExtStorageBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
81, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync
82, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_last_sync
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
FfiConverterI64.lower(lastSync),
)
@@ -596,7 +596,7 @@ export class WebExtStorageBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
82, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded
83, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_set_uploaded
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
FfiConverterI64.lower(serverModifiedMillis),
FfiConverterSequenceTypeGuid.lower(guids),
@@ -625,7 +625,7 @@ export class WebExtStorageBridgedEngine {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
83, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming
84, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_store_incoming
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
FfiConverterSequencestring.lower(incoming),
)
@@ -645,7 +645,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
84, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished
85, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_finished
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -665,7 +665,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
85, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id
86, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_id
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -684,7 +684,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
86, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started
87, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_sync_started
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -703,7 +703,7 @@ export class WebExtStorageBridgedEngine {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
87, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe
88, // webextstorage:uniffi_webext_storage_fn_method_webextstoragebridgedengine_wipe
FfiConverterTypeWebExtStorageBridgedEngine.lower(this),
)
}
@@ -778,7 +778,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
96, // webextstorage:uniffi_webext_storage_fn_constructor_webextstoragestore_new
97, // webextstorage:uniffi_webext_storage_fn_constructor_webextstoragestore_new
FfiConverterString.lower(path),
)
}
@@ -797,7 +797,7 @@ export class WebExtStorageStore {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
88, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine
89, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_bridged_engine
FfiConverterTypeWebExtStorageStore.lower(this),
)
}
@@ -825,7 +825,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
89, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_clear
90, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_clear
FfiConverterTypeWebExtStorageStore.lower(this),
FfiConverterString.lower(extId),
)
@@ -845,7 +845,7 @@ export class WebExtStorageStore {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
90, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_close
91, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_close
FfiConverterTypeWebExtStorageStore.lower(this),
)
}
@@ -881,7 +881,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
91, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get
92, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get
FfiConverterTypeWebExtStorageStore.lower(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -919,7 +919,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
92, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use
93, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_bytes_in_use
FfiConverterTypeWebExtStorageStore.lower(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -941,7 +941,7 @@ export class WebExtStorageStore {
const liftError = (data) => FfiConverterTypeWebExtStorageApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
93, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes
94, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_get_synced_changes
FfiConverterTypeWebExtStorageStore.lower(this),
)
}
@@ -977,7 +977,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
94, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_remove
95, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_remove
FfiConverterTypeWebExtStorageStore.lower(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(keys),
@@ -1015,7 +1015,7 @@ export class WebExtStorageStore {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
95, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_set
96, // webextstorage:uniffi_webext_storage_fn_method_webextstoragestore_set
FfiConverterTypeWebExtStorageStore.lower(this),
FfiConverterString.lower(extId),
FfiConverterTypeJsonValue.lower(val),

View File

@@ -18,6 +18,7 @@ main_thread = [
"SearchEngineSelector.clear_search_config",
"SearchEngineSelector.filter_engine_configuration",
"SearchEngineSelector.set_search_config",
"SearchEngineSelector.set_config_overrides",
]
[suggest.async_wrappers]

View File

@@ -431,7 +431,7 @@ export function add(a,b) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
97, // arithmetic:uniffi_arithmetical_fn_func_add
98, // arithmetic:uniffi_arithmetical_fn_func_add
FfiConverterU64.lower(a),
FfiConverterU64.lower(b),
)
@@ -469,7 +469,7 @@ export function div(dividend,divisor) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
98, // arithmetic:uniffi_arithmetical_fn_func_div
99, // arithmetic:uniffi_arithmetical_fn_func_div
FfiConverterU64.lower(dividend),
FfiConverterU64.lower(divisor),
)
@@ -507,7 +507,7 @@ export function equal(a,b) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
99, // arithmetic:uniffi_arithmetical_fn_func_equal
100, // arithmetic:uniffi_arithmetical_fn_func_equal
FfiConverterU64.lower(a),
FfiConverterU64.lower(b),
)
@@ -545,7 +545,7 @@ export function sub(a,b) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
100, // arithmetic:uniffi_arithmetical_fn_func_sub
101, // arithmetic:uniffi_arithmetical_fn_func_sub
FfiConverterU64.lower(a),
FfiConverterU64.lower(b),
)

View File

@@ -513,7 +513,7 @@ export function getCustomTypesDemo(demo) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
101, // custom_types:uniffi_uniffi_custom_types_fn_func_get_custom_types_demo
102, // custom_types:uniffi_uniffi_custom_types_fn_func_get_custom_types_demo
FfiConverterOptionalTypeCustomTypesDemo.lower(demo),
)
}

View File

@@ -437,7 +437,7 @@ export function gradient(value) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
102, // external_types:uniffi_uniffi_fixture_external_types_fn_func_gradient
103, // external_types:uniffi_uniffi_fixture_external_types_fn_func_gradient
FfiConverterOptionalTypeLine.lower(value),
)
}
@@ -474,7 +474,7 @@ export function intersection(ln1,ln2) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
103, // external_types:uniffi_uniffi_fixture_external_types_fn_func_intersection
104, // external_types:uniffi_uniffi_fixture_external_types_fn_func_intersection
FfiConverterTypeLine.lower(ln1),
FfiConverterTypeLine.lower(ln2),
)
@@ -503,7 +503,7 @@ export function moveSpriteToOrigin(sprite) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
104, // external_types:uniffi_uniffi_fixture_external_types_fn_func_move_sprite_to_origin
105, // external_types:uniffi_uniffi_fixture_external_types_fn_func_move_sprite_to_origin
FfiConverterTypeSprite.lower(sprite),
)
}

View File

@@ -737,7 +737,7 @@ export function callLogRepeat(logger,message,count,exclude) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
105, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_call_log_repeat
106, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_call_log_repeat
FfiConverterTypeLogger.lower(logger),
FfiConverterString.lower(message),
FfiConverterU32.lower(count),
@@ -776,7 +776,7 @@ export function logEvenNumbers(logger,items) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
106, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers
107, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers
FfiConverterTypeLogger.lower(logger),
FfiConverterSequencei32.lower(items),
)
@@ -813,7 +813,7 @@ export function logEvenNumbersMainThread(logger,items) {
throw e;
}
return UniFFIScaffolding.callSync(
107, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread
108, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread
FfiConverterTypeLogger.lower(logger),
FfiConverterSequencei32.lower(items),
)

View File

@@ -662,7 +662,7 @@ export class FutureTester {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
128, // futures:uniffi_uniffi_fixture_futures_fn_constructor_futuretester_init
129, // futures:uniffi_uniffi_fixture_futures_fn_constructor_futuretester_init
)
}
return handleRustResult(functionCall(), liftResult, liftError);}
@@ -687,7 +687,7 @@ export class FutureTester {
throw e;
}
return UniFFIScaffolding.callSync(
125, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_complete_futures
126, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_complete_futures
FfiConverterTypeFutureTester.lower(this),
FfiConverterU8.lower(value),
)
@@ -704,7 +704,7 @@ export class FutureTester {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsync(
126, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_make_future
127, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_make_future
FfiConverterTypeFutureTester.lower(this),
)
}
@@ -724,7 +724,7 @@ export class FutureTester {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
127, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_wake_futures
128, // futures:uniffi_uniffi_fixture_futures_fn_method_futuretester_wake_futures
FfiConverterTypeFutureTester.lower(this),
)
}
@@ -787,7 +787,7 @@ export class RustTask {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
129, // futures:uniffi_uniffi_fixture_futures_fn_method_rusttask_run
130, // futures:uniffi_uniffi_fixture_futures_fn_method_rusttask_run
FfiConverterTypeRustTask.lower(this),
)
}
@@ -858,7 +858,7 @@ export class Traveller {
throw e;
}
return UniFFIScaffolding.callSync(
131, // futures:uniffi_uniffi_fixture_futures_fn_constructor_traveller_new
132, // futures:uniffi_uniffi_fixture_futures_fn_constructor_traveller_new
FfiConverterString.lower(name),
)
}
@@ -873,7 +873,7 @@ export class Traveller {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
130, // futures:uniffi_uniffi_fixture_futures_fn_method_traveller_name
131, // futures:uniffi_uniffi_fixture_futures_fn_method_traveller_name
FfiConverterTypeTraveller.lower(this),
)
}
@@ -950,7 +950,7 @@ export class WorkerQueue {
throw e;
}
return UniFFIScaffolding.callSync(
132, // futures:uniffi_uniffi_fixture_futures_fn_method_workerqueue_add_task
133, // futures:uniffi_uniffi_fixture_futures_fn_method_workerqueue_add_task
FfiConverterTypeWorkerQueue.lower(this),
FfiConverterTypeRustTask.lower(task),
)
@@ -1104,7 +1104,7 @@ export function expensiveComputation() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsync(
108, // futures:uniffi_uniffi_fixture_futures_fn_func_expensive_computation
109, // futures:uniffi_uniffi_fixture_futures_fn_func_expensive_computation
)
}
try {
@@ -1127,7 +1127,7 @@ export function initializeGeckoGlobalWorkerQueue() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
109, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_gecko_global_worker_queue
110, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_gecko_global_worker_queue
)
}
return handleRustResult(functionCall(), liftResult, liftError);
@@ -1151,7 +1151,7 @@ export function initializeGlobalWorkerQueue(workerQueue) {
throw e;
}
return UniFFIScaffolding.callSync(
110, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_global_worker_queue
111, // futures:uniffi_uniffi_fixture_futures_fn_func_initialize_global_worker_queue
FfiConverterTypeWorkerQueue.lower(workerQueue),
)
}
@@ -1176,7 +1176,7 @@ export function roundtripF32(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
111, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f32
112, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f32
FfiConverterF32.lower(v),
)
}
@@ -1205,7 +1205,7 @@ export function roundtripF64(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
112, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f64
113, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_f64
FfiConverterF64.lower(v),
)
}
@@ -1234,7 +1234,7 @@ export function roundtripI16(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
113, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i16
114, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i16
FfiConverterI16.lower(v),
)
}
@@ -1263,7 +1263,7 @@ export function roundtripI32(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
114, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i32
115, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i32
FfiConverterI32.lower(v),
)
}
@@ -1292,7 +1292,7 @@ export function roundtripI64(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
115, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i64
116, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i64
FfiConverterI64.lower(v),
)
}
@@ -1321,7 +1321,7 @@ export function roundtripI8(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
116, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i8
117, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_i8
FfiConverterI8.lower(v),
)
}
@@ -1350,7 +1350,7 @@ export function roundtripMap(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
117, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_map
118, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_map
FfiConverterMapStringString.lower(v),
)
}
@@ -1379,7 +1379,7 @@ export function roundtripObj(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
118, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_obj
119, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_obj
FfiConverterTypeTraveller.lower(v),
)
}
@@ -1408,7 +1408,7 @@ export function roundtripString(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
119, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_string
120, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_string
FfiConverterString.lower(v),
)
}
@@ -1437,7 +1437,7 @@ export function roundtripU16(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
120, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u16
121, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u16
FfiConverterU16.lower(v),
)
}
@@ -1466,7 +1466,7 @@ export function roundtripU32(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
121, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u32
122, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u32
FfiConverterU32.lower(v),
)
}
@@ -1495,7 +1495,7 @@ export function roundtripU64(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
122, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u64
123, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u64
FfiConverterU64.lower(v),
)
}
@@ -1524,7 +1524,7 @@ export function roundtripU8(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
123, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u8
124, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_u8
FfiConverterU8.lower(v),
)
}
@@ -1553,7 +1553,7 @@ export function roundtripVec(v) {
throw e;
}
return UniFFIScaffolding.callAsync(
124, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_vec
125, // futures:uniffi_uniffi_fixture_futures_fn_func_roundtrip_vec
FfiConverterSequenceu32.lower(v),
)
}

View File

@@ -542,7 +542,7 @@ export function gradient(ln) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
133, // geometry:uniffi_uniffi_geometry_fn_func_gradient
134, // geometry:uniffi_uniffi_geometry_fn_func_gradient
FfiConverterTypeLine.lower(ln),
)
}
@@ -579,7 +579,7 @@ export function intersection(ln1,ln2) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
134, // geometry:uniffi_uniffi_geometry_fn_func_intersection
135, // geometry:uniffi_uniffi_geometry_fn_func_intersection
FfiConverterTypeLine.lower(ln1),
FfiConverterTypeLine.lower(ln2),
)

View File

@@ -371,7 +371,7 @@ export class SingletonObject {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
137, // refcounts:uniffi_uniffi_fixture_refcounts_fn_method_singletonobject_method
138, // refcounts:uniffi_uniffi_fixture_refcounts_fn_method_singletonobject_method
FfiConverterTypeSingletonObject.lower(this),
)
}
@@ -423,7 +423,7 @@ export function getJsRefcount() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
135, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_js_refcount
136, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_js_refcount
)
}
return handleRustResult(functionCall(), liftResult, liftError);
@@ -439,7 +439,7 @@ export function getSingleton() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
136, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_singleton
137, // refcounts:uniffi_uniffi_fixture_refcounts_fn_func_get_singleton
)
}
return handleRustResult(functionCall(), liftResult, liftError);

View File

@@ -665,7 +665,7 @@ export class Optionneur {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
168, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_optionneur_new
169, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_optionneur_new
)
}
try {
@@ -691,7 +691,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
143, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_boolean
144, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_boolean
FfiConverterTypeOptionneur.lower(this),
FfiConverterBool.lower(value),
)
@@ -720,7 +720,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
144, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_enum
145, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_enum
FfiConverterTypeOptionneur.lower(this),
FfiConverterTypeEnumeration.lower(value),
)
@@ -749,7 +749,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
145, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f32
146, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f32
FfiConverterTypeOptionneur.lower(this),
FfiConverterF32.lower(value),
)
@@ -778,7 +778,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
146, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f64
147, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f64
FfiConverterTypeOptionneur.lower(this),
FfiConverterF64.lower(value),
)
@@ -807,7 +807,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
147, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec
148, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterI16.lower(value),
)
@@ -836,7 +836,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
148, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex
149, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterI16.lower(value),
)
@@ -865,7 +865,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
149, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec
150, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterI32.lower(value),
)
@@ -894,7 +894,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
150, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex
151, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterI32.lower(value),
)
@@ -923,7 +923,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
151, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec
152, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterI64.lower(value),
)
@@ -952,7 +952,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
152, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex
153, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterI64.lower(value),
)
@@ -981,7 +981,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
153, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec
154, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterI8.lower(value),
)
@@ -1010,7 +1010,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
154, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex
155, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterI8.lower(value),
)
@@ -1039,7 +1039,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
155, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_null
156, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_null
FfiConverterTypeOptionneur.lower(this),
FfiConverterOptionalstring.lower(value),
)
@@ -1068,7 +1068,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
156, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_sequence
157, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_sequence
FfiConverterTypeOptionneur.lower(this),
FfiConverterSequencestring.lower(value),
)
@@ -1097,7 +1097,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
157, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_string
158, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_string
FfiConverterTypeOptionneur.lower(this),
FfiConverterString.lower(value),
)
@@ -1126,7 +1126,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
158, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec
159, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterU16.lower(value),
)
@@ -1155,7 +1155,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
159, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex
160, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterU16.lower(value),
)
@@ -1184,7 +1184,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
160, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec
161, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterU32.lower(value),
)
@@ -1213,7 +1213,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
161, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex
162, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterU32.lower(value),
)
@@ -1242,7 +1242,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
162, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct
163, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct
FfiConverterTypeOptionneur.lower(this),
FfiConverterU32.lower(value),
)
@@ -1271,7 +1271,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
163, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec
164, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterU64.lower(value),
)
@@ -1300,7 +1300,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
164, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex
165, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterU64.lower(value),
)
@@ -1329,7 +1329,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
165, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec
166, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec
FfiConverterTypeOptionneur.lower(this),
FfiConverterU8.lower(value),
)
@@ -1358,7 +1358,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
166, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex
167, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex
FfiConverterTypeOptionneur.lower(this),
FfiConverterU8.lower(value),
)
@@ -1387,7 +1387,7 @@ export class Optionneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
167, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_zero
168, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_zero
FfiConverterTypeOptionneur.lower(this),
FfiConverterOptionali32.lower(value),
)
@@ -1455,7 +1455,7 @@ export class Retourneur {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
184, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_retourneur_new
185, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_retourneur_new
)
}
try {
@@ -1481,7 +1481,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
169, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_boolean
170, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_boolean
FfiConverterTypeRetourneur.lower(this),
FfiConverterBool.lower(value),
)
@@ -1510,7 +1510,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
170, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_double
171, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_double
FfiConverterTypeRetourneur.lower(this),
FfiConverterF64.lower(value),
)
@@ -1539,7 +1539,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
171, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_float
172, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_float
FfiConverterTypeRetourneur.lower(this),
FfiConverterF32.lower(value),
)
@@ -1568,7 +1568,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
172, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i16
173, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i16
FfiConverterTypeRetourneur.lower(this),
FfiConverterI16.lower(value),
)
@@ -1597,7 +1597,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
173, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i32
174, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i32
FfiConverterTypeRetourneur.lower(this),
FfiConverterI32.lower(value),
)
@@ -1626,7 +1626,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
174, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i64
175, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i64
FfiConverterTypeRetourneur.lower(this),
FfiConverterI64.lower(value),
)
@@ -1655,7 +1655,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
175, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i8
176, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i8
FfiConverterTypeRetourneur.lower(this),
FfiConverterI8.lower(value),
)
@@ -1684,7 +1684,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
176, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres
177, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres
FfiConverterTypeRetourneur.lower(this),
FfiConverterTypeDictionnaireNombres.lower(value),
)
@@ -1713,7 +1713,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
177, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes
178, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes
FfiConverterTypeRetourneur.lower(this),
FfiConverterTypeDictionnaireNombresSignes.lower(value),
)
@@ -1742,7 +1742,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
178, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire
179, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire
FfiConverterTypeRetourneur.lower(this),
FfiConverterTypeOptionneurDictionnaire.lower(value),
)
@@ -1771,7 +1771,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
179, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_string
180, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_string
FfiConverterTypeRetourneur.lower(this),
FfiConverterString.lower(value),
)
@@ -1800,7 +1800,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
180, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u16
181, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u16
FfiConverterTypeRetourneur.lower(this),
FfiConverterU16.lower(value),
)
@@ -1829,7 +1829,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
181, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u32
182, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u32
FfiConverterTypeRetourneur.lower(this),
FfiConverterU32.lower(value),
)
@@ -1858,7 +1858,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
182, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u64
183, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u64
FfiConverterTypeRetourneur.lower(this),
FfiConverterU64.lower(value),
)
@@ -1887,7 +1887,7 @@ export class Retourneur {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
183, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u8
184, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u8
FfiConverterTypeRetourneur.lower(this),
FfiConverterU8.lower(value),
)
@@ -1955,7 +1955,7 @@ export class Stringifier {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
197, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_stringifier_new
198, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_stringifier_new
)
}
try {
@@ -1981,7 +1981,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
185, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_boolean
186, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_boolean
FfiConverterTypeStringifier.lower(this),
FfiConverterBool.lower(value),
)
@@ -2010,7 +2010,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
186, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_double
187, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_double
FfiConverterTypeStringifier.lower(this),
FfiConverterF64.lower(value),
)
@@ -2039,7 +2039,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
187, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_float
188, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_float
FfiConverterTypeStringifier.lower(this),
FfiConverterF32.lower(value),
)
@@ -2068,7 +2068,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
188, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i16
189, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i16
FfiConverterTypeStringifier.lower(this),
FfiConverterI16.lower(value),
)
@@ -2097,7 +2097,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
189, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i32
190, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i32
FfiConverterTypeStringifier.lower(this),
FfiConverterI32.lower(value),
)
@@ -2126,7 +2126,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
190, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i64
191, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i64
FfiConverterTypeStringifier.lower(this),
FfiConverterI64.lower(value),
)
@@ -2155,7 +2155,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
191, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i8
192, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i8
FfiConverterTypeStringifier.lower(this),
FfiConverterI8.lower(value),
)
@@ -2184,7 +2184,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
192, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u16
193, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u16
FfiConverterTypeStringifier.lower(this),
FfiConverterU16.lower(value),
)
@@ -2213,7 +2213,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
193, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u32
194, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u32
FfiConverterTypeStringifier.lower(this),
FfiConverterU32.lower(value),
)
@@ -2242,7 +2242,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
194, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u64
195, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u64
FfiConverterTypeStringifier.lower(this),
FfiConverterU64.lower(value),
)
@@ -2271,7 +2271,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
195, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u8
196, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u8
FfiConverterTypeStringifier.lower(this),
FfiConverterU8.lower(value),
)
@@ -2300,7 +2300,7 @@ export class Stringifier {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
196, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_well_known_string
197, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_well_known_string
FfiConverterTypeStringifier.lower(this),
FfiConverterString.lower(value),
)
@@ -3677,7 +3677,7 @@ export function copieCarte(c) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
138, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_carte
139, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_carte
FfiConverterMapStringTypeEnumerationAvecDonnees.lower(c),
)
}
@@ -3706,7 +3706,7 @@ export function copieDictionnaire(d) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
139, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_dictionnaire
140, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_dictionnaire
FfiConverterTypeDictionnaire.lower(d),
)
}
@@ -3735,7 +3735,7 @@ export function copieEnumeration(e) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
140, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumeration
141, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumeration
FfiConverterTypeEnumeration.lower(e),
)
}
@@ -3764,7 +3764,7 @@ export function copieEnumerations(e) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
141, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumerations
142, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumerations
FfiConverterSequenceTypeEnumeration.lower(e),
)
}
@@ -3793,7 +3793,7 @@ export function switcheroo(b) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
142, // rondpoint:uniffi_uniffi_rondpoint_fn_func_switcheroo
143, // rondpoint:uniffi_uniffi_rondpoint_fn_func_switcheroo
FfiConverterBool.lower(b),
)
}

View File

@@ -370,7 +370,7 @@ export class Sprite {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
202, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new
203, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new
FfiConverterOptionalTypePoint.lower(initialPosition),
)
}
@@ -404,7 +404,7 @@ export class Sprite {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
203, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new_relative_to
204, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new_relative_to
FfiConverterTypePoint.lower(reference),
FfiConverterTypeVector.lower(direction),
)
@@ -424,7 +424,7 @@ export class Sprite {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
199, // sprites:uniffi_uniffi_sprites_fn_method_sprite_get_position
200, // sprites:uniffi_uniffi_sprites_fn_method_sprite_get_position
FfiConverterTypeSprite.lower(this),
)
}
@@ -451,7 +451,7 @@ export class Sprite {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
200, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_by
201, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_by
FfiConverterTypeSprite.lower(this),
FfiConverterTypeVector.lower(direction),
)
@@ -479,7 +479,7 @@ export class Sprite {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
201, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_to
202, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_to
FfiConverterTypeSprite.lower(this),
FfiConverterTypePoint.lower(position),
)
@@ -755,7 +755,7 @@ export function translate(p,v) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
198, // sprites:uniffi_uniffi_sprites_fn_func_translate
199, // sprites:uniffi_uniffi_sprites_fn_func_translate
FfiConverterTypePoint.lower(p),
FfiConverterTypeVector.lower(v),
)

View File

@@ -343,7 +343,7 @@ export class TodoList {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
218, // todolist:uniffi_uniffi_todolist_fn_constructor_todolist_new
219, // todolist:uniffi_uniffi_todolist_fn_constructor_todolist_new
)
}
try {
@@ -368,7 +368,7 @@ export class TodoList {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
207, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entries
208, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entries
FfiConverterTypeTodoList.lower(this),
FfiConverterSequenceTypeTodoEntry.lower(entries),
)
@@ -396,7 +396,7 @@ export class TodoList {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
208, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entry
209, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entry
FfiConverterTypeTodoList.lower(this),
FfiConverterTypeTodoEntry.lower(entry),
)
@@ -424,7 +424,7 @@ export class TodoList {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
209, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_item
210, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_item
FfiConverterTypeTodoList.lower(this),
FfiConverterString.lower(todo),
)
@@ -452,7 +452,7 @@ export class TodoList {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
210, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_items
211, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_items
FfiConverterTypeTodoList.lower(this),
FfiConverterSequencestring.lower(items),
)
@@ -480,7 +480,7 @@ export class TodoList {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
211, // todolist:uniffi_uniffi_todolist_fn_method_todolist_clear_item
212, // todolist:uniffi_uniffi_todolist_fn_method_todolist_clear_item
FfiConverterTypeTodoList.lower(this),
FfiConverterString.lower(todo),
)
@@ -501,7 +501,7 @@ export class TodoList {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
212, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_entries
213, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_entries
FfiConverterTypeTodoList.lower(this),
)
}
@@ -521,7 +521,7 @@ export class TodoList {
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
213, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_first
214, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_first
FfiConverterTypeTodoList.lower(this),
)
}
@@ -541,7 +541,7 @@ export class TodoList {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
214, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_items
215, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_items
FfiConverterTypeTodoList.lower(this),
)
}
@@ -561,7 +561,7 @@ export class TodoList {
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
215, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last
216, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last
FfiConverterTypeTodoList.lower(this),
)
}
@@ -581,7 +581,7 @@ export class TodoList {
const liftError = (data) => FfiConverterTypeTodoError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
216, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last_entry
217, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last_entry
FfiConverterTypeTodoList.lower(this),
)
}
@@ -600,7 +600,7 @@ export class TodoList {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
217, // todolist:uniffi_uniffi_todolist_fn_method_todolist_make_default
218, // todolist:uniffi_uniffi_todolist_fn_method_todolist_make_default
FfiConverterTypeTodoList.lower(this),
)
}
@@ -992,7 +992,7 @@ export function createEntryWith(todo) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
204, // todolist:uniffi_uniffi_todolist_fn_func_create_entry_with
205, // todolist:uniffi_uniffi_todolist_fn_func_create_entry_with
FfiConverterString.lower(todo),
)
}
@@ -1013,7 +1013,7 @@ export function getDefaultList() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsyncWrapper(
205, // todolist:uniffi_uniffi_todolist_fn_func_get_default_list
206, // todolist:uniffi_uniffi_todolist_fn_func_get_default_list
)
}
try {
@@ -1040,7 +1040,7 @@ export function setDefaultList(list) {
throw e;
}
return UniFFIScaffolding.callAsyncWrapper(
206, // todolist:uniffi_uniffi_todolist_fn_func_set_default_list
207, // todolist:uniffi_uniffi_todolist_fn_func_set_default_list
FfiConverterTypeTodoList.lower(list),
)
}

View File

@@ -388,7 +388,7 @@ export class Calc {
throw e;
}
return UniFFIScaffolding.callSync(
221, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_method_calc_add
222, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_method_calc_add
FfiConverterTypeCalc.lower(this),
FfiConverterU32.lower(a),
FfiConverterU32.lower(b),
@@ -442,7 +442,7 @@ export function makeBuggyCalculator() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
219, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_buggy_calculator
220, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_buggy_calculator
)
}
return handleRustResult(functionCall(), liftResult, liftError);
@@ -458,7 +458,7 @@ export function makeCalculator() {
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callSync(
220, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_calculator
221, // uniffi_trait_interfaces:uniffi_uniffi_trait_interfaces_fn_func_make_calculator
)
}
return handleRustResult(functionCall(), liftResult, liftError);

View File

@@ -349,6 +349,7 @@ extern "C" {
void* uniffi_search_fn_constructor_searchengineselector_new(RustCallStatus*);
void uniffi_search_fn_method_searchengineselector_clear_search_config(void*, RustCallStatus*);
RustBuffer uniffi_search_fn_method_searchengineselector_filter_engine_configuration(void*, RustBuffer, RustCallStatus*);
void uniffi_search_fn_method_searchengineselector_set_config_overrides(void*, RustBuffer, RustCallStatus*);
void uniffi_search_fn_method_searchengineselector_set_search_config(void*, RustBuffer, RustCallStatus*);
void uniffi_search_fn_method_searchengineselector_use_remote_settings_server(void*, void*, int8_t, RustCallStatus*);
RustBuffer ffi_search_rustbuffer_alloc(uint64_t, RustCallStatus*);
@@ -409,6 +410,7 @@ extern "C" {
void ffi_search_rust_future_complete_void(uint64_t, RustCallStatus*);
uint16_t uniffi_search_checksum_method_searchengineselector_clear_search_config();
uint16_t uniffi_search_checksum_method_searchengineselector_filter_engine_configuration();
uint16_t uniffi_search_checksum_method_searchengineselector_set_config_overrides();
uint16_t uniffi_search_checksum_method_searchengineselector_set_search_config();
uint16_t uniffi_search_checksum_method_searchengineselector_use_remote_settings_server();
uint16_t uniffi_search_checksum_constructor_searchengineselector_new();
@@ -3207,6 +3209,37 @@ public:
);
}
};
class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides : public UniffiSyncCallHandler {
private:
// PrepareRustArgs stores the resulting arguments in these fields
typename ScaffoldingObjectConverter<&kSearchSearchEngineSelectorPointerType>::IntermediateType mPtr;
typename ScaffoldingConverter<RustBuffer>::IntermediateType mOverrides;
// MakeRustCall stores the result of the call in these fields
public:
void PrepareRustArgs(const dom::Sequence<dom::UniFFIScaffoldingValue>& aArgs, ErrorResult& aError) override {
ScaffoldingObjectConverter<&kSearchSearchEngineSelectorPointerType>::FromJs(aArgs[0], &mPtr, aError);
if (aError.Failed()) {
return;
}
ScaffoldingConverter<RustBuffer>::FromJs(aArgs[1], &mOverrides, aError);
if (aError.Failed()) {
return;
}
}
void MakeRustCall(RustCallStatus* aOutStatus) override {
uniffi_search_fn_method_searchengineselector_set_config_overrides(
ScaffoldingObjectConverter<&kSearchSearchEngineSelectorPointerType>::IntoRust(std::move(mPtr)),
ScaffoldingConverter<RustBuffer>::IntoRust(std::move(mOverrides)),
aOutStatus
);
}
virtual void ExtractSuccessfulCallResult(JSContext* aCx, dom::Optional<dom::UniFFIScaffoldingValue>& aDest, ErrorResult& aError) override {
}
};
class ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig : public UniffiSyncCallHandler {
private:
// PrepareRustArgs stores the resulting arguments in these fields
@@ -10285,542 +10318,545 @@ UniquePtr<UniffiSyncCallHandler> GetSyncCallHandler(uint64_t aId) {
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorFilterEngineConfiguration>();
}
case 27: {
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig>();
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetConfigOverrides>();
}
case 28: {
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer>();
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorSetSearchConfig>();
}
case 29: {
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew>();
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnMethodSearchengineselectorUseRemoteSettingsServer>();
}
case 30: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches>();
return MakeUnique<ScaffoldingCallHandlerUniffiSearchFnConstructorSearchengineselectorNew>();
}
case 31: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnFuncRawSuggestionUrlMatches>();
}
case 32: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClear>();
}
case 33: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreClearDismissedSuggestions>();
}
case 34: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreDismissSuggestion>();
}
case 35: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGlobalConfig>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGeonames>();
}
case 36: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchProviderConfig>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchGlobalConfig>();
}
case 37: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIngest>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreFetchProviderConfig>();
}
case 38: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreInterrupt>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreIngest>();
}
case 39: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQuery>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreInterrupt>();
}
case 40: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQueryWithMetrics>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQuery>();
}
case 41: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststoreQueryWithMetrics>();
}
case 42: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderBuild>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststoreNew>();
}
case 43: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderCachePath>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderBuild>();
}
case 44: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderDataPath>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderCachePath>();
}
case 45: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderLoadExtension>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderDataPath>();
}
case 46: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsBucketName>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderLoadExtension>();
}
case 47: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsServer>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsBucketName>();
}
case 48: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsService>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsServer>();
}
case 49: {
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststorebuilderNew>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnMethodSuggeststorebuilderRemoteSettingsService>();
}
case 50: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommand>();
return MakeUnique<ScaffoldingCallHandlerUniffiSuggestFnConstructorSuggeststorebuilderNew>();
}
case 51: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommandAt>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommand>();
}
case 52: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreGetUnsentCommands>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreAddRemoteCommandAt>();
}
case 53: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreRemoveRemoteCommand>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreGetUnsentCommands>();
}
case 54: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreSetPendingCommandSent>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreRemoveRemoteCommand>();
}
case 55: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineApply>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodRemotecommandstoreSetPendingCommandSent>();
}
case 56: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineEnsureCurrentSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineApply>();
}
case 57: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineLastSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineEnsureCurrentSyncId>();
}
case 58: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedenginePrepareForSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineLastSync>();
}
case 59: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineReset>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedenginePrepareForSync>();
}
case 60: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineResetSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineReset>();
}
case 61: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetLastSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineResetSyncId>();
}
case 62: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetUploaded>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetLastSync>();
}
case 63: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineStoreIncoming>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSetUploaded>();
}
case 64: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncFinished>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineStoreIncoming>();
}
case 65: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncFinished>();
}
case 66: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncStarted>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncId>();
}
case 67: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineWipe>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineSyncStarted>();
}
case 68: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreBridgedEngine>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsbridgedengineWipe>();
}
case 69: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreCloseConnection>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreBridgedEngine>();
}
case 70: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreGetAll>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreCloseConnection>();
}
case 71: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreNewRemoteCommandStore>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreGetAll>();
}
case 72: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreRegisterWithSyncManager>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreNewRemoteCommandStore>();
}
case 73: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreSetLocalTabs>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreRegisterWithSyncManager>();
}
case 74: {
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnConstructorTabsstoreNew>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnMethodTabsstoreSetLocalTabs>();
}
case 75: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineApply>();
return MakeUnique<ScaffoldingCallHandlerUniffiTabsFnConstructorTabsstoreNew>();
}
case 76: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineEnsureCurrentSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineApply>();
}
case 77: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineLastSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineEnsureCurrentSyncId>();
}
case 78: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedenginePrepareForSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineLastSync>();
}
case 79: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineReset>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedenginePrepareForSync>();
}
case 80: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineResetSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineReset>();
}
case 81: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetLastSync>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineResetSyncId>();
}
case 82: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetUploaded>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetLastSync>();
}
case 83: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineStoreIncoming>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSetUploaded>();
}
case 84: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncFinished>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineStoreIncoming>();
}
case 85: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncId>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncFinished>();
}
case 86: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncStarted>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncId>();
}
case 87: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineWipe>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineSyncStarted>();
}
case 88: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreBridgedEngine>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragebridgedengineWipe>();
}
case 89: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClear>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreBridgedEngine>();
}
case 90: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClose>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClear>();
}
case 91: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGet>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreClose>();
}
case 92: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetBytesInUse>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGet>();
}
case 93: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetSyncedChanges>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetBytesInUse>();
}
case 94: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreRemove>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreGetSyncedChanges>();
}
case 95: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreSet>();
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreRemove>();
}
case 96: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnMethodWebextstoragestoreSet>();
}
case 97: {
return MakeUnique<ScaffoldingCallHandlerUniffiWebextStorageFnConstructorWebextstoragestoreNew>();
}
#ifdef MOZ_UNIFFI_FIXTURES
case 97: {
case 98: {
return MakeUnique<ScaffoldingCallHandlerUniffiArithmeticalFnFuncAdd>();
}
case 98: {
case 99: {
return MakeUnique<ScaffoldingCallHandlerUniffiArithmeticalFnFuncDiv>();
}
case 99: {
case 100: {
return MakeUnique<ScaffoldingCallHandlerUniffiArithmeticalFnFuncEqual>();
}
case 100: {
case 101: {
return MakeUnique<ScaffoldingCallHandlerUniffiArithmeticalFnFuncSub>();
}
case 101: {
case 102: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiCustomTypesFnFuncGetCustomTypesDemo>();
}
case 102: {
case 103: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureExternalTypesFnFuncGradient>();
}
case 103: {
case 104: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureExternalTypesFnFuncIntersection>();
}
case 104: {
case 105: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureExternalTypesFnFuncMoveSpriteToOrigin>();
}
case 105: {
case 106: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureCallbacksFnFuncCallLogRepeat>();
}
case 106: {
case 107: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureCallbacksFnFuncLogEvenNumbers>();
}
case 107: {
case 108: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureCallbacksFnFuncLogEvenNumbersMainThread>();
}
case 109: {
case 110: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncInitializeGeckoGlobalWorkerQueue>();
}
case 110: {
case 111: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncInitializeGlobalWorkerQueue>();
}
case 125: {
case 126: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodFuturetesterCompleteFutures>();
}
case 127: {
case 128: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodFuturetesterWakeFutures>();
}
case 128: {
case 129: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnConstructorFuturetesterInit>();
}
case 129: {
case 130: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodRusttaskRun>();
}
case 130: {
case 131: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodTravellerName>();
}
case 131: {
case 132: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnConstructorTravellerNew>();
}
case 132: {
case 133: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodWorkerqueueAddTask>();
}
case 133: {
case 134: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiGeometryFnFuncGradient>();
}
case 134: {
case 135: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiGeometryFnFuncIntersection>();
}
case 135: {
case 136: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureRefcountsFnFuncGetJsRefcount>();
}
case 136: {
case 137: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureRefcountsFnFuncGetSingleton>();
}
case 137: {
case 138: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureRefcountsFnMethodSingletonobjectMethod>();
}
case 138: {
case 139: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnFuncCopieCarte>();
}
case 139: {
case 140: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnFuncCopieDictionnaire>();
}
case 140: {
case 141: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnFuncCopieEnumeration>();
}
case 141: {
case 142: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnFuncCopieEnumerations>();
}
case 142: {
case 143: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnFuncSwitcheroo>();
}
case 143: {
case 144: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonBoolean>();
}
case 144: {
case 145: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonEnum>();
}
case 145: {
case 146: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonF32>();
}
case 146: {
case 147: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonF64>();
}
case 147: {
case 148: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI16Dec>();
}
case 148: {
case 149: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI16Hex>();
}
case 149: {
case 150: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI32Dec>();
}
case 150: {
case 151: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI32Hex>();
}
case 151: {
case 152: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI64Dec>();
}
case 152: {
case 153: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI64Hex>();
}
case 153: {
case 154: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI8Dec>();
}
case 154: {
case 155: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonI8Hex>();
}
case 155: {
case 156: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonNull>();
}
case 156: {
case 157: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonSequence>();
}
case 157: {
case 158: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonString>();
}
case 158: {
case 159: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU16Dec>();
}
case 159: {
case 160: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU16Hex>();
}
case 160: {
case 161: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU32Dec>();
}
case 161: {
case 162: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU32Hex>();
}
case 162: {
case 163: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU32Oct>();
}
case 163: {
case 164: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU64Dec>();
}
case 164: {
case 165: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU64Hex>();
}
case 165: {
case 166: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU8Dec>();
}
case 166: {
case 167: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonU8Hex>();
}
case 167: {
case 168: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodOptionneurSinonZero>();
}
case 168: {
case 169: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnConstructorOptionneurNew>();
}
case 169: {
case 170: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueBoolean>();
}
case 170: {
case 171: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueDouble>();
}
case 171: {
case 172: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueFloat>();
}
case 172: {
case 173: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueI16>();
}
case 173: {
case 174: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueI32>();
}
case 174: {
case 175: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueI64>();
}
case 175: {
case 176: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueI8>();
}
case 176: {
case 177: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueNombres>();
}
case 177: {
case 178: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueNombresSignes>();
}
case 178: {
case 179: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueOptionneurDictionnaire>();
}
case 179: {
case 180: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueString>();
}
case 180: {
case 181: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueU16>();
}
case 181: {
case 182: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueU32>();
}
case 182: {
case 183: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueU64>();
}
case 183: {
case 184: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodRetourneurIdentiqueU8>();
}
case 184: {
case 185: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnConstructorRetourneurNew>();
}
case 185: {
case 186: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringBoolean>();
}
case 186: {
case 187: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringDouble>();
}
case 187: {
case 188: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringFloat>();
}
case 188: {
case 189: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringI16>();
}
case 189: {
case 190: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringI32>();
}
case 190: {
case 191: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringI64>();
}
case 191: {
case 192: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringI8>();
}
case 192: {
case 193: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringU16>();
}
case 193: {
case 194: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringU32>();
}
case 194: {
case 195: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringU64>();
}
case 195: {
case 196: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierToStringU8>();
}
case 196: {
case 197: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnMethodStringifierWellKnownString>();
}
case 197: {
case 198: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiRondpointFnConstructorStringifierNew>();
}
case 198: {
case 199: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnFuncTranslate>();
}
case 199: {
case 200: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnMethodSpriteGetPosition>();
}
case 200: {
case 201: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnMethodSpriteMoveBy>();
}
case 201: {
case 202: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnMethodSpriteMoveTo>();
}
case 202: {
case 203: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnConstructorSpriteNew>();
}
case 203: {
case 204: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiSpritesFnConstructorSpriteNewRelativeTo>();
}
case 204: {
case 205: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnFuncCreateEntryWith>();
}
case 205: {
case 206: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnFuncGetDefaultList>();
}
case 206: {
case 207: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnFuncSetDefaultList>();
}
case 207: {
case 208: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistAddEntries>();
}
case 208: {
case 209: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistAddEntry>();
}
case 209: {
case 210: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistAddItem>();
}
case 210: {
case 211: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistAddItems>();
}
case 211: {
case 212: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistClearItem>();
}
case 212: {
case 213: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistGetEntries>();
}
case 213: {
case 214: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistGetFirst>();
}
case 214: {
case 215: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistGetItems>();
}
case 215: {
case 216: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistGetLast>();
}
case 216: {
case 217: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistGetLastEntry>();
}
case 217: {
case 218: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnMethodTodolistMakeDefault>();
}
case 218: {
case 219: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTodolistFnConstructorTodolistNew>();
}
case 219: {
case 220: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTraitInterfacesFnFuncMakeBuggyCalculator>();
}
case 220: {
case 221: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTraitInterfacesFnFuncMakeCalculator>();
}
case 221: {
case 222: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiTraitInterfacesFnMethodCalcAdd>();
}
#endif /* MOZ_UNIFFI_FIXTURES */
@@ -10835,52 +10871,52 @@ UniquePtr<UniffiAsyncCallHandler> GetAsyncCallHandler(uint64_t aId) {
#ifdef MOZ_UNIFFI_FIXTURES
case 108: {
case 109: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncExpensiveComputation>();
}
case 111: {
case 112: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripF32>();
}
case 112: {
case 113: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripF64>();
}
case 113: {
case 114: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripI16>();
}
case 114: {
case 115: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripI32>();
}
case 115: {
case 116: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripI64>();
}
case 116: {
case 117: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripI8>();
}
case 117: {
case 118: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripMap>();
}
case 118: {
case 119: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripObj>();
}
case 119: {
case 120: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripString>();
}
case 120: {
case 121: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripU16>();
}
case 121: {
case 122: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripU32>();
}
case 122: {
case 123: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripU64>();
}
case 123: {
case 124: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripU8>();
}
case 124: {
case 125: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnFuncRoundtripVec>();
}
case 126: {
case 127: {
return MakeUnique<ScaffoldingCallHandlerUniffiUniffiFixtureFuturesFnMethodFuturetesterMakeFuture>();
}
#endif /* MOZ_UNIFFI_FIXTURES */