Skip to main content

boa_engine/value/conversions/try_from_js/
tuples.rs

1//! Implementation of [`TryFromJs`] for tuples.
2//!
3//! Tuples are converted from a JavaScript array, using similar semantics to `TypeScript` tuples:
4//!     - If the tuple is shorter than the array, the extra elements are ignored.
5//!     - If the tuple is longer than the array, the extra elements are `undefined`.
6//!     - If the array is empty, all elements are `undefined`.
7//!
8//! A tuple of size 0 (unit type) does not implement [`TryFromJs`].
9
10use crate::value::JsValue;
11use crate::{Context, JsResult};
12
13use super::TryFromJs;
14
15macro_rules! impl_try_from_js_for_tuples {
16    ($($name:ident),*) => {
17        impl<$($name: TryFromJs),*> TryFromJs for ($($name,)*) {
18            fn try_from_js(value: &JsValue, context: &mut Context) -> JsResult<Self> {
19                let vec: Vec<JsValue> = value.try_js_into(context)?;
20                let mut iter = vec.into_iter();
21
22                Ok((
23                    $(
24                        $name::try_from_js(&iter.next().unwrap_or_else(JsValue::undefined), context)?,
25                    )*
26                ))
27            }
28        }
29    };
30}
31
32impl_try_from_js_for_tuples!(A);
33impl_try_from_js_for_tuples!(A, B);
34impl_try_from_js_for_tuples!(A, B, C);
35impl_try_from_js_for_tuples!(A, B, C, D);
36impl_try_from_js_for_tuples!(A, B, C, D, E);
37impl_try_from_js_for_tuples!(A, B, C, D, E, F);
38impl_try_from_js_for_tuples!(A, B, C, D, E, F, G);
39impl_try_from_js_for_tuples!(A, B, C, D, E, F, G, H);
40impl_try_from_js_for_tuples!(A, B, C, D, E, F, G, H, I);
41impl_try_from_js_for_tuples!(A, B, C, D, E, F, G, H, I, J);