1use std::{
2 collections::HashMap,
3 sync::{Arc, Mutex},
4};
5
6use crate::info::DisplayInfo;
7
8use super::{Data, MersData, MersDataWInfo, MersType, Type};
9
10#[derive(Debug, PartialEq, Clone)]
11pub struct Object(Vec<(usize, Data)>);
12impl Object {
13 pub fn new(v: Vec<(usize, Data)>) -> Self {
14 Self(v)
15 }
16 pub fn get(&self, f: usize) -> Option<&Data> {
17 self.iter().find(|v| v.0 == f).map(|v| &v.1)
18 }
19 pub fn iter(&self) -> std::slice::Iter<(usize, Data)> {
20 self.0.iter()
21 }
22}
23#[derive(Debug, Clone)]
24pub struct ObjectT(Vec<(usize, Type)>);
25impl ObjectT {
26 pub fn new(v: Vec<(usize, Type)>) -> Self {
27 Self(v)
28 }
29 pub fn get(&self, f: usize) -> Option<&Type> {
30 self.iter().find(|v| v.0 == f).map(|v| &v.1)
31 }
32 pub fn iter(&self) -> std::slice::Iter<(usize, Type)> {
33 self.0.iter()
34 }
35 fn len(&self) -> usize {
36 self.0.len()
37 }
38}
39
40impl MersData for Object {
41 fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42 let mut comma_sep = false;
43 write!(f, "{{")?;
44 for (field, val) in self.iter() {
45 if comma_sep {
46 write!(f, ", ")?;
47 }
48 write!(
49 f,
50 "{}: {}",
51 info.get_object_field_name(*field),
52 val.get().with_display(info)
53 )?;
54 comma_sep = true;
55 }
56 write!(f, "}}")?;
57 Ok(())
58 }
59 fn is_eq(&self, other: &dyn MersData) -> bool {
60 if let Some(other) = other.as_any().downcast_ref::<Self>() {
61 self == other
62 } else {
63 false
64 }
65 }
66 fn clone(&self) -> Box<dyn MersData> {
67 Box::new(Clone::clone(self))
68 }
69 fn as_type(&self) -> Type {
70 Type::new(ObjectT(
71 self.iter()
72 .map(|(n, v)| (n.clone(), v.get().as_type()))
73 .collect(),
74 ))
75 }
76 fn as_any(&self) -> &dyn std::any::Any {
77 self
78 }
79 fn mut_any(&mut self) -> &mut dyn std::any::Any {
80 self
81 }
82 fn to_any(self) -> Box<dyn std::any::Any> {
83 Box::new(self)
84 }
85}
86
87impl MersType for ObjectT {
88 fn display(
89 &self,
90 info: &crate::info::DisplayInfo<'_>,
91 f: &mut std::fmt::Formatter,
92 ) -> std::fmt::Result {
93 let mut comma_sep = false;
94 write!(f, "{{")?;
95 for (field, t) in self.iter() {
96 if comma_sep {
97 write!(f, ", ")?;
98 }
99 write!(
100 f,
101 "{}: {}",
102 info.get_object_field_name(*field),
103 t.with_display(info)
104 )?;
105 comma_sep = true;
106 }
107 write!(f, "}}")?;
108 Ok(())
109 }
110 fn is_same_type_as(&self, other: &dyn MersType) -> bool {
111 other.as_any().downcast_ref::<Self>().is_some_and(|other| {
112 self.len() == other.len()
113 && other.iter().all(|(field, target_type)| {
114 self.get(*field)
115 .is_some_and(|self_type| self_type.is_same_type_as(target_type))
116 })
117 })
118 }
119 fn is_included_in(&self, target: &dyn MersType) -> bool {
120 target
121 .as_any()
122 .downcast_ref::<Self>()
123 .is_some_and(|target| {
124 self.len() >= target.len()
125 && target.iter().all(|(field, target_type)| {
126 self.get(*field)
127 .is_some_and(|self_type| self_type.is_included_in(target_type))
128 })
129 })
130 }
131 fn without(&self, remove: &dyn MersType) -> Option<Type> {
132 let m = self.0.len();
133 if let Some(remove) = remove
134 .as_any()
135 .downcast_ref::<Self>()
136 .filter(|r| r.0.len() <= m)
137 {
138 let mut out = Type::empty();
139 for i1 in 0usize.. {
140 let mut self_tuple = Vec::with_capacity(m);
141 let mut i1 = i1;
142 for j in 0..m {
143 let mm = self.0[j].1.types.len();
144 self_tuple.push((self.0[j].0, &self.0[j].1.types[i1 % mm]));
145 i1 /= mm;
146 }
147 if i1 != 0 {
148 break;
149 }
150 let mut covered = false;
151 for i2 in 0usize.. {
152 let mut remove_tuple = Vec::with_capacity(m);
153 let mut i2 = i2;
154 for j in 0..remove.0.len() {
155 let mm = remove.0[j].1.types.len();
156 remove_tuple.push((remove.0[j].0, &remove.0[j].1.types[i2 % mm]));
157 i2 /= mm;
158 }
159 if i2 != 0 {
160 break;
161 }
162 if (0..m).all(|j| {
163 remove_tuple
164 .iter()
165 .find(|(v, _)| *v == self_tuple[j].0)
166 .is_none_or(|(_, r)| {
167 self_tuple[j].1.as_ref().is_included_in(r.as_ref())
168 })
169 }) {
170 covered = true;
171 break;
172 }
173 }
174 if !covered {
175 out.add(Arc::new(Self(
176 self_tuple
177 .iter()
178 .map(|(vi, v)| (*vi, Type::newm(vec![Arc::clone(v)])))
179 .collect(),
180 )));
181 }
182 }
183 Some(out)
184 } else {
185 None
186 }
187 }
188 fn as_any(&self) -> &dyn std::any::Any {
189 self
190 }
191 fn mut_any(&mut self) -> &mut dyn std::any::Any {
192 self
193 }
194 fn to_any(self) -> Box<dyn std::any::Any> {
195 Box::new(self)
196 }
197 fn simplify_for_display(&self, info: &crate::program::run::CheckInfo) -> Option<Type> {
198 Some(Type::new(Self(
199 self.0
200 .iter()
201 .map(|(n, t)| (n.clone(), t.simplify_for_display(info)))
202 .collect(),
203 )))
204 }
205}
206
207pub trait ObjectFieldsMap {
208 fn get_or_add_field(&self, field: &str) -> usize;
209}
210impl ObjectFieldsMap for Arc<Mutex<HashMap<String, usize>>> {
211 fn get_or_add_field(&self, field: &str) -> usize {
212 let mut s = self.lock().unwrap();
213 if let Some(f) = s.get(field) {
214 return *f;
215 }
216 let o = s.len();
217 s.insert(field.to_owned(), o);
218 o
219 }
220}