mirror of https://github.com/boa-dev/boa.git
Browse Source
<!--- Thank you for contributing to Boa! Please fill out the template below, and remove or add any information as you feel neccessary. ---> This Pull Request related to JsMap for #2098. Any feedback on implementing JsMapIterator would be welcome. I wasn't entirely sure if it was the right approach, but as I worked on the example file, it felt like something at least similar would be needed to use Map's .entries(), .keys(), and .values() methods. It changes the following: - Implements JsMap Wrapper - Implements JsMapIterator Wrapper - Creates JsMap example in boa_examplespull/2168/head
Kevin
2 years ago
5 changed files with 557 additions and 1 deletions
@ -0,0 +1,426 @@ |
|||||||
|
//! This module implements a wrapper for the Map Builtin Javascript Object
|
||||||
|
use crate::{ |
||||||
|
builtins::map::{add_entries_from_iterable, ordered_map::OrderedMap}, |
||||||
|
builtins::Map, |
||||||
|
object::{JsFunction, JsMapIterator, JsObject, JsObjectType, ObjectData}, |
||||||
|
Context, JsResult, JsValue, |
||||||
|
}; |
||||||
|
|
||||||
|
use boa_gc::{Finalize, Trace}; |
||||||
|
use std::ops::Deref; |
||||||
|
|
||||||
|
/// `JsMap` provides a wrapper for Boa's implementation of the Javascript `Map` object.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Create a `JsMap` and set a new entry
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// // Create default `Context`
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// // Create a new empty `JsMap`.
|
||||||
|
/// let map = JsMap::new(context);
|
||||||
|
///
|
||||||
|
/// // Set key-value pairs for the `JsMap`.
|
||||||
|
/// map.set("Key-1", "Value-1", context).unwrap();
|
||||||
|
/// map.set("Key-2", 10, context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(map.get_size(context).unwrap(), 2.into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Create a `JsMap` from a `JsArray`
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::{JsArray, JsMap},
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// // Create a default `Context`
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// // Create an array of two `[key, value]` pairs
|
||||||
|
/// let js_array = JsArray::new(context);
|
||||||
|
///
|
||||||
|
/// // Create a `[key, value]` pair of JsValues
|
||||||
|
/// let vec_one: Vec<JsValue> = vec![JsValue::new("first-key"), JsValue::new("first-value")];
|
||||||
|
///
|
||||||
|
/// // We create an push our `[key, value]` pair onto our array as a `JsArray`
|
||||||
|
/// js_array.push(JsArray::from_iter(vec_one, context), context).unwrap();
|
||||||
|
///
|
||||||
|
/// // Create a `JsMap` from the `JsArray` using it's iterable property.
|
||||||
|
/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(js_iterable_map.get("first-key", context).unwrap(), "first-value".into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone, Trace, Finalize)] |
||||||
|
pub struct JsMap { |
||||||
|
inner: JsObject, |
||||||
|
} |
||||||
|
|
||||||
|
impl JsMap { |
||||||
|
/// Creates a new empty [`JsMap`] object.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// // Create a new context.
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// // Create a new empty `JsMap`.
|
||||||
|
/// let map = JsMap::new(context);
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn new(context: &mut Context) -> Self { |
||||||
|
let map = Self::create_map(context); |
||||||
|
Self { inner: map } |
||||||
|
} |
||||||
|
|
||||||
|
/// Create a new [`JsMap`] object from a [`JsObject`] that has an `@@Iterator` field.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::{JsArray, JsMap},
|
||||||
|
/// # Context, JsResult, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// // Create a default `Context`
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// // Create an array of two `[key, value]` pairs
|
||||||
|
/// let js_array = JsArray::new(context);
|
||||||
|
///
|
||||||
|
/// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray`
|
||||||
|
/// let vec_one: Vec<JsValue> = vec![JsValue::new("first-key"), JsValue::new("first-value")];
|
||||||
|
/// js_array.push(JsArray::from_iter(vec_one, context), context).unwrap();
|
||||||
|
///
|
||||||
|
/// // Create a `JsMap` from the `JsArray` using it's iterable property.
|
||||||
|
/// let js_iterable_map = JsMap::from_js_iterable(&js_array.into(), context).unwrap();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
#[inline] |
||||||
|
pub fn from_js_iterable(iterable: &JsValue, context: &mut Context) -> JsResult<Self> { |
||||||
|
// Create a new map object.
|
||||||
|
let map = Self::create_map(context); |
||||||
|
|
||||||
|
// Let adder be Get(map, "set") per spec. This action should not fail with default map.
|
||||||
|
let adder = map |
||||||
|
.get("set", context) |
||||||
|
.expect("creating a map with the default prototype must not fail"); |
||||||
|
|
||||||
|
let _completion_record = add_entries_from_iterable(&map, iterable, &adder, context)?; |
||||||
|
|
||||||
|
Ok(Self { inner: map }) |
||||||
|
} |
||||||
|
|
||||||
|
/// Creates a [`JsMap`] from a valid [`JsObject`], or returns a `TypeError` if the provided object is not a [`JsMap`]
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Valid Example - returns a `JsMap` object
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # builtins::map::ordered_map::OrderedMap,
|
||||||
|
/// # object::{JsObject, ObjectData, JsMap},
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// // `some_object` can be any JavaScript `Map` object.
|
||||||
|
/// let some_object = JsObject::from_proto_and_data(
|
||||||
|
/// context.intrinsics().constructors().map().prototype(),
|
||||||
|
/// ObjectData::map(OrderedMap::new())
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// // Create `JsMap` object with incoming object.
|
||||||
|
/// let js_map = JsMap::from_object(some_object, context).unwrap();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Invalid Example - returns a `TypeError` with the message "object is not a Map"
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::{JsObject, JsArray, JsMap},
|
||||||
|
/// # Context, JsResult, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let some_object = JsArray::new(context);
|
||||||
|
///
|
||||||
|
/// // Some object is an Array object, not a map object
|
||||||
|
/// assert!(JsMap::from_object(some_object.into(), context).is_err());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn from_object(object: JsObject, context: &mut Context) -> JsResult<Self> { |
||||||
|
if object.borrow().is_map() { |
||||||
|
Ok(Self { inner: object }) |
||||||
|
} else { |
||||||
|
context.throw_type_error("object is not a Map") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Utility function to generate the default `Map` object.
|
||||||
|
fn create_map(context: &mut Context) -> JsObject { |
||||||
|
// Get default Map prototype
|
||||||
|
let prototype = context.intrinsics().constructors().map().prototype(); |
||||||
|
|
||||||
|
// Create a default map object with [[MapData]] as a new empty list
|
||||||
|
JsObject::from_proto_and_data(prototype, ObjectData::map(OrderedMap::new())) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns a new [`JsMapIterator`] object that yields the `[key, value]` pairs within the [`JsMap`] in insertion order.
|
||||||
|
#[inline] |
||||||
|
pub fn entries(&self, context: &mut Context) -> JsResult<JsMapIterator> { |
||||||
|
let iterator_record = Map::entries(&self.inner.clone().into(), &[], context)? |
||||||
|
.get_iterator(context, None, None)?; |
||||||
|
let map_iterator_object = iterator_record.iterator(); |
||||||
|
JsMapIterator::from_object(map_iterator_object.clone(), context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns a new [`JsMapIterator`] object that yields the `key` for each element within the [`JsMap`] in insertion order.
|
||||||
|
#[inline] |
||||||
|
pub fn keys(&self, context: &mut Context) -> JsResult<JsMapIterator> { |
||||||
|
let iterator_record = Map::keys(&self.inner.clone().into(), &[], context)? |
||||||
|
.get_iterator(context, None, None)?; |
||||||
|
let map_iterator_object = iterator_record.iterator(); |
||||||
|
JsMapIterator::from_object(map_iterator_object.clone(), context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Inserts a new entry into the [`JsMap`] object
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
///
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
/// js_map.set(2, 4, context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(js_map.get("foo", context).unwrap(), "bar".into());
|
||||||
|
/// assert_eq!(js_map.get(2, context).unwrap(), 4.into())
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn set<K, V>(&self, key: K, value: V, context: &mut Context) -> JsResult<JsValue> |
||||||
|
where |
||||||
|
K: Into<JsValue>, |
||||||
|
V: Into<JsValue>, |
||||||
|
{ |
||||||
|
Map::set( |
||||||
|
&self.inner.clone().into(), |
||||||
|
&[key.into(), value.into()], |
||||||
|
context, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
/// Gets the size of the [`JsMap`] object.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
///
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
///
|
||||||
|
/// let map_size = js_map.get_size(context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(map_size, 1.into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn get_size(&self, context: &mut Context) -> JsResult<JsValue> { |
||||||
|
Map::get_size(&self.inner.clone().into(), &[], context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Removes element from [`JsMap`] with a matching `key` value.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
/// js_map.set("hello", "world", context).unwrap();
|
||||||
|
///
|
||||||
|
/// js_map.delete("foo", context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(js_map.get_size(context).unwrap(), 1.into());
|
||||||
|
/// assert_eq!(js_map.get("foo", context).unwrap(), JsValue::undefined());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn delete<T>(&self, key: T, context: &mut Context) -> JsResult<JsValue> |
||||||
|
where |
||||||
|
T: Into<JsValue>, |
||||||
|
{ |
||||||
|
Map::delete(&self.inner.clone().into(), &[key.into()], context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Gets the value associated with the specified key within the [`JsMap`], or `undefined` if the key does not exist.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
///
|
||||||
|
/// let retrieved_value = js_map.get("foo", context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(retrieved_value, "bar".into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn get<T>(&self, key: T, context: &mut Context) -> JsResult<JsValue> |
||||||
|
where |
||||||
|
T: Into<JsValue>, |
||||||
|
{ |
||||||
|
Map::get(&self.inner.clone().into(), &[key.into()], context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Removes all entries from the [`JsMap`].
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
/// js_map.set("hello", "world", context).unwrap();
|
||||||
|
///
|
||||||
|
/// js_map.clear(context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(js_map.get_size(context).unwrap(), 0.into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn clear(&self, context: &mut Context) -> JsResult<JsValue> { |
||||||
|
Map::clear(&self.inner.clone().into(), &[], context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Checks if [`JsMap`] has an entry with the provided `key` value.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use boa_engine::{
|
||||||
|
/// # object::JsMap,
|
||||||
|
/// # Context, JsValue,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// let context = &mut Context::default();
|
||||||
|
///
|
||||||
|
/// let js_map = JsMap::new(context);
|
||||||
|
/// js_map.set("foo", "bar", context).unwrap();
|
||||||
|
///
|
||||||
|
/// let has_key = js_map.has("foo", context).unwrap();
|
||||||
|
///
|
||||||
|
/// assert_eq!(has_key, true.into());
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[inline] |
||||||
|
pub fn has<T>(&self, key: T, context: &mut Context) -> JsResult<JsValue> |
||||||
|
where |
||||||
|
T: Into<JsValue>, |
||||||
|
{ |
||||||
|
Map::has(&self.inner.clone().into(), &[key.into()], context) |
||||||
|
} |
||||||
|
|
||||||
|
/// Executes the provided callback function for each key-value pair within the [`JsMap`].
|
||||||
|
#[inline] |
||||||
|
pub fn for_each( |
||||||
|
&self, |
||||||
|
callback: JsFunction, |
||||||
|
this_arg: JsValue, |
||||||
|
context: &mut Context, |
||||||
|
) -> JsResult<JsValue> { |
||||||
|
Map::for_each( |
||||||
|
&self.inner.clone().into(), |
||||||
|
&[callback.into(), this_arg], |
||||||
|
context, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
/// Returns a new [`JsMapIterator`] object that yields the `value` for each element within the [`JsMap`] in insertion order.
|
||||||
|
#[inline] |
||||||
|
pub fn values(&self, context: &mut Context) -> JsResult<JsMapIterator> { |
||||||
|
let iterator_record = Map::values(&self.inner.clone().into(), &[], context)? |
||||||
|
.get_iterator(context, None, None)?; |
||||||
|
let map_iterator_object = iterator_record.iterator(); |
||||||
|
JsMapIterator::from_object(map_iterator_object.clone(), context) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<JsMap> for JsObject { |
||||||
|
#[inline] |
||||||
|
fn from(o: JsMap) -> Self { |
||||||
|
o.inner.clone() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<JsMap> for JsValue { |
||||||
|
#[inline] |
||||||
|
fn from(o: JsMap) -> Self { |
||||||
|
o.inner.clone().into() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Deref for JsMap { |
||||||
|
type Target = JsObject; |
||||||
|
|
||||||
|
#[inline] |
||||||
|
fn deref(&self) -> &Self::Target { |
||||||
|
&self.inner |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl JsObjectType for JsMap {} |
@ -0,0 +1,57 @@ |
|||||||
|
//! This module implements a wrapper for the `MapIterator` object
|
||||||
|
use crate::{ |
||||||
|
builtins::map::map_iterator::MapIterator, |
||||||
|
object::{JsObject, JsObjectType}, |
||||||
|
Context, JsResult, JsValue, |
||||||
|
}; |
||||||
|
|
||||||
|
use boa_gc::{Finalize, Trace}; |
||||||
|
use std::ops::Deref; |
||||||
|
|
||||||
|
/// JavaScript `MapIterator` rust object
|
||||||
|
#[derive(Debug, Clone, Finalize, Trace)] |
||||||
|
pub struct JsMapIterator { |
||||||
|
inner: JsObject, |
||||||
|
} |
||||||
|
|
||||||
|
impl JsMapIterator { |
||||||
|
/// Create a [`JsMapIterator`] from a [`JsObject`]. If object is not a `MapIterator`, throw `TypeError`
|
||||||
|
#[inline] |
||||||
|
pub fn from_object(object: JsObject, context: &mut Context) -> JsResult<Self> { |
||||||
|
if object.borrow().is_map_iterator() { |
||||||
|
Ok(Self { inner: object }) |
||||||
|
} else { |
||||||
|
context.throw_type_error("object is not a MapIterator") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Advances the `JsMapIterator` and gets the next result in the `JsMap`
|
||||||
|
pub fn next(&self, context: &mut Context) -> JsResult<JsValue> { |
||||||
|
MapIterator::next(&self.inner.clone().into(), &[], context) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<JsMapIterator> for JsObject { |
||||||
|
#[inline] |
||||||
|
fn from(o: JsMapIterator) -> Self { |
||||||
|
o.inner.clone() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<JsMapIterator> for JsValue { |
||||||
|
#[inline] |
||||||
|
fn from(o: JsMapIterator) -> Self { |
||||||
|
o.inner.clone().into() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Deref for JsMapIterator { |
||||||
|
type Target = JsObject; |
||||||
|
|
||||||
|
#[inline] |
||||||
|
fn deref(&self) -> &Self::Target { |
||||||
|
&self.inner |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl JsObjectType for JsMapIterator {} |
@ -0,0 +1,58 @@ |
|||||||
|
use boa_engine::{ |
||||||
|
object::{JsArray, JsMap}, |
||||||
|
Context, JsResult, JsValue, |
||||||
|
}; |
||||||
|
|
||||||
|
fn main() -> JsResult<()> { |
||||||
|
// Create a `Context` for the Javascript executor.
|
||||||
|
let context = &mut Context::default(); |
||||||
|
|
||||||
|
// Create a new empty map.
|
||||||
|
let map = JsMap::new(context); |
||||||
|
|
||||||
|
// Set a key-value for the map.
|
||||||
|
map.set("Key-1", "Value-1", context)?; |
||||||
|
|
||||||
|
let map_check = map.has("Key-1", context)?; |
||||||
|
assert_eq!(map_check, true.into()); // true
|
||||||
|
|
||||||
|
// Set a second key-value to the same map.
|
||||||
|
map.set(2, 4, context)?; |
||||||
|
|
||||||
|
assert_eq!(map.get_size(context)?, 2.into()); //true
|
||||||
|
|
||||||
|
assert_eq!(map.get("Key-1", context)?, "Value-1".into()); |
||||||
|
assert_eq!(map.get(2, context)?, 4.into()); |
||||||
|
// Delete an entry with a provided key.
|
||||||
|
map.delete("Key-1", context)?; |
||||||
|
assert_eq!(map.get_size(context)?, 1.into()); |
||||||
|
|
||||||
|
let deleted_key_one = map.get("Key-1", context)?; |
||||||
|
|
||||||
|
assert_eq!(deleted_key_one, JsValue::undefined()); |
||||||
|
|
||||||
|
// Retrieve a MapIterator for all entries in the Map.
|
||||||
|
let entries = map.entries(context)?; |
||||||
|
|
||||||
|
let _first_value = entries.next(context)?; |
||||||
|
|
||||||
|
// Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]]
|
||||||
|
let js_array = JsArray::new(context); |
||||||
|
|
||||||
|
let vec_one = vec![JsValue::new("first-key"), JsValue::new("first-value")]; |
||||||
|
let vec_two = vec![JsValue::new("second-key"), JsValue::new("second-value")]; |
||||||
|
|
||||||
|
js_array.push(JsArray::from_iter(vec_one, context), context)?; |
||||||
|
js_array.push(JsArray::from_iter(vec_two, context), context)?; |
||||||
|
|
||||||
|
// Create a map from the JsArray using it's iterable property.
|
||||||
|
let iter_map = JsMap::from_js_iterable(&js_array.into(), context)?; |
||||||
|
|
||||||
|
assert_eq!(iter_map.get("first-key", context)?, "first-value".into()); |
||||||
|
|
||||||
|
iter_map.set("third-key", "third-value", context)?; |
||||||
|
|
||||||
|
assert_eq!(iter_map.get_size(context)?, JsValue::new(3)); |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
Loading…
Reference in new issue