mech_core/structures/
map.rs

1use crate::*;
2use indexmap::map::*;
3
4// Map ------------------------------------------------------------------
5
6#[cfg(feature = "map")]
7#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct MechMap {
9  pub key_kind: ValueKind,
10  pub value_kind: ValueKind,
11  pub num_elements: usize,
12  pub map: IndexMap<Value,Value>,
13}
14
15#[cfg(feature = "map")]
16impl MechMap {
17
18  #[cfg(feature = "pretty_print")]
19  pub fn to_html(&self) -> String {
20    let mut src = String::new();
21    for (i, (key, value)) in self.map.iter().enumerate() {
22      let k = key.to_html();
23      let v = value.to_html();
24      if i == 0 {
25        src = format!("{}: {}", k, v);
26      } else {
27        src = format!("{}, {}: {}", src, k, v);
28      }
29    }
30    format!("<span class=\"mech-map\"><span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span></span>",src)
31  }
32
33  pub fn kind(&self) -> ValueKind {
34    ValueKind::Map(Box::new(self.key_kind.clone()), Box::new(self.value_kind.clone()))
35  }
36
37  pub fn size_of(&self) -> usize {
38    self.map.iter().map(|(k,v)| k.size_of() + v.size_of()).sum()
39  }
40
41  pub fn from_vec(vec: Vec<(Value,Value)>) -> MechMap {
42    let mut map = IndexMap::new();
43    for (k,v) in vec {
44      map.insert(k,v);
45    }
46    MechMap{
47      key_kind: map.keys().next().unwrap().kind(),
48      value_kind: map.values().next().unwrap().kind(),
49      num_elements: map.len(),
50      map}
51  }
52}
53
54#[cfg(feature = "pretty_print")]
55impl PrettyPrint for MechMap {
56  fn pretty_print(&self) -> String {
57    let mut builder = Builder::default();
58    let mut element_strings = vec![];
59    let mut key_strings = vec![];
60    for (k,v) in self.map.iter() {
61      element_strings.push(v.pretty_print());
62      key_strings.push(k.pretty_print());
63    }    
64    builder.push_record(key_strings);
65    builder.push_record(element_strings);
66    let mut table = builder.build();
67    table.with(Style::modern_rounded());
68    format!("{table}")
69  }
70}
71
72#[cfg(feature = "map")]
73impl Hash for MechMap {
74  fn hash<H: Hasher>(&self, state: &mut H) {
75    for x in self.map.iter() {
76      x.hash(state)
77    }
78  }
79}
80
81#[derive(Debug, Clone)]
82pub struct MapKeyKindMismatchError {
83  pub expected_kind: ValueKind,
84  pub actual_kind: ValueKind,
85}
86impl MechErrorKind2 for MapKeyKindMismatchError {
87  fn name(&self) -> &str {
88    "MapKeyKindMismatch"
89  }
90
91  fn message(&self) -> String {
92    format!(
93      "Map key kind mismatch (expected `{}`, found `{}`).",
94      self.expected_kind, self.actual_kind
95    )
96  }
97}
98
99#[derive(Debug, Clone)]
100pub struct MapValueKindMismatchError {
101  pub expected_kind: ValueKind,
102  pub actual_kind: ValueKind,
103}
104impl MechErrorKind2 for MapValueKindMismatchError {
105  fn name(&self) -> &str {
106    "MapValueKindMismatch"
107  }
108
109  fn message(&self) -> String {
110    format!(
111      "Map value kind mismatch (expected `{}`, found `{}`).",
112      self.expected_kind, self.actual_kind
113    )
114  }
115}