Skip to main content

icydb_schema/node/
index_store.rs

1use crate::prelude::*;
2use canic_utils::case::{Case, Casing};
3
4///
5/// IndexStore
6///
7
8#[derive(Clone, Debug, Serialize)]
9pub struct IndexStore {
10    pub def: Def,
11    pub ident: &'static str,
12    pub canister: &'static str,
13    pub entry_memory_id: u8,
14    pub fingerprint_memory_id: u8,
15}
16
17impl MacroNode for IndexStore {
18    fn as_any(&self) -> &dyn std::any::Any {
19        self
20    }
21}
22
23impl ValidateNode for IndexStore {
24    fn validate(&self) -> Result<(), ErrorTree> {
25        let mut errs = ErrorTree::new();
26        let schema = schema_read();
27
28        match schema.cast_node::<Canister>(self.canister) {
29            Ok(canister) => {
30                let min = canister.memory_min;
31                let max = canister.memory_max;
32
33                if !(min..=max).contains(&self.entry_memory_id) {
34                    err!(
35                        errs,
36                        "entry_memory_id {} outside of range {}-{}",
37                        self.entry_memory_id,
38                        min,
39                        max
40                    );
41                }
42
43                if !(min..=max).contains(&self.fingerprint_memory_id) {
44                    err!(
45                        errs,
46                        "fingerprint_memory_id {} outside of range {}-{}",
47                        self.fingerprint_memory_id,
48                        min,
49                        max
50                    );
51                }
52
53                if self.entry_memory_id == self.fingerprint_memory_id {
54                    err!(
55                        errs,
56                        "entry_memory_id and fingerprint_memory_id must be distinct (both = {})",
57                        self.entry_memory_id
58                    );
59                }
60            }
61            Err(e) => errs.add(e),
62        }
63
64        if !self.ident.is_case(Case::UpperSnake) {
65            err!(errs, "ident '{}' must be UPPER_SNAKE_CASE", self.ident);
66        }
67
68        errs.result()
69    }
70}
71
72impl VisitableNode for IndexStore {
73    fn route_key(&self) -> String {
74        self.def.path()
75    }
76
77    fn drive<V: Visitor>(&self, v: &mut V) {
78        self.def.accept(v);
79    }
80}