icydb_schema/node/
item.rs1use crate::prelude::*;
2use std::ops::Not;
3
4#[derive(Clone, Debug, Serialize)]
9pub struct Item {
10 pub target: ItemTarget,
11
12 #[serde(default, skip_serializing_if = "Option::is_none")]
13 pub relation: Option<&'static str>,
14
15 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
16 pub validators: &'static [TypeValidator],
17
18 #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
19 pub sanitizers: &'static [TypeSanitizer],
20
21 #[serde(default, skip_serializing_if = "Not::not")]
22 pub indirect: bool,
23}
24
25impl Item {
26 #[must_use]
27 pub const fn is_relation(&self) -> bool {
28 self.relation.is_some()
29 }
30}
31
32impl ValidateNode for Item {
33 fn validate(&self) -> Result<(), ErrorTree> {
34 let mut errs = ErrorTree::new();
35 let schema = schema_read();
36
37 match &self.target {
38 ItemTarget::Is(path) => {
39 if schema.check_node_as::<Entity>(path).is_ok() {
41 err!(errs, "a non-relation Item cannot reference an Entity");
42 }
43 }
44
45 ItemTarget::Primitive(_) => {}
46 }
47
48 if let Some(relation) = &self.relation {
50 if self.indirect {
51 err!(errs, "relations cannot be set to indirect");
52 }
53
54 match schema.cast_node::<Entity>(relation) {
56 Ok(entity) => {
57 if let Some(primary_field) = entity.get_pk_field() {
59 let relation_target = &primary_field.value.item.target;
60
61 if &self.target != relation_target {
63 err!(
64 errs,
65 "relation target type mismatch: expected {:?}, found {:?}",
66 relation_target,
67 self.target
68 );
69 }
70 } else {
71 err!(
72 errs,
73 "relation entity '{relation}' missing primary key field '{0}'",
74 entity.primary_key
75 );
76 }
77 }
78 Err(_) => {
79 err!(errs, "relation entity '{relation}' not found");
80 }
81 }
82 }
83
84 errs.result()
85 }
86}
87
88impl VisitableNode for Item {
89 fn drive<V: Visitor>(&self, v: &mut V) {
90 for node in self.validators {
91 node.accept(v);
92 }
93 }
94}
95
96#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
101pub enum ItemTarget {
102 Is(&'static str),
103 Primitive(Primitive),
104}