gitql_core/values/
array.rs1use 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}