gitql_core/values/
composite.rs1use std::any::Any;
2use std::cmp::Ordering;
3use std::collections::HashMap;
4
5use gitql_ast::types::composite::CompositeType;
6use gitql_ast::types::DataType;
7
8use indexmap::IndexMap;
9
10use super::base::Value;
11
12#[derive(Clone)]
13pub struct CompositeValue {
14 pub name: String,
15 pub members: IndexMap<String, Box<dyn Value>>,
16}
17
18impl CompositeValue {
19 pub fn new(name: String, members: IndexMap<String, Box<dyn Value>>) -> Self {
20 CompositeValue { name, members }
21 }
22
23 pub fn empty(name: String) -> Self {
24 CompositeValue {
25 name,
26 members: IndexMap::default(),
27 }
28 }
29
30 pub fn add_member(mut self, name: String, value: Box<dyn Value>) -> Self {
31 self.members.insert(name, value);
32 self
33 }
34}
35
36impl Value for CompositeValue {
37 fn literal(&self) -> String {
38 let mut str = String::new();
39 let last_position = self.members.len() - 1;
40 str += "(";
41 for (pos, member) in self.members.iter().enumerate() {
42 str += &member.1.literal();
43 if pos != last_position {
44 str += ", ";
45 }
46 }
47 str += ")";
48 str
49 }
50
51 fn equals(&self, other: &Box<dyn Value>) -> bool {
52 if let Some(other_composite) = other.as_any().downcast_ref::<CompositeValue>() {
53 return self.name.eq(&other_composite.name)
54 && self.members.eq(&other_composite.members);
55 }
56 false
57 }
58
59 fn compare(&self, _other: &Box<dyn Value>) -> Option<Ordering> {
60 None
61 }
62
63 fn data_type(&self) -> Box<dyn DataType> {
64 let name = self.name.to_string();
65 let mut members: HashMap<String, Box<dyn DataType>> = HashMap::new();
66 for member in self.members.iter() {
67 members.insert(member.0.to_string(), member.1.data_type().clone());
68 }
69 Box::new(CompositeType::new(name, members))
70 }
71
72 fn as_any(&self) -> &dyn Any {
73 self
74 }
75}