1mod arg;
2mod canister;
3mod def;
4mod entity;
5mod r#enum;
6mod field;
7mod index;
8mod item;
9mod list;
10mod map;
11mod newtype;
12mod primary_key;
13mod record;
14mod sanitizer;
15mod schema;
16mod set;
17mod store;
18mod tuple;
19mod r#type;
20mod validator;
21mod value;
22
23use crate::{
24 prelude::*,
25 visit::{Event, Visitor},
26};
27use std::any::Any;
28use thiserror::Error as ThisError;
29
30pub use arg::*;
31pub use canister::*;
32pub use def::*;
33pub use entity::*;
34pub use r#enum::*;
35pub use field::*;
36pub use index::*;
37pub use item::*;
38pub use list::*;
39pub use map::*;
40pub use newtype::*;
41pub use primary_key::*;
42pub use record::*;
43pub use sanitizer::*;
44pub use schema::*;
45pub use set::*;
46pub use store::*;
47pub use tuple::*;
48pub use r#type::*;
49pub use validator::*;
50pub use value::*;
51
52const RESERVED_INTERNAL_MEMORY_ID: u8 = u8::MAX;
53
54#[derive(Debug, ThisError)]
62pub enum NodeError {
63 #[error("{0} is an incorrect node type")]
64 IncorrectNodeType(String),
65
66 #[error("path not found: {0}")]
67 PathNotFound(String),
68}
69
70pub trait MacroNode: Any {
83 fn as_any(&self) -> &dyn Any;
84}
85
86pub trait TypeNode: MacroNode {
93 fn ty(&self) -> &Type;
94}
95
96pub trait ValidateNode {
104 fn validate(&self) -> Result<(), ErrorTree> {
105 Ok(())
106 }
107}
108
109pub trait VisitableNode: ValidateNode {
117 fn route_key(&self) -> String {
119 String::new()
120 }
121
122 fn accept<V: Visitor>(&self, visitor: &mut V) {
124 visitor.push(&self.route_key());
125 visitor.visit(self, Event::Enter);
126 self.drive(visitor);
127 visitor.visit(self, Event::Exit);
128 visitor.pop();
129 }
130
131 fn drive<V: Visitor>(&self, _: &mut V) {}
133}
134
135pub(crate) fn validate_memory_id_in_range(
137 errs: &mut ErrorTree,
138 label: &str,
139 memory_id: u8,
140 min: u8,
141 max: u8,
142) {
143 if memory_id < min || memory_id > max {
144 err!(errs, "{label} {memory_id} outside of range {min}-{max}");
145 }
146}
147
148pub(crate) fn validate_memory_id_not_reserved(errs: &mut ErrorTree, label: &str, memory_id: u8) {
150 if memory_id == RESERVED_INTERNAL_MEMORY_ID {
151 err!(
152 errs,
153 "{label} {memory_id} is reserved for stable-structures internals",
154 );
155 }
156}