Skip to main content

icydb_schema/node/
store.rs

1use crate::node::{validate_memory_id_in_range, validate_memory_id_not_reserved};
2use crate::prelude::*;
3
4///
5/// Store
6///
7/// Schema node describing a stable IC BTreeMap pair that stores:
8/// - primary entity data
9/// - all index data for that entity
10///
11
12#[derive(Clone, Debug, Serialize)]
13pub struct Store {
14    pub def: Def,
15    pub ident: &'static str,
16    pub canister: &'static str,
17    pub data_memory_id: u8,
18    pub index_memory_id: u8,
19}
20
21impl MacroNode for Store {
22    fn as_any(&self) -> &dyn std::any::Any {
23        self
24    }
25}
26
27impl ValidateNode for Store {
28    fn validate(&self) -> Result<(), ErrorTree> {
29        let mut errs = ErrorTree::new();
30        let schema = schema_read();
31
32        match schema.cast_node::<Canister>(self.canister) {
33            Ok(canister) => {
34                // Validate data memory ID
35                validate_memory_id_in_range(
36                    &mut errs,
37                    "data_memory_id",
38                    self.data_memory_id,
39                    canister.memory_min,
40                    canister.memory_max,
41                );
42                validate_memory_id_not_reserved(&mut errs, "data_memory_id", self.data_memory_id);
43
44                // Validate index memory ID
45                validate_memory_id_in_range(
46                    &mut errs,
47                    "index_memory_id",
48                    self.index_memory_id,
49                    canister.memory_min,
50                    canister.memory_max,
51                );
52                validate_memory_id_not_reserved(&mut errs, "index_memory_id", self.index_memory_id);
53
54                // Ensure they are not the same
55                if self.data_memory_id == self.index_memory_id {
56                    err!(
57                        errs,
58                        "data_memory_id and index_memory_id must differ (both are {})",
59                        self.data_memory_id,
60                    );
61                }
62            }
63            Err(e) => errs.add(e),
64        }
65
66        errs.result()
67    }
68}
69
70impl VisitableNode for Store {
71    fn route_key(&self) -> String {
72        self.def.path()
73    }
74
75    fn drive<V: Visitor>(&self, v: &mut V) {
76        self.def.accept(v);
77    }
78}