Skip to content

Commit

Permalink
Implement TryFromJs for Either<L, R> (#3822)
Browse files Browse the repository at this point in the history
* Implement TryFromJs for Either<L, R>

* Add explicit feature in Cargo.toml
  • Loading branch information
hansl authored Apr 26, 2024
1 parent 9ec0a13 commit 6156768
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions core/engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ rust-version.workspace = true
[features]
profiler = ["boa_profiler/profiler"]
deser = ["boa_interner/serde", "boa_ast/serde"]
either = ["dep:either"]

# 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
Expand Down Expand Up @@ -104,6 +105,7 @@ intrusive-collections = "0.9.6"
cfg-if = "1.0.0"
time.workspace = true
hashbrown.workspace = true
either = { version = "1", optional = true }

# intl deps
boa_icu_provider = { workspace = true, features = ["std"], optional = true }
Expand Down
44 changes: 44 additions & 0 deletions core/engine/src/value/conversions/either.rs
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions core/engine/src/value/conversions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::js_string;

use super::{JsBigInt, JsObject, JsString, JsSymbol, JsValue, Profiler};

mod either;
mod serde_json;
pub(super) mod try_from_js;

Expand Down

0 comments on commit 6156768

Please sign in to comment.