1use super::*;
4
5pub(crate) fn arr_at(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
7 let items = generic_array_items(it, &t);
8 let n = arg(a, 0).to_number() as i64;
9 let len = items.len() as i64;
10 let idx = if n < 0 { len + n } else { n };
11 if idx >= 0 && idx < len {
12 Ok(items[idx as usize].clone())
13 } else {
14 Ok(Value::Undefined)
15 }
16}
17pub(crate) fn arr_find_last(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
18 let items = generic_array_items(it, &t);
19 let f = arg(a, 0);
20 let this_arg = arg(a, 1);
21 for i in (0..items.len()).rev() {
22 if it
23 .call_value(
24 &f,
25 this_arg.clone(),
26 &[items[i].clone(), Value::Number(i as f64), t.clone()],
27 )?
28 .truthy()
29 {
30 return Ok(items[i].clone());
31 }
32 }
33 Ok(Value::Undefined)
34}
35pub(crate) fn arr_find_last_index(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
36 let items = generic_array_items(it, &t);
37 let f = arg(a, 0);
38 let this_arg = arg(a, 1);
39 for i in (0..items.len()).rev() {
40 if it
41 .call_value(
42 &f,
43 this_arg.clone(),
44 &[items[i].clone(), Value::Number(i as f64), t.clone()],
45 )?
46 .truthy()
47 {
48 return Ok(Value::Number(i as f64));
49 }
50 }
51 Ok(Value::Number(-1.0))
52}
53pub(crate) fn arr_flat_map(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
54 let items = generic_array_items(it, &t);
55 let f = arg(a, 0);
56 let this_arg = arg(a, 1);
57 let mut out: Vec<Value> = Vec::new();
58 for (i, v) in items.iter().enumerate() {
59 let r = it.call_value(
60 &f,
61 this_arg.clone(),
62 &[v.clone(), Value::Number(i as f64), t.clone()],
63 )?;
64 let inner = if let Value::Object(o) = &r {
65 if let ObjKind::Array(items) = &o.borrow().kind {
66 Some(items.clone())
67 } else {
68 None
69 }
70 } else {
71 None
72 };
73 match inner {
74 Some(arr) => out.extend(arr),
75 None => out.push(r),
76 }
77 }
78 let a_obj = array_species_create(it, &t, 0)?;
79 populate_array_species(it, &a_obj, out)
80}
81pub fn make_iterator(items: Vec<Value>) -> super::super::value::ObjRef {
89 let o = Obj::host("iterator");
90 o.borrow_mut().props.insert("_items".into(), Value::Object(Obj::array(items)));
91 o.borrow_mut().props.insert("_pos".into(), Value::Number(0.0));
92 o
93}
94pub fn iterator_next(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
95 if let Value::Object(o) = &this {
96 let items = o.borrow().props.get("_items").cloned();
97 let pos = o
98 .borrow()
99 .props
100 .get("_pos")
101 .map(|v| v.to_number() as usize)
102 .unwrap_or(0);
103 if let Some(Value::Object(arr)) = items {
104 let item = if let ObjKind::Array(v) = &arr.borrow().kind {
105 v.get(pos).cloned()
106 } else {
107 None
108 };
109 if let Some(value) = item {
110 o.borrow_mut().props.insert("_pos".into(), Value::Number((pos + 1) as f64));
111 return Ok(iter_result(value, false));
112 }
113 }
114 }
115 Ok(iter_result(Value::Undefined, true))
116}
117pub fn iterator_self(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
118 Ok(this)
119}
120pub(crate) fn iterator_remaining(this: &Value) -> Vec<Value> {
127 if let Value::Object(o) = this {
128 let items = o.borrow().props.get("_items").cloned();
129 let pos = o
130 .borrow()
131 .props
132 .get("_pos")
133 .map(|v| v.to_number() as usize)
134 .unwrap_or(0);
135 if let Some(Value::Object(arr)) = items {
136 let rest: Option<Vec<Value>> = if let ObjKind::Array(v) = &arr.borrow().kind {
137 Some(v.iter().skip(pos).cloned().collect())
138 } else {
139 None
140 };
141 if let Some(rest) = rest {
142 let len = if let ObjKind::Array(v) = &arr.borrow().kind { v.len() } else { pos };
143 o.borrow_mut().props.insert("_pos".into(), Value::Number(len as f64));
144 return rest;
145 }
146 }
147 }
148 Vec::new()
149}
150pub fn iterator_map(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
152 let cb = arg(a, 0);
153 let items = iterator_remaining(&this);
154 let mut out = Vec::with_capacity(items.len());
155 for (i, v) in items.into_iter().enumerate() {
156 out.push(it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?);
157 }
158 Ok(Value::Object(make_iterator(out)))
159}
160pub fn iterator_filter(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
162 let cb = arg(a, 0);
163 let items = iterator_remaining(&this);
164 let mut out = Vec::new();
165 for (i, v) in items.into_iter().enumerate() {
166 let keep = it.call_value(&cb, Value::Undefined, &[v.clone(), Value::Number(i as f64)])?;
167 if keep.truthy() {
168 out.push(v);
169 }
170 }
171 Ok(Value::Object(make_iterator(out)))
172}
173pub fn iterator_take(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
175 let n = arg(a, 0).to_number();
176 let n = if n.is_finite() && n > 0.0 { n as usize } else { 0 };
177 let items = iterator_remaining(&this);
178 Ok(Value::Object(make_iterator(items.into_iter().take(n).collect())))
179}
180pub fn iterator_drop(_it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
182 let n = arg(a, 0).to_number();
183 let n = if n.is_finite() && n > 0.0 { n as usize } else { 0 };
184 let items = iterator_remaining(&this);
185 Ok(Value::Object(make_iterator(items.into_iter().skip(n).collect())))
186}
187pub fn iterator_to_array(_it: &mut Interp, this: Value, _a: &[Value]) -> Result<Value, Value> {
189 Ok(Value::Object(Obj::array(iterator_remaining(&this))))
190}
191pub fn iterator_for_each(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
193 let cb = arg(a, 0);
194 let items = iterator_remaining(&this);
195 for (i, v) in items.into_iter().enumerate() {
196 it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
197 }
198 Ok(Value::Undefined)
199}
200pub fn iterator_flat_map(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
206 let cb = arg(a, 0);
207 let items = iterator_remaining(&this);
208 let mut out = Vec::new();
209 for (i, v) in items.into_iter().enumerate() {
210 let mapped = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
211 out.extend(it.iter_to_vec(&mapped));
212 }
213 Ok(Value::Object(make_iterator(out)))
214}
215pub fn iterator_some(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
220 let cb = arg(a, 0);
221 let items = iterator_remaining(&this);
222 for (i, v) in items.into_iter().enumerate() {
223 let r = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
224 if r.truthy() {
225 return Ok(Value::Bool(true));
226 }
227 }
228 Ok(Value::Bool(false))
229}
230pub fn iterator_every(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
231 let cb = arg(a, 0);
232 let items = iterator_remaining(&this);
233 for (i, v) in items.into_iter().enumerate() {
234 let r = it.call_value(&cb, Value::Undefined, &[v, Value::Number(i as f64)])?;
235 if !r.truthy() {
236 return Ok(Value::Bool(false));
237 }
238 }
239 Ok(Value::Bool(true))
240}
241pub fn iterator_find(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
242 let cb = arg(a, 0);
243 let items = iterator_remaining(&this);
244 for (i, v) in items.into_iter().enumerate() {
245 let r = it.call_value(&cb, Value::Undefined, &[v.clone(), Value::Number(i as f64)])?;
246 if r.truthy() {
247 return Ok(v);
248 }
249 }
250 Ok(Value::Undefined)
251}
252pub fn iterator_reduce(it: &mut Interp, this: Value, a: &[Value]) -> Result<Value, Value> {
254 let cb = arg(a, 0);
255 let items = iterator_remaining(&this);
256 let mut iter = items.into_iter().enumerate();
257 let mut acc = if a.len() > 1 {
258 arg(a, 1)
259 } else {
260 match iter.next() {
261 Some((_, v)) => v,
262 None => return Err(it.error("Reduce of empty iterator with no initial value")),
263 }
264 };
265 for (i, v) in iter {
266 acc = it.call_value(&cb, Value::Undefined, &[acc, v, Value::Number(i as f64)])?;
267 }
268 Ok(acc)
269}
270pub(crate) fn arr_entries(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
271 let out: Vec<Value> = generic_array_items(it, &t)
272 .into_iter()
273 .enumerate()
274 .map(|(i, v)| Value::Object(Obj::array(alloc::vec![Value::Number(i as f64), v])))
275 .collect();
276 Ok(Value::Object(make_iterator(out)))
277}
278pub(crate) fn arr_keys(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
279 let n = generic_array_items(it, &t).len();
280 Ok(Value::Object(make_iterator(
281 (0..n).map(|i| Value::Number(i as f64)).collect(),
282 )))
283}
284pub(crate) fn arr_values(it: &mut Interp, t: Value, _a: &[Value]) -> Result<Value, Value> {
285 let items = generic_array_items(it, &t);
286 Ok(Value::Object(make_iterator(items)))
287}
288pub(crate) fn arr_reduce_right(it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
289 let items = generic_array_items(it, &t);
290 let f = arg(a, 0);
291 let (mut acc, start) = if a.len() > 1 {
292 (arg(a, 1), items.len())
293 } else if items.is_empty() {
294 return Err(it.error("Reduce of empty array with no initial value"));
295 } else {
296 (items[items.len() - 1].clone(), items.len() - 1)
297 };
298 let holes = super::props_methods::holes_of(&t);
299 for i in (0..start).rev() {
300 if holes.get(i).copied().unwrap_or(false) {
301 continue;
302 }
303 acc = it.call_value(
304 &f,
305 Value::Undefined,
306 &[acc, items[i].clone(), Value::Number(i as f64), t.clone()],
307 )?;
308 }
309 Ok(acc)
310}
311
312pub(crate) fn str_at(_it: &mut Interp, t: Value, a: &[Value]) -> Result<Value, Value> {
314 let chars: Vec<char> = this_str(&t).chars().collect();
315 let n = arg(a, 0).to_number() as i64;
316 let len = chars.len() as i64;
317 let idx = if n < 0 { len + n } else { n };
318 if idx >= 0 && idx < len {
319 Ok(Value::str(chars[idx as usize].to_string()))
320 } else {
321 Ok(Value::Undefined)
322 }
323}
324
325pub(crate) fn resolve_maybe_thenable(
333 it: &mut Interp,
334 item: &Value,
335) -> Option<PromiseRc<PromiseRefCell<PromiseState>>> {
336 if let Some(s) = this_promise_state(item) {
337 return Some(s);
338 }
339 let then_fn = if matches!(item, Value::Object(_)) {
344 it.get_property(item, "then").unwrap_or(Value::Undefined)
345 } else {
346 Value::Undefined
347 };
348 let has_then = matches!(&then_fn, Value::Object(f) if f.borrow().is_callable());
349 if has_then {
350 let s = new_pending();
351 it.promise_resolve(&s, item.clone());
352 Some(s)
353 } else {
354 None
355 }
356}
357pub(crate) fn promise_all_settled_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
358 let items = it.iter_to_vec(&arg(a, 0));
359 let result = new_pending();
360 it.run_microtasks();
361 let mut out: Vec<Value> = Vec::new();
362 for item in items {
363 let o = Obj::plain();
364 {
365 let mut b = o.borrow_mut();
366 match resolve_maybe_thenable(it, &item) {
367 Some(s) => {
368 let st = s.borrow();
369 match st.status {
370 PromiseStatus::Rejected => {
371 b.props.insert("status".into(), Value::str("rejected"));
372 b.props.insert("reason".into(), st.value.clone());
373 }
374 _ => {
375 b.props.insert("status".into(), Value::str("fulfilled"));
376 b.props.insert("value".into(), st.value.clone());
377 }
378 }
379 }
380 None => {
381 b.props.insert("status".into(), Value::str("fulfilled"));
382 b.props.insert("value".into(), item.clone());
383 }
384 }
385 }
386 out.push(Value::Object(o));
387 }
388 it.promise_resolve(&result, Value::Object(Obj::array(out)));
389 Ok(Value::Object(Obj::promise(result)))
390}
391pub(crate) fn promise_race_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
392 let items = it.iter_to_vec(&arg(a, 0));
393 let result = new_pending();
394 it.run_microtasks();
395 for item in items {
396 match resolve_maybe_thenable(it, &item) {
397 Some(s) => {
398 let (status, val) = {
399 let b = s.borrow();
400 (b.status, b.value.clone())
401 };
402 match status {
403 PromiseStatus::Fulfilled => {
404 it.promise_resolve(&result, val);
405 return Ok(Value::Object(Obj::promise(result)));
406 }
407 PromiseStatus::Rejected => {
408 it.promise_reject(&result, val);
409 return Ok(Value::Object(Obj::promise(result)));
410 }
411 PromiseStatus::Pending => {}
412 }
413 }
414 None => {
415 it.promise_resolve(&result, item.clone());
416 return Ok(Value::Object(Obj::promise(result)));
417 }
418 }
419 }
420 Ok(Value::Object(Obj::promise(result)))
421}
422pub(crate) fn promise_any_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
427 let items = it.iter_to_vec(&arg(a, 0));
428 let result = new_pending();
429 it.run_microtasks();
430 let mut reasons: Vec<Value> = Vec::new();
431 for item in items {
432 match resolve_maybe_thenable(it, &item) {
433 Some(s) => {
434 let (status, val) = {
435 let b = s.borrow();
436 (b.status, b.value.clone())
437 };
438 match status {
439 PromiseStatus::Fulfilled => {
440 it.promise_resolve(&result, val);
441 return Ok(Value::Object(Obj::promise(result)));
442 }
443 PromiseStatus::Rejected => {
444 reasons.push(val);
445 }
446 PromiseStatus::Pending => {}
447 }
448 }
449 None => {
450 it.promise_resolve(&result, item.clone());
451 return Ok(Value::Object(Obj::promise(result)));
452 }
453 }
454 }
455 let agg = make_aggregate_error(it, reasons, "All promises were rejected");
456 it.promise_reject(&result, agg);
457 Ok(Value::Object(Obj::promise(result)))
458}
459
460pub fn iterator_concat_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
463 let mut combined = Vec::new();
464 for arg_val in a {
465 let items = it.iter_to_vec(arg_val);
466 combined.extend(items);
467 }
468 Ok(Value::Object(make_iterator(combined)))
469}
470
471pub fn iterator_from_static(it: &mut Interp, _t: Value, a: &[Value]) -> Result<Value, Value> {
474 let source = arg(a, 0);
475 let items = it.iter_to_vec(&source);
476 Ok(Value::Object(make_iterator(items)))
477}