Skip to main content

icydb_model/node/
record.rs

1use crate::prelude::*;
2
3///
4/// Record
5///
6
7#[derive(Clone, Debug, Serialize)]
8pub struct Record {
9    def: Def,
10    source_key: &'static str,
11    fields: FieldList,
12    ty: Type,
13}
14
15impl Record {
16    /// Creates a record node from its canonical schema parts.
17    #[must_use]
18    pub const fn new(def: Def, source_key: &'static str, fields: FieldList, ty: Type) -> Self {
19        Self {
20            def,
21            source_key,
22            fields,
23            ty,
24        }
25    }
26
27    /// Returns the definition metadata for this record node.
28    #[must_use]
29    pub const fn def(&self) -> &Def {
30        &self.def
31    }
32
33    /// Returns the immutable type source key.
34    #[must_use]
35    pub const fn source_key(&self) -> &'static str {
36        self.source_key
37    }
38
39    /// Returns the record field list.
40    #[must_use]
41    pub const fn fields(&self) -> &FieldList {
42        &self.fields
43    }
44
45    /// Returns the canonical runtime type descriptor.
46    #[must_use]
47    pub const fn ty(&self) -> &Type {
48        &self.ty
49    }
50}
51
52impl MacroNode for Record {
53    fn as_any(&self) -> &dyn std::any::Any {
54        self
55    }
56}
57
58impl ValidateNode for Record {
59    fn validate(&self) -> Result<(), ErrorTree> {
60        let mut errs = ErrorTree::new();
61        validate_source_key(
62            &mut errs,
63            "record type",
64            self.source_key(),
65            icydb_schema::TypeSourceKey::try_new,
66        );
67        let mut seen = std::collections::BTreeSet::new();
68        for field in self.fields().fields() {
69            if !seen.insert(field.source_key()) {
70                err!(
71                    errs,
72                    "duplicate record field source key '{}'",
73                    field.source_key(),
74                );
75            }
76        }
77        errs.result()
78    }
79}
80
81impl VisitableNode for Record {
82    fn route_key(&self) -> String {
83        self.def().path()
84    }
85
86    fn drive<V: Visitor>(&self, v: &mut V) {
87        self.def().accept(v);
88        self.fields().accept(v);
89        self.ty().accept(v);
90    }
91}