Skip to main content

substrate_data/schema/plain/
maps.rs

1//! The schemas of maps by string keys.
2
3use std::collections::{BTreeMap, HashMap};
4use std::hash::BuildHasher;
5
6use crate::model::borrowed::ValueRef;
7use crate::model::value::{Seg, Value};
8use crate::schema::{Reader, Schema, Shape, is_metadata_key};
9
10/// `v`'s entries read as `T`s into `put`, source-only keys skipped.
11pub(super) fn read_map<T: Schema>(
12    v: &ValueRef<'_>,
13    cx: &mut Reader<'_>,
14    mut put: impl FnMut(String, T),
15) -> Option<()> {
16    let map = cx.map(v)?;
17    let mut ok = true;
18    for (k, item) in map.iter() {
19        if is_metadata_key(k) {
20            continue;
21        }
22        match cx.at(Seg::Key(k.to_string()), |cx| T::read(item, cx)) {
23            Some(x) => put(k.to_string(), x),
24            None => ok = false,
25        }
26    }
27    ok.then_some(())
28}
29
30impl<T: Schema> Schema for BTreeMap<String, T> {
31    fn shape() -> Shape {
32        Shape::Map(T::shape)
33    }
34    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
35        let mut out = BTreeMap::new();
36        read_map(v, cx, |k, x| {
37            out.insert(k, x);
38        })?;
39        Some(out)
40    }
41    fn write(&self) -> Value {
42        Value::Map(self.iter().map(|(k, v)| (k.clone(), v.write())).collect())
43    }
44    fn write_text(&self, w: &mut crate::text::Writer) {
45        w.map(self.len());
46        for (k, v) in self {
47            w.key(k);
48            v.write_text(w);
49        }
50    }
51}
52
53impl<T: Schema, S: BuildHasher + Default> Schema for HashMap<String, T, S> {
54    fn shape() -> Shape {
55        Shape::Map(T::shape)
56    }
57    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
58        let mut out = HashMap::default();
59        read_map(v, cx, |k, x| {
60            out.insert(k, x);
61        })?;
62        Some(out)
63    }
64    fn write(&self) -> Value {
65        let mut keys: Vec<&String> = self.keys().collect();
66        keys.sort();
67        Value::Map(
68            keys.into_iter()
69                .map(|k| (k.clone(), self[k].write()))
70                .collect(),
71        )
72    }
73}