mech_core/structures/
set.rs1use crate::*;
2use indexmap::set::{IndexSet, Iter};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct MechSet {
8 pub kind: ValueKind,
9 pub num_elements: usize,
10 pub set: IndexSet<Value>,
11}
12
13impl MechSet {
14
15 pub fn new(kind: ValueKind, size: usize) -> MechSet {
16 MechSet{
17 kind,
18 num_elements: size,
19 set: IndexSet::with_capacity(size)
20 }
21 }
22
23 #[cfg(feature = "pretty_print")]
24 pub fn to_html(&self) -> String {
25 let mut src = String::new();
26 for (i, element) in self.set.iter().enumerate() {
27 let e = element.to_html();
28 if i == 0 {
29 src = format!("{}", e);
30 } else {
31 src = format!("{}, {}", src, e);
32 }
33 }
34 format!("<span class=\"mech-set\"><span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span></span>",src)
35 }
36
37 pub fn kind(&self) -> ValueKind {
38 let size = if self.num_elements > 0 { Some(self.num_elements) } else { None };
39 ValueKind::Set(Box::new(self.kind.clone()), size)
40 }
41
42 pub fn size_of(&self) -> usize {
43 self.set.iter().map(|x| x.size_of()).sum()
44 }
45
46 pub fn from_vec(vec: Vec<Value>) -> MechSet {
47 let mut set = IndexSet::new();
48 for v in vec {
49 set.insert(v);
50 }
51 let kind = if set.len() > 0 { set.iter().next().unwrap().kind() } else { ValueKind::Empty };
52 MechSet{
53 kind,
54 num_elements: set.len(),
55 set}
56 }
57
58 pub fn from_set(set: IndexSet<Value>) -> MechSet {
59 let kind = if set.len() > 0 { set.iter().next().unwrap().kind() } else { ValueKind::Empty };
60 MechSet{
61 kind,
62 num_elements: set.len(),
63 set}
64 }
65
66}
67
68#[cfg(feature = "pretty_print")]
69impl PrettyPrint for MechSet {
70 fn pretty_print(&self) -> String {
71 let mut builder = Builder::default();
72 let mut element_strings = vec![];
73 for x in self.set.iter() {
74 element_strings.push(x.pretty_print());
75 }
76 builder.push_record(element_strings);
77
78 let style = Style::empty()
79 .top(' ')
80 .left('║')
81 .right('║')
82 .bottom(' ')
83 .vertical(' ')
84 .intersection_bottom(' ')
85 .corner_top_left('╔')
86 .corner_top_right('╗')
87 .corner_bottom_left('╚')
88 .corner_bottom_right('╝');
89 let mut table = builder.build();
90 table.with(style);
91 format!("{table}")
92 }
93}
94
95impl Hash for MechSet {
96 fn hash<H: Hasher>(&self, state: &mut H) {
97 for x in self.set.iter() {
98 x.hash(state)
99 }
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct SetKindMismatchError {
105 pub expected_kind: ValueKind,
106 pub actual_kind: ValueKind,
107}
108impl MechErrorKind2 for SetKindMismatchError {
109 fn name(&self) -> &str { "SetKindMismatch" }
110 fn message(&self) -> String {
111 format!("Schema mismatch: set kind mismatch (expected: {}, found: {}).",
112 self.expected_kind, self.actual_kind)
113 }
114}