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    name: &'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, name: &'static str, fields: FieldList, ty: Type) -> Self {
19        Self {
20            def,
21            name,
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 current declared type name.
34    #[must_use]
35    pub const fn name(&self) -> &'static str {
36        self.name
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_name(
62            &mut errs,
63            "record type",
64            self.name(),
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.name()) {
70                err!(errs, "duplicate record field name '{}'", field.name(),);
71            }
72        }
73        errs.result()
74    }
75}
76
77impl VisitableNode for Record {
78    fn route_key(&self) -> String {
79        self.def().path()
80    }
81
82    fn drive<V: Visitor>(&self, v: &mut V) {
83        self.def().accept(v);
84        self.fields().accept(v);
85        self.ty().accept(v);
86    }
87}