csml_interpreter/data/
fn_args_type.rs

1use crate::data::{
2    position::Position,
3    primitive::{PrimitiveArray, PrimitiveObject, PrimitiveString},
4    Interval, Literal,
5};
6use crate::error_format::*;
7
8use std::collections::{hash_map::Iter, HashMap};
9
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub enum ArgsType {
14    Named(HashMap<String, Literal>),
15    Normal(HashMap<String, Literal>),
16}
17
18impl ArgsType {
19    pub fn args_to_debug(&self, interval: Interval) -> Literal {
20        match self {
21            Self::Named(map) | Self::Normal(map) => {
22                let mut obj = HashMap::new();
23
24                let mut args = vec![];
25                let size = map.len();
26                let mut index = 0;
27                let mut is_secure = false;
28                while index < size {
29                    let lit = map[&format!("arg{}", index)].clone();
30                    if lit.secure_variable {
31                        is_secure = true;
32                    }
33                    let value =
34                        PrimitiveString::get_literal(&lit.primitive.to_string(), lit.interval);
35                    args.push(value);
36                    index = index + 1;
37                }
38
39                obj.insert(
40                    "args".to_owned(),
41                    PrimitiveArray::get_literal(&args, interval),
42                );
43
44                let mut lit = PrimitiveObject::get_literal(&obj, interval);
45                lit.secure_variable = is_secure;
46                lit.set_content_type("debug");
47
48                lit
49            }
50        }
51    }
52
53    pub fn args_to_log(&self) -> String {
54        match self {
55            Self::Named(map) | Self::Normal(map) => {
56                let mut args = vec![];
57                let size = map.len();
58                let mut index = 0;
59                while index < size {
60                    let lit = map[&format!("arg{}", index)].clone();
61                    if lit.secure_variable {
62                        return "secure variables can not be logged".to_string()
63                    }
64
65                    let value = lit.primitive.to_string();
66                    args.push(value);
67                    index = index + 1;
68                }
69
70                format!("{}", args.join(", "))
71            }
72        }
73    }
74
75    pub fn get<'a>(&'a self, key: &str, index: usize) -> Option<&'a Literal> {
76        match self {
77            Self::Named(var) => {
78                match (var.get(key), index) {
79                    (Some(val), _) => Some(val),
80                    // tmp ?
81                    (None, 0) => var.get(&format!("arg{}", index)),
82                    (None, _) => None,
83                }
84            }
85            Self::Normal(var) => var.get(&format!("arg{}", index)),
86        }
87    }
88
89    pub fn len(&self) -> usize {
90        match self {
91            Self::Named(var) | Self::Normal(var) => var.len(),
92        }
93    }
94
95    pub fn iter(&self) -> Iter<'_, String, Literal> {
96        match self {
97            Self::Named(var) | Self::Normal(var) => var.iter(),
98        }
99    }
100
101    pub fn populate(
102        &self,
103        map: &mut HashMap<String, Literal>,
104        vec: &[&str],
105        flow_name: &str,
106        interval: Interval,
107    ) -> Result<(), ErrorInfo> {
108        match self {
109            Self::Named(var) => {
110                for (key, value) in var.iter() {
111                    if !vec.contains(&(key as &str)) && key != "arg0" {
112                        map.insert(key.to_owned(), value.to_owned());
113                    }
114                }
115                Ok(())
116            }
117            Self::Normal(var) => {
118                if vec.len() < var.len() {
119                    //TODO:: error msg
120                    Err(gen_error_info(
121                        Position::new(interval, flow_name),
122                        "to many arguments".to_owned(),
123                    ))
124                } else {
125                    Ok(())
126                }
127            }
128        }
129    }
130
131    pub fn populate_json_to_literal(
132        &self,
133        map: &mut HashMap<String, Literal>,
134        vec: &[serde_json::Value],
135        flow_name: &str,
136        interval: Interval,
137    ) -> Result<(), ErrorInfo> {
138        match self {
139            Self::Named(var) => {
140                for (key, value) in var.iter() {
141                    let contains = vec.iter().find(|obj| {
142                        if let Some(map) = obj.as_object() {
143                            map.contains_key(key)
144                        } else {
145                            false
146                        }
147                    });
148
149                    if let (None, true) = (contains, key != "arg0") {
150                        map.insert(key.to_owned(), value.to_owned());
151                    }
152                }
153                Ok(())
154            }
155            Self::Normal(var) => {
156                if vec.len() < var.len() {
157                    Err(gen_error_info(
158                        Position::new(interval, flow_name),
159                        "to many arguments".to_owned(),
160                    ))
161                } else {
162                    Ok(())
163                }
164            }
165        }
166    }
167}