gitql_core/values/
row.rs

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}