csml_interpreter/data/primitive/
array.rs

1use crate::data::position::Position;
2use crate::data::{
3    data::{init_child_context, init_child_scope, Data},
4    literal,
5    literal::ContentType,
6    primitive::{
7        Primitive, PrimitiveBoolean, PrimitiveClosure, PrimitiveInt, PrimitiveNull,
8        PrimitiveString, PrimitiveType, Right,
9    },
10    tokens::TYPES,
11    ArgsType, Interval, Literal, MemoryType, Message, MessageData, MSG,
12};
13use crate::error_format::*;
14use crate::interpreter::variable_handler::resolve_csml_object::{
15    exec_closure, insert_args_in_scope_memory, insert_memories_in_scope_memory,
16};
17use phf::phf_map;
18use rand::seq::SliceRandom;
19use rand::Rng;
20use serde::{Deserialize, Serialize};
21use serde_json::json;
22use std::cmp::Ordering;
23use std::usize;
24use std::{collections::HashMap, sync::mpsc};
25
26////////////////////////////////////////////////////////////////////////////////
27// DATA STRUCTURES
28////////////////////////////////////////////////////////////////////////////////
29
30type PrimitiveMethod = fn(
31    array: &mut PrimitiveArray,
32    args: &HashMap<String, Literal>,
33    additional_info: &Option<HashMap<String, Literal>>,
34    interval: Interval,
35    data: &mut Data,
36    msg_data: &mut MessageData,
37    sender: &Option<mpsc::Sender<MSG>>,
38) -> Result<Literal, ErrorInfo>;
39
40const FUNCTIONS: phf::Map<&'static str, (PrimitiveMethod, Right)> = phf_map! {
41    "is_number" => (PrimitiveArray::is_number as PrimitiveMethod, Right::Read),
42    "is_int" => (PrimitiveArray::is_int as PrimitiveMethod, Right::Read),
43    "is_float" => (PrimitiveArray::is_float as PrimitiveMethod, Right::Read),
44    "type_of" => (PrimitiveArray::type_of as PrimitiveMethod, Right::Read),
45    "get_info" => (PrimitiveArray::get_info as PrimitiveMethod, Right::Read),
46    "is_error" => (PrimitiveArray::is_error as PrimitiveMethod, Right::Read),
47    "to_string" => (PrimitiveArray::to_string as PrimitiveMethod, Right::Read),
48
49    "init" => (PrimitiveArray::init as PrimitiveMethod, Right::Read),
50    "find" => (PrimitiveArray::find as PrimitiveMethod, Right::Read),
51    "is_empty" => (PrimitiveArray::is_empty as PrimitiveMethod, Right::Read),
52    "insert_at" => (PrimitiveArray::insert_at as PrimitiveMethod, Right::Write),
53    "index_of" => (PrimitiveArray::index_of as PrimitiveMethod, Right::Read),
54    "join" => (PrimitiveArray::join as PrimitiveMethod, Right::Read),
55    "length" => (PrimitiveArray::length as PrimitiveMethod, Right::Read),
56    "one_of" => (PrimitiveArray::one_of as PrimitiveMethod, Right::Read),
57    "push" => (PrimitiveArray::push as PrimitiveMethod, Right::Write),
58    "pop" => (PrimitiveArray::pop as PrimitiveMethod, Right::Write),
59    "remove_at" => (PrimitiveArray::remove_at as PrimitiveMethod, Right::Write),
60    "slice" => (PrimitiveArray::slice as PrimitiveMethod, Right::Read),
61    "shuffle" => (PrimitiveArray::shuffle as PrimitiveMethod, Right::Write),
62    "map" => (PrimitiveArray::map as PrimitiveMethod, Right::Read),
63    "filter" => (PrimitiveArray::filter as PrimitiveMethod, Right::Read),
64    "reduce" => (PrimitiveArray::reduce as PrimitiveMethod, Right::Read),
65    "reverse" => (PrimitiveArray::reverse as PrimitiveMethod, Right::Read),
66    "append" => (PrimitiveArray::append as PrimitiveMethod, Right::Read),
67    "flatten" => (PrimitiveArray::flatten as PrimitiveMethod, Right::Read),
68};
69
70#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
71pub struct PrimitiveArray {
72    pub value: Vec<Literal>,
73}
74
75////////////////////////////////////////////////////////////////////////////////
76// METHOD FUNCTIONS
77////////////////////////////////////////////////////////////////////////////////
78
79fn check_index(
80    index: i64,
81    length: i64,
82    flow_name: &str,
83    interval: Interval,
84) -> Result<(), ErrorInfo> {
85    if index.is_negative() {
86        return Err(gen_error_info(
87            Position::new(interval, flow_name),
88            ERROR_ARRAY_NEGATIVE.to_owned(),
89        ));
90    }
91
92    if index > length {
93        return Err(gen_error_info(
94            Position::new(interval, flow_name),
95            ERROR_ARRAY_INDEX.to_owned(),
96        ));
97    }
98
99    Ok(())
100}
101
102impl PrimitiveArray {
103    fn is_number(
104        _array: &mut PrimitiveArray,
105        args: &HashMap<String, Literal>,
106        _additional_info: &Option<HashMap<String, Literal>>,
107        interval: Interval,
108        data: &mut Data,
109        _msg_data: &mut MessageData,
110        _sender: &Option<mpsc::Sender<MSG>>,
111    ) -> Result<Literal, ErrorInfo> {
112        let usage = "is_number() => boolean";
113
114        if !args.is_empty() {
115            return Err(gen_error_info(
116                Position::new(interval, &data.context.flow),
117                format!("usage: {}", usage),
118            ));
119        }
120
121        Ok(PrimitiveBoolean::get_literal(false, interval))
122    }
123
124    fn is_int(
125        _array: &mut PrimitiveArray,
126        args: &HashMap<String, Literal>,
127        _additional_info: &Option<HashMap<String, Literal>>,
128        interval: Interval,
129        data: &mut Data,
130        _msg_data: &mut MessageData,
131        _sender: &Option<mpsc::Sender<MSG>>,
132    ) -> Result<Literal, ErrorInfo> {
133        let usage = "is_int() => boolean";
134
135        if !args.is_empty() {
136            return Err(gen_error_info(
137                Position::new(interval, &data.context.flow),
138                format!("usage: {}", usage),
139            ));
140        }
141
142        Ok(PrimitiveBoolean::get_literal(false, interval))
143    }
144
145    fn is_float(
146        _array: &mut PrimitiveArray,
147        args: &HashMap<String, Literal>,
148        _additional_info: &Option<HashMap<String, Literal>>,
149        interval: Interval,
150        data: &mut Data,
151        _msg_data: &mut MessageData,
152        _sender: &Option<mpsc::Sender<MSG>>,
153    ) -> Result<Literal, ErrorInfo> {
154        let usage = "is_float() => boolean";
155
156        if !args.is_empty() {
157            return Err(gen_error_info(
158                Position::new(interval, &data.context.flow),
159                format!("usage: {}", usage),
160            ));
161        }
162
163        Ok(PrimitiveBoolean::get_literal(false, interval))
164    }
165
166    fn type_of(
167        _array: &mut PrimitiveArray,
168        args: &HashMap<String, Literal>,
169        _additional_info: &Option<HashMap<String, Literal>>,
170        interval: Interval,
171        data: &mut Data,
172        _msg_data: &mut MessageData,
173        _sender: &Option<mpsc::Sender<MSG>>,
174    ) -> Result<Literal, ErrorInfo> {
175        let usage = "type_of() => string";
176
177        if !args.is_empty() {
178            return Err(gen_error_info(
179                Position::new(interval, &data.context.flow),
180                format!("usage: {}", usage),
181            ));
182        }
183
184        Ok(PrimitiveString::get_literal("array", interval))
185    }
186
187    fn get_info(
188        _array: &mut PrimitiveArray,
189        args: &HashMap<String, Literal>,
190        additional_info: &Option<HashMap<String, Literal>>,
191        interval: Interval,
192        data: &mut Data,
193        _msg_data: &mut MessageData,
194        _sender: &Option<mpsc::Sender<MSG>>,
195    ) -> Result<Literal, ErrorInfo> {
196        literal::get_info(args, additional_info, interval, data)
197    }
198
199    fn is_error(
200        _array: &mut PrimitiveArray,
201        _args: &HashMap<String, Literal>,
202        additional_info: &Option<HashMap<String, Literal>>,
203        interval: Interval,
204        _data: &mut Data,
205        _msg_data: &mut MessageData,
206        _sender: &Option<mpsc::Sender<MSG>>,
207    ) -> Result<Literal, ErrorInfo> {
208        match additional_info {
209            Some(map) if map.contains_key("error") => {
210                Ok(PrimitiveBoolean::get_literal(true, interval))
211            }
212            _ => Ok(PrimitiveBoolean::get_literal(false, interval)),
213        }
214    }
215
216    fn to_string(
217        array: &mut PrimitiveArray,
218        args: &HashMap<String, Literal>,
219        _additional_info: &Option<HashMap<String, Literal>>,
220        interval: Interval,
221        data: &mut Data,
222        _msg_data: &mut MessageData,
223        _sender: &Option<mpsc::Sender<MSG>>,
224    ) -> Result<Literal, ErrorInfo> {
225        let usage = "to_string() => string";
226
227        if !args.is_empty() {
228            return Err(gen_error_info(
229                Position::new(interval, &data.context.flow),
230                format!("usage: {}", usage),
231            ));
232        }
233
234        Ok(PrimitiveString::get_literal(&array.to_string(), interval))
235    }
236}
237
238impl PrimitiveArray {
239    fn init(
240        _array: &mut PrimitiveArray,
241        args: &HashMap<String, Literal>,
242        _additional_info: &Option<HashMap<String, Literal>>,
243        interval: Interval,
244        data: &mut Data,
245        _msg_data: &mut MessageData,
246        _sender: &Option<mpsc::Sender<MSG>>,
247    ) -> Result<Literal, ErrorInfo> {
248        let usage = "init(capacity: Int) => [Literal]";
249
250        if args.len() != 1 {
251            return Err(gen_error_info(
252                Position::new(interval, &data.context.flow),
253                format!("usage: {}", usage),
254            ));
255        }
256
257        let capacity = match args.get("arg0") {
258            Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
259                *Literal::get_value::<i64>(
260                    &res.primitive,
261                    &data.context.flow,
262                    interval,
263                    ERROR_ARRAY_INSERT_AT.to_owned(),
264                )? as usize
265            }
266            _ => {
267                return Err(gen_error_info(
268                    Position::new(interval, &data.context.flow),
269                    ERROR_ARRAY_INSERT_AT.to_owned(),
270                ));
271            }
272        };
273
274        let mut vec = Vec::with_capacity(capacity);
275        for _ in 0..capacity {
276            vec.push(PrimitiveNull::get_literal(interval));
277        }
278
279        Ok(PrimitiveArray::get_literal(&vec, interval))
280    }
281
282    fn find(
283        array: &mut PrimitiveArray,
284        args: &HashMap<String, Literal>,
285        _additional_info: &Option<HashMap<String, Literal>>,
286        interval: Interval,
287        data: &mut Data,
288        _msg_data: &mut MessageData,
289        _sender: &Option<mpsc::Sender<MSG>>,
290    ) -> Result<Literal, ErrorInfo> {
291        let usage = "find(value: primitive) => array";
292
293        if array.value.len() + args.len() == usize::MAX {
294            return Err(gen_error_info(
295                Position::new(interval, &data.context.flow),
296                format!("{} {}", ERROR_ARRAY_OVERFLOW, usize::MAX),
297            ));
298        }
299
300        let value = match args.get("arg0") {
301            Some(res) => res,
302            _ => {
303                return Err(gen_error_info(
304                    Position::new(interval, &data.context.flow),
305                    format!("usage: {}", usage),
306                ));
307            }
308        };
309
310        let mut vector = Vec::new();
311
312        for literal in array.value.iter() {
313            if literal == value {
314                vector.push(literal.to_owned());
315            }
316        }
317
318        if !vector.is_empty() {
319            return Ok(PrimitiveArray::get_literal(&vector, interval));
320        }
321
322        Ok(PrimitiveArray::get_literal(&[], interval))
323    }
324
325    fn is_empty(
326        array: &mut PrimitiveArray,
327        args: &HashMap<String, Literal>,
328        _additional_info: &Option<HashMap<String, Literal>>,
329        interval: Interval,
330        data: &mut Data,
331        _msg_data: &mut MessageData,
332        _sender: &Option<mpsc::Sender<MSG>>,
333    ) -> Result<Literal, ErrorInfo> {
334        let usage = "is_empty() => boolean";
335
336        if !args.is_empty() {
337            return Err(gen_error_info(
338                Position::new(interval, &data.context.flow),
339                format!("usage: {}", usage),
340            ));
341        }
342
343        let result = array.value.is_empty();
344
345        Ok(PrimitiveBoolean::get_literal(result, interval))
346    }
347
348    fn insert_at(
349        array: &mut PrimitiveArray,
350        args: &HashMap<String, Literal>,
351        _additional_info: &Option<HashMap<String, Literal>>,
352        interval: Interval,
353        data: &mut Data,
354        _msg_data: &mut MessageData,
355        _sender: &Option<mpsc::Sender<MSG>>,
356    ) -> Result<Literal, ErrorInfo> {
357        let usage = "insert_at(index: int, value: primitive) => null";
358
359        if args.len() != 2 {
360            return Err(gen_error_info(
361                Position::new(interval, &data.context.flow),
362                format!("usage: {}", usage),
363            ));
364        }
365
366        let index = match args.get("arg0") {
367            Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
368                Literal::get_value::<i64>(
369                    &res.primitive,
370                    &data.context.flow,
371                    interval,
372                    ERROR_ARRAY_INSERT_AT.to_owned(),
373                )?
374            }
375            _ => {
376                return Err(gen_error_info(
377                    Position::new(interval, &data.context.flow),
378                    ERROR_ARRAY_INSERT_AT.to_owned(),
379                ));
380            }
381        };
382
383        let value = match args.get("arg1") {
384            Some(res) => res,
385            _ => {
386                return Err(gen_error_info(
387                    Position::new(interval, &data.context.flow),
388                    format!("usage: {}", usage),
389                ));
390            }
391        };
392
393        check_index(
394            *index,
395            array.value.len() as i64,
396            &data.context.flow,
397            interval,
398        )?;
399
400        array.value.insert(*index as usize, value.clone());
401
402        Ok(PrimitiveNull::get_literal(interval))
403    }
404
405    fn index_of(
406        array: &mut PrimitiveArray,
407        args: &HashMap<String, Literal>,
408        _additional_info: &Option<HashMap<String, Literal>>,
409        interval: Interval,
410        data: &mut Data,
411        _msg_data: &mut MessageData,
412        _sender: &Option<mpsc::Sender<MSG>>,
413    ) -> Result<Literal, ErrorInfo> {
414        let usage = "index_of(value: primitive) => int";
415
416        if args.len() != 1 {
417            return Err(gen_error_info(
418                Position::new(interval, &data.context.flow),
419                format!("usage: {}", usage),
420            ));
421        }
422
423        let value = match args.get("arg0") {
424            Some(res) => res,
425            None => {
426                return Err(gen_error_info(
427                    Position::new(interval, &data.context.flow),
428                    format!("usage: {}", usage),
429                ));
430            }
431        };
432
433        for (index, literal) in array.value.iter().enumerate() {
434            if literal == value {
435                return Ok(PrimitiveInt::get_literal(index as i64, interval));
436            }
437        }
438
439        Ok(PrimitiveInt::get_literal(-1, interval))
440    }
441
442    fn join(
443        array: &mut PrimitiveArray,
444        args: &HashMap<String, Literal>,
445        _additional_info: &Option<HashMap<String, Literal>>,
446        interval: Interval,
447        data: &mut Data,
448        _msg_data: &mut MessageData,
449        _sender: &Option<mpsc::Sender<MSG>>,
450    ) -> Result<Literal, ErrorInfo> {
451        let usage = "join(separator: string) => string";
452
453        if args.len() != 1 {
454            return Err(gen_error_info(
455                Position::new(interval, &data.context.flow),
456                format!("usage: {}", usage),
457            ));
458        }
459
460        let separator = match args.get("arg0") {
461            Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveString => {
462                Literal::get_value::<String>(
463                    &res.primitive,
464                    &data.context.flow,
465                    interval,
466                    ERROR_ARRAY_JOIN.to_owned(),
467                )?
468            }
469            _ => {
470                return Err(gen_error_info(
471                    Position::new(interval, &data.context.flow),
472                    ERROR_ARRAY_JOIN.to_owned(),
473                ));
474            }
475        };
476
477        let length = array.value.len();
478        let mut result = String::new();
479
480        for (index, string) in array.value.iter().enumerate() {
481            result.push_str(&string.primitive.to_string());
482
483            if index + 1 != length {
484                result.push_str(separator);
485            }
486        }
487
488        Ok(PrimitiveString::get_literal(&result, interval))
489    }
490
491    fn length(
492        array: &mut PrimitiveArray,
493        args: &HashMap<String, Literal>,
494        _additional_info: &Option<HashMap<String, Literal>>,
495        interval: Interval,
496        data: &mut Data,
497        _msg_data: &mut MessageData,
498        _sender: &Option<mpsc::Sender<MSG>>,
499    ) -> Result<Literal, ErrorInfo> {
500        let usage = "length() => int";
501
502        if !args.is_empty() {
503            return Err(gen_error_info(
504                Position::new(interval, &data.context.flow),
505                format!("usage: {}", usage),
506            ));
507        }
508
509        let result = array.value.len();
510
511        Ok(PrimitiveInt::get_literal(result as i64, interval))
512    }
513
514    fn one_of(
515        array: &mut PrimitiveArray,
516        args: &HashMap<String, Literal>,
517        _additional_info: &Option<HashMap<String, Literal>>,
518        interval: Interval,
519        data: &mut Data,
520        _msg_data: &mut MessageData,
521        _sender: &Option<mpsc::Sender<MSG>>,
522    ) -> Result<Literal, ErrorInfo> {
523        let usage = "one_of() => primitive";
524
525        if !args.is_empty() {
526            return Err(gen_error_info(
527                Position::new(interval, &data.context.flow),
528                format!("usage: {}", usage),
529            ));
530        }
531
532        if let Some(res) = array
533            .value
534            .get(rand::thread_rng().gen_range(0..array.value.len()))
535        {
536            return Ok(res.to_owned());
537        }
538
539        Ok(PrimitiveNull::get_literal(interval))
540    }
541
542    fn push(
543        array: &mut PrimitiveArray,
544        args: &HashMap<String, Literal>,
545        _additional_info: &Option<HashMap<String, Literal>>,
546        interval: Interval,
547        data: &mut Data,
548        _msg_data: &mut MessageData,
549        _sender: &Option<mpsc::Sender<MSG>>,
550    ) -> Result<Literal, ErrorInfo> {
551        let usage = "push(value: primitive) => null";
552
553        if args.len() != 1 {
554            return Err(gen_error_info(
555                Position::new(interval, &data.context.flow),
556                format!("usage: {}", usage),
557            ));
558        }
559
560        let value = match args.get("arg0") {
561            Some(res) => res,
562            None => {
563                return Err(gen_error_info(
564                    Position::new(interval, &data.context.flow),
565                    format!("usage: {}", usage),
566                ));
567            }
568        };
569
570        if array.value.len() + args.len() == usize::MAX {
571            return Err(gen_error_info(
572                Position::new(interval, &data.context.flow),
573                format!("{} {}", ERROR_ARRAY_OVERFLOW, usize::MAX,),
574            ));
575        }
576
577        array.value.push(value.to_owned());
578
579        Ok(PrimitiveNull::get_literal(interval))
580    }
581
582    fn pop(
583        array: &mut PrimitiveArray,
584        args: &HashMap<String, Literal>,
585        _additional_info: &Option<HashMap<String, Literal>>,
586        interval: Interval,
587        data: &mut Data,
588        _msg_data: &mut MessageData,
589        _sender: &Option<mpsc::Sender<MSG>>,
590    ) -> Result<Literal, ErrorInfo> {
591        let usage = "pop() => primitive";
592
593        if !args.is_empty() {
594            return Err(gen_error_info(
595                Position::new(interval, &data.context.flow),
596                format!("usage: {}", usage),
597            ));
598        }
599
600        match array.value.pop() {
601            Some(literal) => Ok(literal),
602            None => Err(gen_error_info(
603                Position::new(interval, &data.context.flow),
604                ERROR_ARRAY_POP.to_owned(),
605            )),
606        }
607    }
608
609    fn remove_at(
610        array: &mut PrimitiveArray,
611        args: &HashMap<String, Literal>,
612        _additional_info: &Option<HashMap<String, Literal>>,
613        interval: Interval,
614        data: &mut Data,
615        _msg_data: &mut MessageData,
616        _sender: &Option<mpsc::Sender<MSG>>,
617    ) -> Result<Literal, ErrorInfo> {
618        let usage = "remove_at(index: int) => primitive";
619
620        if args.len() != 1 {
621            return Err(gen_error_info(
622                Position::new(interval, &data.context.flow),
623                format!("usage: {}", usage),
624            ));
625        }
626
627        let index = match args.get("arg0") {
628            Some(res) if res.primitive.get_type() == PrimitiveType::PrimitiveInt => {
629                Literal::get_value::<i64>(
630                    &res.primitive,
631                    &data.context.flow,
632                    interval,
633                    ERROR_ARRAY_REMOVE_AT.to_owned(),
634                )?
635            }
636            _ => {
637                return Err(gen_error_info(
638                    Position::new(interval, &data.context.flow),
639                    ERROR_ARRAY_REMOVE_AT.to_owned(),
640                ));
641            }
642        };
643
644        check_index(
645            *index,
646            array.value.len() as i64,
647            &data.context.flow,
648            interval,
649        )?;
650
651        Ok(array.value.remove(*index as usize))
652    }
653
654    fn shuffle(
655        array: &mut PrimitiveArray,
656        args: &HashMap<String, Literal>,
657        _additional_info: &Option<HashMap<String, Literal>>,
658        interval: Interval,
659        data: &mut Data,
660        _msg_data: &mut MessageData,
661        _sender: &Option<mpsc::Sender<MSG>>,
662    ) -> Result<Literal, ErrorInfo> {
663        let usage = "shuffle() => array";
664
665        if !args.is_empty() {
666            return Err(gen_error_info(
667                Position::new(interval, &data.context.flow),
668                format!("usage: {}", usage),
669            ));
670        }
671
672        let mut vector = array.value.to_owned();
673
674        vector.shuffle(&mut rand::thread_rng());
675
676        Ok(PrimitiveArray::get_literal(&vector, interval))
677    }
678
679    fn slice(
680        array: &mut PrimitiveArray,
681        args: &HashMap<String, Literal>,
682        _additional_info: &Option<HashMap<String, Literal>>,
683        interval: Interval,
684        data: &mut Data,
685        _msg_data: &mut MessageData,
686        _sender: &Option<mpsc::Sender<MSG>>,
687    ) -> Result<Literal, ErrorInfo> {
688        let usage = "slice(start: Integer, end: Optional<Integer>) => [Literal]";
689        let len = array.value.len();
690
691        match args.len() {
692            1 => match args.get("arg0") {
693                Some(literal) => {
694                    let mut int_start = Literal::get_value::<i64>(
695                        &literal.primitive,
696                        &data.context.flow,
697                        literal.interval,
698                        ERROR_SLICE_ARG_INT.to_owned(),
699                    )?
700                    .to_owned();
701
702                    if int_start < 0 {
703                        int_start = len as i64 + int_start;
704                    }
705
706                    let start = match int_start {
707                        value if value >= 0 && (value as usize) < len => value as usize,
708                        _ => {
709                            return Err(gen_error_info(
710                                Position::new(interval, &data.context.flow),
711                                ERROR_SLICE_ARG_LEN.to_owned(),
712                            ))
713                        }
714                    };
715
716                    let value = array.value[start..]
717                        .iter()
718                        .cloned()
719                        .collect::<Vec<Literal>>();
720
721                    Ok(PrimitiveArray::get_literal(&value, interval))
722                }
723                _ => Err(gen_error_info(
724                    Position::new(interval, &data.context.flow),
725                    ERROR_SLICE_ARG_INT.to_owned(),
726                )),
727            },
728            2 => match (args.get("arg0"), args.get("arg1")) {
729                (Some(literal_start), Some(literal_end)) => {
730                    let mut int_start = Literal::get_value::<i64>(
731                        &literal_start.primitive,
732                        &data.context.flow,
733                        literal_start.interval,
734                        ERROR_SLICE_ARG_INT.to_owned(),
735                    )?
736                    .to_owned();
737                    let mut int_end = Literal::get_value::<i64>(
738                        &literal_end.primitive,
739                        &data.context.flow,
740                        literal_end.interval,
741                        ERROR_SLICE_ARG_INT.to_owned(),
742                    )?
743                    .to_owned();
744
745                    if int_start < 0 {
746                        int_start = len as i64 + int_start;
747                    }
748
749                    if int_end.is_negative() {
750                        int_end = len as i64 + int_end;
751                    }
752                    if int_end < int_start {
753                        return Err(gen_error_info(
754                            Position::new(interval, &data.context.flow),
755                            ERROR_SLICE_ARG2.to_owned(),
756                        ));
757                    }
758
759                    let (start, end) = match (int_start, int_end) {
760                        (start, end)
761                            if int_start >= 0
762                                && end >= 0
763                                && (start as usize) < len
764                                && (end as usize) <= len =>
765                        {
766                            (start as usize, end as usize)
767                        }
768                        _ => {
769                            return Err(gen_error_info(
770                                Position::new(interval, &data.context.flow),
771                                ERROR_SLICE_ARG_LEN.to_owned(),
772                            ))
773                        }
774                    };
775                    let value = array.value[start..end]
776                        .iter()
777                        .cloned()
778                        .collect::<Vec<Literal>>();
779
780                    Ok(PrimitiveArray::get_literal(&value, interval))
781                }
782                _ => Err(gen_error_info(
783                    Position::new(interval, &data.context.flow),
784                    ERROR_SLICE_ARG_INT.to_owned(),
785                )),
786            },
787            _ => Err(gen_error_info(
788                Position::new(interval, &data.context.flow),
789                format!("usage: {}", usage),
790            )),
791        }
792    }
793
794    fn reverse(
795        array: &mut PrimitiveArray,
796        args: &HashMap<String, Literal>,
797        _additional_info: &Option<HashMap<String, Literal>>,
798        interval: Interval,
799        data: &mut Data,
800        _msg_data: &mut MessageData,
801        _sender: &Option<mpsc::Sender<MSG>>,
802    ) -> Result<Literal, ErrorInfo> {
803        let usage = "reverse() => [Literal]";
804
805        if !args.is_empty() {
806            return Err(gen_error_info(
807                Position::new(interval, &data.context.flow),
808                format!("usage: {}", usage),
809            ));
810        }
811
812        let mut reversed_list = array.value.clone();
813        reversed_list.reverse();
814
815        Ok(PrimitiveArray::get_literal(&reversed_list, interval))
816    }
817
818    fn append(
819        array: &mut PrimitiveArray,
820        args: &HashMap<String, Literal>,
821        _additional_info: &Option<HashMap<String, Literal>>,
822        interval: Interval,
823        data: &mut Data,
824        _msg_data: &mut MessageData,
825        _sender: &Option<mpsc::Sender<MSG>>,
826    ) -> Result<Literal, ErrorInfo> {
827        let usage = "append(other_array: [Literal]) => [Literal]";
828
829        if args.len() != 1 {
830            return Err(gen_error_info(
831                Position::new(interval, &data.context.flow),
832                format!("usage: {}", usage),
833            ));
834        }
835
836        let mut other_array: Vec<Literal> = match args.get("arg0") {
837            Some(res) if res.content_type == "array" => {
838                let value = Literal::get_value::<Vec<Literal>>(
839                    &res.primitive,
840                    &data.context.flow,
841                    interval,
842                    ERROR_ARRAY_INSERT_AT.to_owned(),
843                )?;
844
845                (*value).clone().to_vec()
846            }
847            _ => {
848                return Err(gen_error_info(
849                    Position::new(interval, &data.context.flow),
850                    ERROR_ARRAY_INSERT_AT.to_owned(),
851                ));
852            }
853        };
854
855        let mut new_array = array.value.clone();
856
857        new_array.append(&mut other_array);
858
859        Ok(PrimitiveArray::get_literal(&new_array, interval))
860    }
861
862    fn flatten(
863        array: &mut PrimitiveArray,
864        args: &HashMap<String, Literal>,
865        _additional_info: &Option<HashMap<String, Literal>>,
866        interval: Interval,
867        data: &mut Data,
868        _msg_data: &mut MessageData,
869        _sender: &Option<mpsc::Sender<MSG>>,
870    ) -> Result<Literal, ErrorInfo> {
871        let usage = "flatten() => [Literal]";
872
873        if args.len() != 0 {
874            return Err(gen_error_info(
875                Position::new(interval, &data.context.flow),
876                format!("usage: {}", usage),
877            ));
878        }
879
880        let mut new_array = vec![];
881
882        for lit in array.value.iter() {
883            if lit.content_type == "array" {
884                let value = Literal::get_value::<Vec<Literal>>(
885                    &lit.primitive,
886                    &data.context.flow,
887                    interval,
888                    ERROR_ARRAY_INSERT_AT.to_owned(),
889                )?;
890                for elem in value.iter() {
891                    new_array.push(elem.to_owned())
892                }
893            } else {
894                new_array.push(lit.to_owned())
895            }
896        }
897
898        Ok(PrimitiveArray::get_literal(&new_array, interval))
899    }
900}
901
902impl PrimitiveArray {
903    fn map(
904        array: &mut PrimitiveArray,
905        args: &HashMap<String, Literal>,
906        _additional_info: &Option<HashMap<String, Literal>>,
907        interval: Interval,
908        data: &mut Data,
909        msg_data: &mut MessageData,
910        sender: &Option<mpsc::Sender<MSG>>,
911    ) -> Result<Literal, ErrorInfo> {
912        let usage = "map(fn) expect one argument of type [Closure]";
913
914        match args.get("arg0") {
915            Some(lit) => {
916                let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
917                    &lit.primitive,
918                    &data.context.flow,
919                    interval,
920                    format!("usage: {}", usage),
921                )?;
922
923                let mut vec = vec![];
924                let mut context = init_child_context(&data);
925                let mut step_count = data.step_count.clone();
926                let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
927
928                if let Some(memories) = closure.enclosed_variables.clone() {
929                    insert_memories_in_scope_memory(
930                        &mut new_scope_data,
931                        memories,
932                        msg_data,
933                        sender,
934                    );
935                }
936
937                for (index, value) in array.value.iter().enumerate() {
938                    let mut map = HashMap::new();
939                    map.insert("arg0".to_owned(), value.to_owned());
940                    if closure.args.len() >= 2 {
941                        map.insert(
942                            "arg1".to_owned(),
943                            PrimitiveInt::get_literal(index as i64, interval),
944                        );
945                    }
946
947                    let args = ArgsType::Normal(map);
948                    insert_args_in_scope_memory(
949                        &mut new_scope_data,
950                        &closure.args,
951                        &args,
952                        msg_data,
953                        sender,
954                    );
955
956                    let result = exec_closure(
957                        &closure.func,
958                        &closure.args,
959                        args,
960                        interval,
961                        &mut new_scope_data,
962                        msg_data,
963                        sender,
964                    )?;
965                    vec.push(result);
966                }
967
968                Ok(PrimitiveArray::get_literal(&vec, interval))
969            }
970            None => Err(gen_error_info(
971                Position::new(interval, &data.context.flow),
972                format!("usage: {}", usage),
973            )),
974        }
975    }
976
977    fn filter(
978        array: &mut PrimitiveArray,
979        args: &HashMap<String, Literal>,
980        _additional_info: &Option<HashMap<String, Literal>>,
981        interval: Interval,
982        data: &mut Data,
983        msg_data: &mut MessageData,
984        sender: &Option<mpsc::Sender<MSG>>,
985    ) -> Result<Literal, ErrorInfo> {
986        let usage = "filter(fn) expect one argument of type [Closure]";
987
988        match args.get("arg0") {
989            Some(lit) => {
990                let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
991                    &lit.primitive,
992                    &data.context.flow,
993                    interval,
994                    format!("usage: {}", usage),
995                )?;
996
997                let mut vec = vec![];
998
999                let mut context = init_child_context(&data);
1000                let mut step_count = data.step_count.clone();
1001                let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
1002
1003                if let Some(memories) = closure.enclosed_variables.clone() {
1004                    insert_memories_in_scope_memory(
1005                        &mut new_scope_data,
1006                        memories,
1007                        msg_data,
1008                        sender,
1009                    );
1010                }
1011
1012                for (index, value) in array.value.iter().enumerate() {
1013                    let mut map = HashMap::new();
1014                    map.insert("arg0".to_owned(), value.to_owned());
1015                    if closure.args.len() >= 2 {
1016                        map.insert(
1017                            "arg1".to_owned(),
1018                            PrimitiveInt::get_literal(index as i64, interval),
1019                        );
1020                    }
1021
1022                    let args = ArgsType::Normal(map);
1023
1024                    insert_args_in_scope_memory(
1025                        &mut new_scope_data,
1026                        &closure.args,
1027                        &args,
1028                        msg_data,
1029                        sender,
1030                    );
1031
1032                    let result = exec_closure(
1033                        &closure.func,
1034                        &closure.args,
1035                        args,
1036                        interval,
1037                        &mut new_scope_data,
1038                        msg_data,
1039                        sender,
1040                    )?;
1041
1042                    if result.primitive.as_bool() {
1043                        vec.push(value.clone());
1044                    }
1045                }
1046
1047                Ok(PrimitiveArray::get_literal(&vec, interval))
1048            }
1049            None => Err(gen_error_info(
1050                Position::new(interval, &data.context.flow),
1051                format!("usage: {}", usage),
1052            )),
1053        }
1054    }
1055
1056    fn reduce(
1057        array: &mut PrimitiveArray,
1058        args: &HashMap<String, Literal>,
1059        _additional_info: &Option<HashMap<String, Literal>>,
1060        interval: Interval,
1061        data: &mut Data,
1062        msg_data: &mut MessageData,
1063        sender: &Option<mpsc::Sender<MSG>>,
1064    ) -> Result<Literal, ErrorInfo> {
1065        let usage = "reduce(acc, fn) expect tow arguments an initial value and 'Closure' with two arguments: an 'accumulator', and an element";
1066
1067        match (args.get("arg0"), args.get("arg1")) {
1068            (Some(acc), Some(closure)) => {
1069                let mut accumulator = acc.clone();
1070
1071                let closure: &PrimitiveClosure = Literal::get_value::<PrimitiveClosure>(
1072                    &closure.primitive,
1073                    &data.context.flow,
1074                    interval,
1075                    format!("usage: {}", usage),
1076                )?;
1077
1078                let mut context = init_child_context(&data);
1079                let mut step_count = data.step_count.clone();
1080                let mut new_scope_data = init_child_scope(data, &mut context, &mut step_count);
1081
1082                for (index, value) in array.value.iter().enumerate() {
1083                    let mut map = HashMap::new();
1084                    map.insert("arg0".to_owned(), accumulator);
1085                    map.insert("arg1".to_owned(), value.to_owned());
1086
1087                    if closure.args.len() >= 2 {
1088                        map.insert(
1089                            "arg2".to_owned(),
1090                            PrimitiveInt::get_literal(index as i64, interval),
1091                        );
1092                    }
1093
1094                    let args = ArgsType::Normal(map);
1095
1096                    insert_args_in_scope_memory(
1097                        &mut new_scope_data,
1098                        &closure.args,
1099                        &args,
1100                        msg_data,
1101                        sender,
1102                    );
1103
1104                    accumulator = exec_closure(
1105                        &closure.func,
1106                        &closure.args,
1107                        args,
1108                        interval,
1109                        &mut new_scope_data,
1110                        msg_data,
1111                        sender,
1112                    )?;
1113                }
1114
1115                Ok(accumulator)
1116            }
1117            _ => Err(gen_error_info(
1118                Position::new(interval, &data.context.flow),
1119                format!("usage: {}", usage),
1120            )),
1121        }
1122    }
1123}
1124
1125////////////////////////////////////////////////////////////////////////////////
1126// PUBLIC FUNCTIONS
1127////////////////////////////////////////////////////////////////////////////////
1128
1129impl PrimitiveArray {
1130    pub fn new(value: &[Literal]) -> Self {
1131        Self {
1132            value: value.to_owned(),
1133        }
1134    }
1135
1136    pub fn get_literal(vector: &[Literal], interval: Interval) -> Literal {
1137        let primitive = Box::new(PrimitiveArray::new(vector));
1138
1139        Literal {
1140            content_type: "array".to_owned(),
1141            primitive,
1142            additional_info: None,
1143            secure_variable: false,
1144            interval,
1145        }
1146    }
1147}
1148
1149////////////////////////////////////////////////////////////////////////////////
1150// TRAIT FUNCTIONS
1151////////////////////////////////////////////////////////////////////////////////
1152
1153#[typetag::serde]
1154impl Primitive for PrimitiveArray {
1155    fn is_eq(&self, other: &dyn Primitive) -> bool {
1156        if let Some(other) = other.as_any().downcast_ref::<Self>() {
1157            return self.value == other.value;
1158        }
1159
1160        false
1161    }
1162
1163    fn is_cmp(&self, other: &dyn Primitive) -> Option<Ordering> {
1164        if let Some(other) = other.as_any().downcast_ref::<Self>() {
1165            return self.value.partial_cmp(&other.value);
1166        }
1167
1168        None
1169    }
1170
1171    fn do_add(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1172        Err(format!(
1173            "{} {:?} + {:?}",
1174            ERROR_ILLEGAL_OPERATION,
1175            self.get_type(),
1176            other.get_type()
1177        ))
1178    }
1179
1180    fn do_sub(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1181        Err(format!(
1182            "{} {:?} - {:?}",
1183            ERROR_ILLEGAL_OPERATION,
1184            self.get_type(),
1185            other.get_type()
1186        ))
1187    }
1188
1189    fn do_div(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1190        Err(format!(
1191            "{} {:?} / {:?}",
1192            ERROR_ILLEGAL_OPERATION,
1193            self.get_type(),
1194            other.get_type()
1195        ))
1196    }
1197
1198    fn do_mul(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1199        Err(format!(
1200            "{} {:?} * {:?}",
1201            ERROR_ILLEGAL_OPERATION,
1202            self.get_type(),
1203            other.get_type()
1204        ))
1205    }
1206
1207    fn do_rem(&self, other: &dyn Primitive) -> Result<Box<dyn Primitive>, String> {
1208        Err(format!(
1209            "{} {:?} % {:?}",
1210            ERROR_ILLEGAL_OPERATION,
1211            self.get_type(),
1212            other.get_type()
1213        ))
1214    }
1215
1216    fn as_debug(&self) -> &dyn std::fmt::Debug {
1217        self
1218    }
1219
1220    fn as_any(&self) -> &dyn std::any::Any {
1221        self
1222    }
1223
1224    fn get_type(&self) -> PrimitiveType {
1225        PrimitiveType::PrimitiveArray
1226    }
1227
1228    fn as_box_clone(&self) -> Box<dyn Primitive> {
1229        Box::new((*self).clone())
1230    }
1231
1232    fn to_json(&self) -> serde_json::Value {
1233        let mut vector: Vec<serde_json::Value> = Vec::new();
1234
1235        for literal in self.value.iter() {
1236            let value = literal.primitive.to_json();
1237
1238            if !TYPES.contains(&&(*literal.content_type)) {
1239                let mut map = serde_json::Map::new();
1240                map.insert(
1241                    "content_type".to_owned(),
1242                    serde_json::json!(literal.content_type),
1243                );
1244                map.insert("content".to_owned(), value);
1245
1246                vector.push(serde_json::json!(map));
1247            } else {
1248                vector.push(value);
1249            }
1250        }
1251
1252        serde_json::Value::Array(vector)
1253    }
1254
1255    fn format_mem(&self, _content_type: &str, first: bool) -> serde_json::Value {
1256        let mut vector: Vec<serde_json::Value> = Vec::new();
1257
1258        for literal in self.value.iter() {
1259            let content_type = &literal.content_type;
1260            let value = literal.primitive.format_mem(content_type, first);
1261            vector.push(value);
1262        }
1263
1264        serde_json::Value::Array(vector)
1265    }
1266
1267    fn to_string(&self) -> String {
1268        self.to_json().to_string()
1269    }
1270
1271    fn as_bool(&self) -> bool {
1272        true
1273    }
1274
1275    fn get_value(&self) -> &dyn std::any::Any {
1276        &self.value
1277    }
1278
1279    fn get_mut_value(&mut self) -> &mut dyn std::any::Any {
1280        &mut self.value
1281    }
1282
1283    fn to_msg(&self, content_type: String) -> Message {
1284        let vec = self.value.iter().fold(vec![], |mut acc, v| {
1285            acc.push(v.primitive.to_json());
1286            acc
1287        });
1288        Message {
1289            content_type,
1290            content: json!(vec),
1291        }
1292    }
1293
1294    fn do_exec(
1295        &mut self,
1296        name: &str,
1297        args: &HashMap<String, Literal>,
1298        mem_type: &MemoryType,
1299        additional_info: &Option<HashMap<String, Literal>>,
1300        interval: Interval,
1301        _content_type: &ContentType,
1302        data: &mut Data,
1303        msg_data: &mut MessageData,
1304        sender: &Option<mpsc::Sender<MSG>>,
1305    ) -> Result<(Literal, Right), ErrorInfo> {
1306        if let Some((f, right)) = FUNCTIONS.get(name) {
1307            if *mem_type == MemoryType::Constant && *right == Right::Write {
1308                return Err(gen_error_info(
1309                    Position::new(interval, &data.context.flow),
1310                    format!("{}", ERROR_CONSTANT_MUTABLE_FUNCTION),
1311                ));
1312            } else {
1313                let res = f(
1314                    self,
1315                    args,
1316                    additional_info,
1317                    interval,
1318                    data,
1319                    msg_data,
1320                    sender,
1321                )?;
1322
1323                return Ok((res, *right));
1324            }
1325        }
1326
1327        Err(gen_error_info(
1328            Position::new(interval, &data.context.flow),
1329            format!("[{}] {}", name, ERROR_ARRAY_UNKNOWN_METHOD),
1330        ))
1331    }
1332}