Browse Source

Implement TryFromJs for Either<L, R> (#3822)

* Implement TryFromJs for Either<L, R>

* Add explicit feature in Cargo.toml
pull/3832/head
Hans Larsen 7 months ago committed by GitHub
parent
commit
61567687cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      Cargo.lock
  2. 2
      core/engine/Cargo.toml
  3. 44
      core/engine/src/value/conversions/either.rs
  4. 1
      core/engine/src/value/conversions/mod.rs

1
Cargo.lock generated

@ -399,6 +399,7 @@ dependencies = [
"cfg-if", "cfg-if",
"criterion", "criterion",
"dashmap", "dashmap",
"either",
"fast-float", "fast-float",
"fixed_decimal", "fixed_decimal",
"float-cmp", "float-cmp",

2
core/engine/Cargo.toml

@ -14,6 +14,7 @@ rust-version.workspace = true
[features] [features]
profiler = ["boa_profiler/profiler"] profiler = ["boa_profiler/profiler"]
deser = ["boa_interner/serde", "boa_ast/serde"] deser = ["boa_interner/serde", "boa_ast/serde"]
either = ["dep:either"]
# Enables the `Intl` builtin object and bundles a default ICU4X data provider. # Enables the `Intl` builtin object and bundles a default ICU4X data provider.
# Prefer this over `intl` if you just want to enable `Intl` without dealing with the # Prefer this over `intl` if you just want to enable `Intl` without dealing with the
@ -104,6 +105,7 @@ intrusive-collections = "0.9.6"
cfg-if = "1.0.0" cfg-if = "1.0.0"
time.workspace = true time.workspace = true
hashbrown.workspace = true hashbrown.workspace = true
either = { version = "1", optional = true }
# intl deps # intl deps
boa_icu_provider = { workspace = true, features = ["std"], optional = true } boa_icu_provider = { workspace = true, features = ["std"], optional = true }

44
core/engine/src/value/conversions/either.rs

@ -0,0 +1,44 @@
//! Implementation of [`TryFromJs`] for [`Either`].
//!
//! This will try to deserialize for the [`Either::Left`] type
//! first, and if it fails will try the [`Either::Right`] type.
//!
//! Upon failure of both, the second failure will be returned.
#![cfg(feature = "either")]
use crate::value::TryFromJs;
use boa_engine::{Context, JsResult, JsValue};
use either::Either;
impl<L, R> TryFromJs for Either<L, R>
where
L: TryFromJs,
R: TryFromJs,
{
#[inline]
fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
L::try_from_js(value, context)
.map(Self::Left)
.or_else(|_| R::try_from_js(value, context).map(Self::Right))
}
}
#[test]
fn either() {
let v = JsValue::Integer(123);
let mut context = Context::default();
assert_eq!(
Either::<i32, i32>::try_from_js(&v, &mut context),
Ok(Either::Left(123))
);
assert_eq!(
Either::<i32, String>::try_from_js(&v, &mut context),
Ok(Either::Left(123))
);
assert_eq!(
Either::<String, i32>::try_from_js(&v, &mut context),
Ok(Either::Right(123))
);
assert!(Either::<String, String>::try_from_js(&v, &mut context).is_err());
}

1
core/engine/src/value/conversions/mod.rs

@ -4,6 +4,7 @@ use crate::js_string;
use super::{JsBigInt, JsObject, JsString, JsSymbol, JsValue, Profiler}; use super::{JsBigInt, JsObject, JsString, JsSymbol, JsValue, Profiler};
mod either;
mod serde_json; mod serde_json;
pub(super) mod try_from_js; pub(super) mod try_from_js;

Loading…
Cancel
Save