mers_lib/data/
object.rs

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}