gitql_core/values/
array.rs

1use std::any::Any;
2use std::cmp::Ordering;
3
4use gitql_ast::types::array::ArrayType;
5use gitql_ast::types::DataType;
6
7use super::base::Value;
8use super::boolean::BoolValue;
9use super::integer::IntValue;
10
11#[derive(Clone)]
12pub struct ArrayValue {
13    pub values: Vec<Box<dyn Value>>,
14    pub base_type: Box<dyn DataType>,
15}
16
17impl ArrayValue {
18    pub fn new(values: Vec<Box<dyn Value>>, base_type: Box<dyn DataType>) -> Self {
19        ArrayValue { values, base_type }
20    }
21
22    pub fn empty(base_type: Box<dyn DataType>) -> Self {
23        ArrayValue {
24            values: Vec::default(),
25            base_type,
26        }
27    }
28
29    pub fn add_element(mut self, element: Box<dyn Value>) -> Self {
30        self.values.push(element);
31        self
32    }
33}
34
35impl Value for ArrayValue {
36    fn literal(&self) -> String {
37        let mut str = String::new();
38        let elements = &self.values;
39        if elements.is_empty() {
40            return "[]".to_string();
41        }
42
43        str += "[";
44        for (pos, element) in elements.iter().enumerate() {
45            str += &element.literal();
46            if pos + 1 != elements.len() {
47                str += ", ";
48            }
49        }
50        str += "]";
51        str
52    }
53
54    fn equals(&self, other: &Box<dyn Value>) -> bool {
55        if let Some(other_array) = other.as_any().downcast_ref::<ArrayValue>() {
56            if !self.base_type.equals(&other_array.base_type) {
57                return false;
58            }
59
60            let self_values = &self.values;
61            let other_values = &other_array.values;
62            if self.values.len() != other_values.len() {
63                return false;
64            }
65
66            for i in 0..self.values.len() {
67                if !self_values[i].equals(&other_values[i]) {
68                    return false;
69                }
70            }
71        }
72        false
73    }
74
75    fn compare(&self, _other: &Box<dyn Value>) -> Option<Ordering> {
76        None
77    }
78
79    fn data_type(&self) -> Box<dyn DataType> {
80        Box::new(ArrayType {
81            base: self.base_type.clone(),
82        })
83    }
84
85    fn as_any(&self) -> &dyn Any {
86        self
87    }
88
89    fn index_op(&self, index: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
90        if let Some(index) = index.as_any().downcast_ref::<IntValue>() {
91            if (index.value < 1) || (index.value as usize > self.values.len()) {
92                return Err("Array Index must be between 1 and length of Array".to_string());
93            }
94
95            let array_index = (index.value - 1) as usize;
96            return Ok(self.values[array_index].clone());
97        }
98        Err("Unexpected Array Index type".to_string())
99    }
100
101    fn slice_op(
102        &self,
103        start: &Option<Box<dyn Value>>,
104        end: &Option<Box<dyn Value>>,
105    ) -> Result<Box<dyn Value>, String> {
106        if start.is_none() && end.is_none() {
107            return Ok(Box::new(self.clone()));
108        }
109
110        let mut start_index: usize = 0;
111
112        if start.is_some() {
113            if let Some(start_value) = start.clone().unwrap().as_any().downcast_ref::<IntValue>() {
114                if start_value.value < 1 || start_value.value >= self.values.len() as i64 {
115                    return Err("Slice start must be between 1 and length of Array".to_string());
116                }
117                start_index = start_value.value as usize;
118            }
119        }
120
121        let mut end_index: usize = self.values.len();
122        if end.is_some() {
123            if let Some(end_value) = end.clone().unwrap().as_any().downcast_ref::<IntValue>() {
124                if end_value.value < start_index as i64
125                    || end_value.value > self.values.len() as i64
126                {
127                    return Err("Slice end must be between start and length of Array".to_string());
128                }
129                end_index = end_value.value as usize;
130            }
131        }
132
133        let slice = self.values[start_index..end_index].to_vec();
134        Ok(Box::new(ArrayValue {
135            values: slice,
136            base_type: self.base_type.clone(),
137        }))
138    }
139
140    fn logical_or_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
141        if let Some(other_array) = other.as_any().downcast_ref::<ArrayValue>() {
142            for value in self.values.iter() {
143                for other_value in other_array.values.iter() {
144                    if value.equals(other_value) {
145                        return Ok(Box::new(BoolValue { value: true }));
146                    }
147                }
148            }
149            return Ok(Box::new(BoolValue::new_false()));
150        }
151        Err("Unexpected Array overlap type".to_string())
152    }
153
154    fn contains_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
155        for value in self.values.iter() {
156            if value.equals(other) {
157                return Ok(Box::new(BoolValue { value: true }));
158            }
159        }
160
161        Ok(Box::new(BoolValue::new_false()))
162    }
163}