Skip to main content

rust_dynamic/
push.rs

1use crate::value::{Value, timestamp_ms};
2use crate::metric::Metric;
3use crate::types::*;
4use nanoid::nanoid;
5
6impl Value {
7    pub fn push(&mut self, value: Value) -> Self {
8        match self.dt {
9            JSON => {
10                match &self.data {
11                    Val::Json(v) => {
12                        if ! v.is_array() {
13                            return self.clone();
14                        }
15                        match value.cast_value_to_json() {
16                            Ok(j_value) => {
17                                match self.cast_json() {
18                                    Ok(mut j_arr_value) => {
19                                        let j_array = j_arr_value.as_array_mut().unwrap();
20                                        j_array.push(j_value);
21                                        return Value::json(serde_json::to_value(j_array).unwrap());
22                                    }
23                                    Err(_) => {
24                                        return self.clone();
25                                    }
26                                }
27                            }
28                            Err(_) => {
29                                return self.clone();
30                            }
31                        }
32                    }
33                    _ => {}
34                }
35                return self.clone();
36            }
37            LIST | RESULT => {
38                let mut data: Vec<Value> = Vec::new();
39                match &self.data {
40                    Val::List(v) => {
41                        for i in v {
42                            data.push(i.clone());
43                        }
44                        data.push(value.clone());
45                    }
46                    _ => {},
47                }
48                return Value::from_list(data);
49            }
50            MATRIX => {
51                let mut data: Vec<Vec<Value>> = Vec::new();
52                match &self.data {
53                    Val::Matrix(v) => {
54                        for i in v {
55                            data.push(i.clone());
56                        }
57                        if value.type_of() == LIST {
58                            let list_data = match value.cast_list() {
59                                Ok(list_data) => list_data,
60                                Err(_) => {
61                                    return self.clone();
62                                }
63                            };
64                            data.push(list_data);
65                        }
66                    }
67                    _ => {},
68                }
69                return Value::from_matrix(data);
70            }
71            TEXTBUFFER => {
72                match self.cast_string() {
73                    Ok(str_val) => {
74                        let mut res = Value::text_buffer(str_val);
75                        res = res + value;
76                        return res;
77                    }
78                    Err(_) => {
79                        return self.clone();
80                    }
81                }
82            }
83            QUEUE | FIFO => {
84                let mut data: Vec<Value> = Vec::new();
85                match &self.data {
86                    Val::Queue(v) => {
87                        for i in v {
88                            data.push(i.clone());
89                        }
90                        data.push(value.clone());
91                    }
92                    _ => {},
93                }
94                if self.dt == QUEUE {
95                    return Value::to_queue(data);
96                } else {
97                    return Value::to_fifo(data);
98                }
99            }
100            LAMBDA => {
101                let mut data: Vec<Value> = Vec::new();
102                match &self.data {
103                    Val::Lambda(v) => {
104                        for i in v {
105                            data.push(i.clone());
106                        }
107                        data.push(value.clone());
108                    }
109                    _ => {},
110                }
111                return Value::to_lambda(data);
112            }
113            METRICS => {
114                if value.dt != FLOAT {
115                    return self.clone();
116                }
117                match &self.data {
118                    Val::Metrics(v) => {
119                        let mut m_data: Vec<Metric> = Vec::new();
120                        for i in v {
121                            m_data.push(i.clone());
122                        }
123                        m_data.push(Metric::new(value.cast_float().unwrap()));
124                        m_data.remove(0);
125                        return Value::from_metrics(m_data);
126                    }
127                    _ => return self.clone(),
128                }
129            }
130            BIN => {
131                if value.dt == STRING {
132                    let str_data = match value.cast_string() {
133                        Ok(str_data) => str_data,
134                        Err(_) => return self.clone(),
135                    };
136                    let mut bin_data = match self.cast_bin() {
137                        Ok(bin_data) => bin_data,
138                        Err(_) => return self.clone(),
139                    };
140                    let bytes: Vec<u8> = str_data.into_bytes();
141                    for b in bytes {
142                        bin_data.push(b);
143                    }
144                    return Value::from_bin(bin_data);
145                } else if value.dt == BIN {
146                    let bin_in_data = match value.cast_bin() {
147                        Ok(bin_data) => bin_data,
148                        Err(_) => return self.clone(),
149                    };
150                    let mut bin_data = match self.cast_bin() {
151                        Ok(bin_data) => bin_data,
152                        Err(_) => return self.clone(),
153                    };
154                    for b in bin_in_data {
155                        bin_data.push(b);
156                    }
157                    return Value::from_bin(bin_data);
158                } else {
159                    return self.clone();
160                }
161            }
162            _ => {
163                let mut res = value.clone();
164                res.q = self.q;
165                res.id = nanoid!();
166                res.stamp = timestamp_ms();
167                return res;
168            }
169        }
170    }
171}