1extern crate self as icydb_model;
8
9pub mod application;
10pub mod base;
11pub mod build;
12pub mod error;
13pub mod fragment;
14#[cfg_attr(
18 target_arch = "wasm32",
19 allow(
20 dead_code,
21 reason = "Wasm retains declaration nodes while host code owns whole-graph traversal"
22 )
23)]
24pub mod node;
25pub mod normalize;
26#[cfg_attr(
27 target_arch = "wasm32",
28 expect(dead_code, reason = "whole-graph schema validation is host-owned")
29)]
30mod schema_validate;
31mod typed_adapter;
32pub mod types;
33pub mod validate;
34#[cfg_attr(
35 target_arch = "wasm32",
36 allow(
37 dead_code,
38 reason = "Wasm retains declarations while host code owns graph visitation"
39 )
40)]
41mod visit;
42pub mod visitor;
43
44use crate::{build::BuildError, node::NodeError};
45use thiserror::Error as ThisError;
46
47pub mod prelude {
49 pub(crate) use crate::build::schema_read;
50 pub use crate::{
51 EntitySource as _, Inner as _, NormalizeAndValidate as _, Path as _, base, canister,
52 entity, enum_, err,
53 error::ErrorTree,
54 list, map, newtype,
55 node::*,
56 normalizer, record,
57 schema::*,
58 set, store, tuple,
59 types::{Cardinality, Primitive},
60 validator,
61 visitor::{
62 Issue, Normalize as _, NormalizeAuto, NormalizeCustom, Normalizer as _, Validate as _,
63 ValidateAuto, ValidateCustom, Validator as _, Visitable as _, VisitorContext,
64 },
65 };
66 pub(crate) use crate::{
67 node::{MacroNode, ValidateNode, VisitableNode},
68 visit::Visitor,
69 };
70
71 pub use serde::{Deserialize, Serialize};
72}
73
74pub use application::NormalizeAndValidate;
75pub use icydb_model_macros::{
76 Add, AddAssign, Deref, DerefMut, Display, Div, DivAssign, Inner, Mul, MulAssign, Neg, Product,
77 Rem, RemAssign, Sub, SubAssign, Sum, canister, entity, enum_, list, map, newtype, normalizer,
78 record, set, store, tuple, validator,
79};
80pub use icydb_schema::MAX_INDEX_FIELDS;
81pub use normalize::normalize;
82#[doc(hidden)]
83pub use typed_adapter::{
84 TypedAdapterContext, TypedEnumDescriptor, TypedEnumSelection, TypedInputValue, TypedNamedType,
85 TypedOutputValue, TypedScalarValue, TypedValueError,
86};
87pub use validate::validate;
88
89pub trait Path {
91 const PATH: &'static str;
93}
94
95pub trait EntitySource {
101 const ENTITY: &'static str;
103}
104
105pub trait Inner<T> {
107 fn inner(&self) -> &T;
109
110 fn into_inner(self) -> T;
112}
113
114pub mod schema {
116 pub use icydb_schema::*;
117}
118
119#[doc(hidden)]
121pub mod __reexports {
122
123 #[cfg(not(target_arch = "wasm32"))]
124 pub use ctor;
125 pub use icydb_model_macros;
126 pub use remain;
127 pub use serde;
128}
129
130#[derive(Debug, ThisError)]
137pub enum Error {
138 #[error(transparent)]
139 BuildError(#[from] BuildError),
140
141 #[error(transparent)]
142 NodeError(#[from] NodeError),
143}
144
145#[cfg(test)]
150mod tests {
151 use super::{Error, build::BuildError, error::ErrorTree, node::NodeError};
152
153 #[test]
154 fn build_errors_remain_in_build_boundary() {
155 let schema_error = Error::from(BuildError::Validation(ErrorTree::from(
156 "missing schema relation target",
157 )));
158
159 match schema_error {
160 Error::BuildError(BuildError::Validation(tree)) => {
161 assert!(
162 tree.messages()
163 .iter()
164 .any(|message| message == "missing schema relation target"),
165 "build validation errors must remain wrapped as build-boundary failures",
166 );
167 }
168 Error::BuildError(BuildError::Graph(error)) => {
169 panic!("unexpected graph error: {error}");
170 }
171 Error::NodeError(_) => {
172 panic!("build validation failures must not be remapped into node-boundary errors");
173 }
174 }
175 }
176
177 #[test]
178 fn node_errors_remain_in_node_boundary() {
179 let schema_error = Error::from(NodeError::PathNotFound("entity.user_id".to_string()));
180
181 match schema_error {
182 Error::NodeError(NodeError::PathNotFound(path)) => {
183 assert_eq!(path, "entity.user_id");
184 }
185 Error::NodeError(NodeError::IncorrectNodeType(path)) => {
186 panic!("unexpected node error kind after conversion for path {path}");
187 }
188 Error::BuildError(_) => {
189 panic!("node errors must not be remapped into build-boundary failures");
190 }
191 }
192 }
193}