mech_core/structures/
set.rs

1use crate::*;
2use indexmap::set::{IndexSet, Iter};
3
4// Set --------------------------------------------------------------------------
5
6#[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}