1use std::any::Any;
2use std::cmp::Ordering;
3
4use gitql_ast::types::row::RowType;
5use gitql_ast::types::DataType;
6
7use super::base::Value;
8
9#[derive(Clone)]
10pub struct RowValue {
11 pub columns: Vec<Box<dyn Value>>,
12 pub row_type: RowType,
13}
14
15impl RowValue {
16 pub fn new(columns: Vec<Box<dyn Value>>, row_type: RowType) -> Self {
17 RowValue { columns, row_type }
18 }
19}
20
21impl Value for RowValue {
22 fn literal(&self) -> String {
23 let mut str = String::new();
24 str += "(";
25 for (pos, element) in self.columns.iter().enumerate() {
26 str += &element.literal();
27 if pos + 1 != self.columns.len() {
28 str += ", ";
29 }
30 }
31 str += ")";
32 str
33 }
34
35 fn equals(&self, other: &Box<dyn Value>) -> bool {
36 if let Some(other_row) = other.as_any().downcast_ref::<RowValue>() {
37 let data_type: Box<dyn DataType> = Box::new(other_row.row_type.clone());
38 if !self.row_type.equals(&data_type) {
39 return false;
40 }
41
42 let len = self.row_type.tuple.len();
43 for i in 0..len {
44 if !self.columns[i].eq(&other_row.columns[i]) {
45 return false;
46 }
47 }
48
49 return true;
50 }
51 false
52 }
53
54 fn compare(&self, _other: &Box<dyn Value>) -> Option<Ordering> {
55 None
56 }
57
58 fn data_type(&self) -> Box<dyn DataType> {
59 Box::new(self.row_type.clone())
60 }
61
62 fn as_any(&self) -> &dyn Any {
63 self
64 }
65}