Browse Source

Add an "iter()" method to Js*Array for convenience (#3986)

* Allow dead code for code that is newly detected as unused

* Fix compile errors with nightly rust

* Add missing SAFETY section

* Increase safety of `FutexWaiters`

* Add an "iter()" method to Js*Array for convenience

It might be optimizable, and in either case it should be but this at
least let people use an easy API and enjoy future improvements.

* Fix clippies

---------

Co-authored-by: Theo Paris <theo@tinted.dev>
Co-authored-by: José Julián Espina <julian.espina@canonical.com>
pull/3994/head
Hans Larsen 2 months ago committed by GitHub
parent
commit
cdb47510b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 56
      core/engine/src/object/builtins/jstypedarray.rs
  2. 5
      core/engine/src/value/mod.rs

56
core/engine/src/object/builtins/jstypedarray.rs

@ -542,7 +542,7 @@ impl JsTypedArray {
/// Iterates the typed array in reverse order and returns the value of /// Iterates the typed array in reverse order and returns the value of
/// the first element that satisfies the provided testing function. /// the first element that satisfies the provided testing function.
/// If no elements satisfy the testing function, `JsResult::Ok(None)` is returned. /// If no elements satisfy the testing function, `JsResult::Ok(None)` is returned.
/// ///
/// Calls `TypedArray.prototype.findLast()`. /// Calls `TypedArray.prototype.findLast()`.
/// ///
@ -927,6 +927,7 @@ macro_rules! JsTypedArrayType {
$constructor_function:ident, $constructor_function:ident,
$checker_function:ident, $checker_function:ident,
$constructor_object:ident, $constructor_object:ident,
$value_to_elem:ident,
$element:ty $element:ty
) => { ) => {
@ -1017,6 +1018,21 @@ macro_rules! JsTypedArrayType {
}, },
}) })
} }
/// Create an iterator over the typed array's elements.
pub fn iter<'a>(&'a self, context: &'a mut Context) -> impl Iterator<Item = $element> + 'a {
let length = self.length(context).unwrap_or(0);
let mut index = 0;
std::iter::from_fn(move || {
if index < length {
let value = self.get(index, context).ok()?;
index += 1;
value.$value_to_elem(context).ok()
} else {
None
}
})
}
} }
impl From<$name> for JsObject { impl From<$name> for JsObject {
@ -1066,6 +1082,7 @@ JsTypedArrayType!(
Uint8Array, Uint8Array,
is_typed_uint8_array, is_typed_uint8_array,
typed_uint8_array, typed_uint8_array,
to_uint8,
u8 u8
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1073,6 +1090,7 @@ JsTypedArrayType!(
Int8Array, Int8Array,
is_typed_int8_array, is_typed_int8_array,
typed_int8_array, typed_int8_array,
to_int8,
i8 i8
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1080,6 +1098,7 @@ JsTypedArrayType!(
Uint16Array, Uint16Array,
is_typed_uint16_array, is_typed_uint16_array,
typed_uint16_array, typed_uint16_array,
to_uint16,
u16 u16
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1087,6 +1106,7 @@ JsTypedArrayType!(
Int16Array, Int16Array,
is_typed_int16_array, is_typed_int16_array,
typed_int16_array, typed_int16_array,
to_int16,
i16 i16
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1094,6 +1114,7 @@ JsTypedArrayType!(
Uint32Array, Uint32Array,
is_typed_uint32_array, is_typed_uint32_array,
typed_uint32_array, typed_uint32_array,
to_u32,
u32 u32
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1101,6 +1122,7 @@ JsTypedArrayType!(
Int32Array, Int32Array,
is_typed_int32_array, is_typed_int32_array,
typed_int32_array, typed_int32_array,
to_i32,
i32 i32
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1108,6 +1130,7 @@ JsTypedArrayType!(
Float32Array, Float32Array,
is_typed_float32_array, is_typed_float32_array,
typed_float32_array, typed_float32_array,
to_f32,
f32 f32
); );
JsTypedArrayType!( JsTypedArrayType!(
@ -1115,5 +1138,36 @@ JsTypedArrayType!(
Float64Array, Float64Array,
is_typed_float64_array, is_typed_float64_array,
typed_float64_array, typed_float64_array,
to_number,
f64 f64
); );
#[test]
fn typed_iterators_uint8() {
let context = &mut Context::default();
let vec = vec![1u8, 2, 3, 4, 5, 6, 7, 8];
let array = JsUint8Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}
#[test]
fn typed_iterators_uint32() {
let context = &mut Context::default();
let vec = vec![1u32, 2, 0xFFFF, 4, 0xFF12_3456, 6, 7, 8];
let array = JsUint32Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}
#[test]
fn typed_iterators_f32() {
let context = &mut Context::default();
let vec = vec![0.1f32, 0.2, 0.3, 0.4, 1.1, 9.99999];
let array = JsFloat32Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}

5
core/engine/src/value/mod.rs

@ -927,6 +927,11 @@ impl JsValue {
} }
} }
/// Converts a value to a 32 bit floating point.
pub fn to_f32(&self, context: &mut Context) -> JsResult<f32> {
self.to_number(context).map(|n| n as f32)
}
/// This is a more specialized version of `to_numeric`, including `BigInt`. /// This is a more specialized version of `to_numeric`, including `BigInt`.
/// ///
/// This function is equivalent to `Number(value)` in JavaScript /// This function is equivalent to `Number(value)` in JavaScript

Loading…
Cancel
Save