Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/engine/src/module/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ pub fn resolve_module_specifier(

// On Windows, also replace `/` with `\`. JavaScript imports use `/` as path separator.
#[cfg(target_family = "windows")]
let specifier = specifier.replace('/', "\\");
let specifier = cow_utils::CowUtils::cow_replace(specifier.as_str(), '/', "\\");

let short_path = Path::new(&specifier);
let short_path = Path::new(&*specifier);

// In ECMAScript, a path is considered relative if it starts with
// `./` or `../`. In Rust it's any path that start with `/`.
Expand All @@ -79,7 +79,7 @@ pub fn resolve_module_specifier(
));
}
} else {
base_path.join(&specifier)
base_path.join(&*specifier)
};

if long_path.is_relative() && base.is_some() {
Expand Down
27 changes: 27 additions & 0 deletions core/engine/src/value/conversions/try_from_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,33 @@ impl TryFromJs for JsString {
}
}

impl<T> TryFromJs for Box<T>
where
T: TryFromJs,
{
fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
T::try_from_js(value, context).map(Box::new)
}
}

impl<T> TryFromJs for std::rc::Rc<T>
where
T: TryFromJs,
{
fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
T::try_from_js(value, context).map(std::rc::Rc::new)
}
}

impl<T> TryFromJs for std::sync::Arc<T>
where
T: TryFromJs,
{
fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
T::try_from_js(value, context).map(std::sync::Arc::new)
}
}

impl<T> TryFromJs for Option<T>
where
T: TryFromJs,
Expand Down
75 changes: 64 additions & 11 deletions core/engine/src/value/conversions/try_into_js.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::class::Class;
use crate::{Context, JsNativeError, JsResult, JsString, JsValue};

/// This trait adds a conversions from a Rust Type into [`JsValue`].
Expand All @@ -7,15 +6,6 @@ pub trait TryIntoJs: Sized {
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue>;
}

impl<T> TryIntoJs for T
where
T: Class + Clone,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
T::from_data(self.clone(), context).map(JsValue::from)
}
}

impl TryIntoJs for bool {
fn try_into_js(&self, _context: &mut Context) -> JsResult<JsValue> {
Ok(JsValue::from(*self))
Expand Down Expand Up @@ -146,6 +136,42 @@ impl TryIntoJs for u128 {
}
}

impl<T> TryIntoJs for &T
where
T: TryIntoJs,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
(**self).try_into_js(context)
}
}

impl<T> TryIntoJs for Box<T>
where
T: TryIntoJs,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
self.as_ref().try_into_js(context)
}
}

impl<T> TryIntoJs for std::rc::Rc<T>
where
T: TryIntoJs,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
self.as_ref().try_into_js(context)
}
}

impl<T> TryIntoJs for std::sync::Arc<T>
where
T: TryIntoJs,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
self.as_ref().try_into_js(context)
}
}

impl<T> TryIntoJs for Option<T>
where
T: TryIntoJs,
Expand Down Expand Up @@ -236,7 +262,7 @@ where
#[cfg(test)]
mod try_into_js_tests {
use crate::value::{TryFromJs, TryIntoJs};
use crate::{Context, JsResult};
use crate::{Context, JsResult, JsValue};

#[test]
fn big_int_err() {
Expand Down Expand Up @@ -314,4 +340,31 @@ mod try_into_js_tests {
assert_eq!(vec_init, vec);
Ok(())
}

// https://github.com/boa-dev/boa/issues/4360
#[test]
fn try_into_js_to_string() {
use crate::JsObject;
use crate::js_string;

let mut context = Context::default();
let context = &mut context;

let obj = JsObject::default(context.intrinsics());
obj.create_data_property_or_throw(
js_string!("foo"),
TryIntoJs::try_into_js(&0usize, context).unwrap(),
context,
)
.unwrap();
obj.create_data_property_or_throw(
js_string!("bar"),
TryIntoJs::try_into_js(&1usize, context).unwrap(),
context,
)
.unwrap();
let value: JsValue = obj.into();
let s = value.to_string(context).unwrap();
assert_eq!(s.to_std_string_escaped(), "[object Object]");
}
}
9 changes: 9 additions & 0 deletions core/macros/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,15 @@ impl ClassVisitor {
Ok(())
}
}

impl boa_engine::value::TryIntoJs for #class_ty
where
Self: Clone,
{
fn try_into_js(&self, context: &mut boa_engine::Context) -> boa_engine::JsResult<boa_engine::JsValue> {
<Self as boa_engine::class::Class>::from_data(self.clone(), context).map(Into::into)
}
}
}
}
}
Expand Down
Loading