Skip to main content

icydb_schema/node/
entity.rs

1use crate::prelude::*;
2use std::any::Any;
3
4///
5/// Entity
6///
7
8#[derive(Clone, Debug, Serialize)]
9pub struct Entity {
10    pub def: Def,
11    pub store: &'static str,
12    pub primary_key: &'static str,
13
14    #[serde(default, skip_serializing_if = "Option::is_none")]
15    pub name: Option<&'static str>,
16
17    #[serde(default, skip_serializing_if = "<[_]>::is_empty")]
18    pub indexes: &'static [Index],
19
20    pub fields: FieldList,
21    pub ty: Type,
22}
23
24impl Entity {
25    #[must_use]
26    /// Return the primary key field if it exists on the entity.
27    pub fn get_pk_field(&self) -> Option<&Field> {
28        self.fields.get(self.primary_key)
29    }
30
31    #[must_use]
32    /// Resolve the entity name used for schema identity.
33    pub fn resolved_name(&self) -> &'static str {
34        self.name.unwrap_or(self.def.ident)
35    }
36}
37
38impl MacroNode for Entity {
39    fn as_any(&self) -> &dyn Any {
40        self
41    }
42}
43
44impl TypeNode for Entity {
45    fn ty(&self) -> &Type {
46        &self.ty
47    }
48}
49
50impl ValidateNode for Entity {
51    fn validate(&self) -> Result<(), ErrorTree> {
52        let mut errs = ErrorTree::new();
53        let schema = schema_read();
54
55        // store
56        match schema.cast_node::<DataStore>(self.store) {
57            Ok(_) => {}
58            Err(e) => errs.add(e),
59        }
60
61        // Validate index store references.
62        for index in self.indexes {
63            // Indexing is hash-based over Value equality for all variants; collisions surface as corruption.
64            // index store
65            match schema.cast_node::<IndexStore>(index.store) {
66                Ok(_) => {}
67                Err(e) => errs.add(e),
68            }
69        }
70
71        errs.result()
72    }
73}
74
75impl VisitableNode for Entity {
76    fn route_key(&self) -> String {
77        self.def.path()
78    }
79
80    fn drive<V: Visitor>(&self, v: &mut V) {
81        self.def.accept(v);
82        self.fields.accept(v);
83        self.ty.accept(v);
84    }
85}