hydrate_schema/schema/
record.rs

1use super::Schema;
2use crate::{
3    HashMap, SchemaDefRecordFieldMarkup, SchemaDefRecordMarkup, SchemaFingerprint, SchemaNamedType,
4};
5use std::ops::Deref;
6use std::sync::Arc;
7use uuid::Uuid;
8
9#[derive(Debug)]
10pub struct SchemaRecordField {
11    name: String,
12    aliases: Box<[String]>,
13    field_schema: Schema,
14    markup: SchemaDefRecordFieldMarkup,
15    field_uuid: Uuid,
16}
17
18impl SchemaRecordField {
19    pub fn new(
20        name: String,
21        field_uuid: Uuid,
22        aliases: Box<[String]>,
23        field_schema: Schema,
24        markup: SchemaDefRecordFieldMarkup,
25    ) -> Self {
26        SchemaRecordField {
27            name,
28            field_uuid,
29            aliases,
30            field_schema,
31            markup,
32        }
33    }
34
35    pub fn name(&self) -> &str {
36        &self.name
37    }
38
39    pub fn aliases(&self) -> &[String] {
40        &self.aliases
41    }
42
43    pub fn field_schema(&self) -> &Schema {
44        &self.field_schema
45    }
46
47    pub fn markup(&self) -> &SchemaDefRecordFieldMarkup {
48        &self.markup
49    }
50
51    pub fn field_uuid(&self) -> Uuid {
52        self.field_uuid
53    }
54}
55
56#[derive(Debug)]
57pub struct SchemaRecordInner {
58    name: String,
59    type_uuid: Uuid,
60    fingerprint: SchemaFingerprint,
61    aliases: Box<[String]>,
62    fields: Box<[SchemaRecordField]>,
63    markup: SchemaDefRecordMarkup,
64}
65
66#[derive(Clone, Debug)]
67pub struct SchemaRecord {
68    inner: Arc<SchemaRecordInner>,
69}
70
71impl Deref for SchemaRecord {
72    type Target = SchemaRecordInner;
73
74    fn deref(&self) -> &Self::Target {
75        &*self.inner
76    }
77}
78
79impl SchemaRecord {
80    pub fn new(
81        name: String,
82        type_uuid: Uuid,
83        fingerprint: SchemaFingerprint,
84        aliases: Box<[String]>,
85        mut fields: Vec<SchemaRecordField>,
86        markup: SchemaDefRecordMarkup,
87    ) -> Self {
88        // Check names are unique
89        for i in 0..fields.len() {
90            for j in 0..i {
91                assert_ne!(fields[i].name, fields[j].name);
92            }
93        }
94
95        fields.sort_by(|lhs, rhs| lhs.name.cmp(&rhs.name));
96
97        let inner = SchemaRecordInner {
98            name,
99            type_uuid,
100            fingerprint,
101            aliases,
102            fields: fields.into_boxed_slice(),
103            markup,
104        };
105
106        SchemaRecord {
107            inner: Arc::new(inner),
108        }
109    }
110
111    pub fn name(&self) -> &str {
112        &self.name
113    }
114
115    pub fn type_uuid(&self) -> Uuid {
116        self.type_uuid
117    }
118
119    pub fn fingerprint(&self) -> SchemaFingerprint {
120        self.fingerprint
121    }
122
123    pub fn aliases(&self) -> &[String] {
124        &*self.aliases
125    }
126
127    pub fn fields(&self) -> &[SchemaRecordField] {
128        &*self.fields
129    }
130
131    pub fn field_schema(
132        &self,
133        field_name: impl AsRef<str>,
134    ) -> Option<&Schema> {
135        for field in &*self.fields {
136            if field.name == field_name.as_ref() {
137                return Some(&field.field_schema);
138            }
139        }
140
141        None
142    }
143
144    pub fn find_property_schema(
145        &self,
146        path: impl AsRef<str>,
147        named_types: &HashMap<SchemaFingerprint, SchemaNamedType>,
148    ) -> Option<Schema> {
149        SchemaNamedType::Record(self.clone()).find_property_schema(path, named_types)
150    }
151
152    pub fn find_field_from_name(
153        &self,
154        field_name: &str,
155    ) -> Option<&SchemaRecordField> {
156        self.fields.iter().find(|x| x.name == field_name)
157    }
158
159    pub fn find_field_from_field_uuid(
160        &self,
161        field_uuid: Uuid,
162    ) -> Option<&SchemaRecordField> {
163        self.fields.iter().find(|x| x.field_uuid == field_uuid)
164    }
165
166    pub fn markup(&self) -> &SchemaDefRecordMarkup {
167        &self.markup
168    }
169}