hydrate_data/
schema_set.rs1use crate::value::ValueEnum;
2use crate::{
3 DataSetError, DataSetResult, HashMap, SchemaFingerprint, SchemaLinker, SchemaLinkerResult,
4 SchemaNamedType, Value,
5};
6use std::sync::Arc;
7use uuid::Uuid;
8
9#[derive(Default)]
13pub struct SchemaSetBuilder {
14 schemas_by_type_uuid: HashMap<Uuid, SchemaFingerprint>,
15 schemas_by_name: HashMap<String, SchemaFingerprint>,
16 schemas: HashMap<SchemaFingerprint, SchemaNamedType>,
17 default_enum_values: HashMap<SchemaFingerprint, Value>,
18}
19
20impl SchemaSetBuilder {
21 pub fn build(self) -> SchemaSet {
22 let inner = SchemaSetInner {
23 schemas_by_type_uuid: self.schemas_by_type_uuid,
24 schemas_by_name: self.schemas_by_name,
25 schemas: self.schemas,
26 default_enum_values: self.default_enum_values,
27 };
28
29 SchemaSet {
30 inner: Arc::new(inner),
31 }
32 }
33
34 pub fn add_linked_types(
35 &mut self,
36 linker: SchemaLinker,
37 ) -> SchemaLinkerResult<()> {
38 let linked = linker.link_schemas()?;
39
40 for (k, v) in linked.schemas {
43 if let Some(enum_schema) = v.try_as_enum() {
44 let default_value = Value::Enum(ValueEnum::new(
45 enum_schema.default_value().name().to_string(),
46 ));
47 let old = self.default_enum_values.insert(k, default_value.clone());
48 if let Some(old) = old {
49 assert_eq!(old.as_enum().unwrap(), default_value.as_enum().unwrap());
50 }
51 }
52 let v_fingerprint = v.fingerprint();
53 let old = self.schemas.insert(k, v);
54 if let Some(old) = old {
55 assert_eq!(old.fingerprint(), v_fingerprint);
56 }
57 }
58
59 for (k, v) in linked.schemas_by_name {
60 let old = self.schemas_by_name.insert(k, v);
61 assert!(old.is_none());
62 }
63
64 for (k, v) in linked.schemas_by_type_uuid {
65 let old = self.schemas_by_type_uuid.insert(k, v);
66 assert!(old.is_none());
67 }
68
69 Ok(())
70 }
71
72 pub fn restore_named_types(
73 &mut self,
74 named_types: Vec<SchemaNamedType>,
75 ) {
76 for named_type in named_types {
77 self.schemas.insert(named_type.fingerprint(), named_type);
78 }
79 }
80}
81
82pub struct SchemaSetInner {
83 schemas_by_type_uuid: HashMap<Uuid, SchemaFingerprint>,
84 schemas_by_name: HashMap<String, SchemaFingerprint>,
85 schemas: HashMap<SchemaFingerprint, SchemaNamedType>,
86 default_enum_values: HashMap<SchemaFingerprint, Value>,
87}
88
89#[derive(Clone)]
90pub struct SchemaSet {
91 inner: Arc<SchemaSetInner>,
92}
93
94impl SchemaSet {
95 pub fn schemas(&self) -> &HashMap<SchemaFingerprint, SchemaNamedType> {
96 &self.inner.schemas
97 }
98
99 pub fn schemas_by_type_uuid(&self) -> &HashMap<Uuid, SchemaFingerprint> {
100 &self.inner.schemas_by_type_uuid
101 }
102
103 pub fn default_value_for_enum(
104 &self,
105 fingerprint: SchemaFingerprint,
106 ) -> Option<&Value> {
107 self.inner.default_enum_values.get(&fingerprint)
108 }
109
110 pub fn find_named_type_by_type_uuid(
111 &self,
112 type_uuid: Uuid,
113 ) -> DataSetResult<&SchemaNamedType> {
114 Ok(self
115 .try_find_named_type_by_type_uuid(type_uuid)
116 .ok_or(DataSetError::SchemaNotFound)?)
117 }
118
119 pub fn try_find_named_type_by_type_uuid(
120 &self,
121 type_uuid: Uuid,
122 ) -> Option<&SchemaNamedType> {
123 self.inner
124 .schemas_by_type_uuid
125 .get(&type_uuid)
126 .map(|fingerprint| self.find_named_type_by_fingerprint(*fingerprint))
127 .flatten()
128 }
129
130 pub fn find_named_type(
131 &self,
132 name: impl AsRef<str>,
133 ) -> DataSetResult<&SchemaNamedType> {
134 Ok(self
135 .try_find_named_type(name)
136 .ok_or(DataSetError::SchemaNotFound)?)
137 }
138
139 pub fn try_find_named_type(
140 &self,
141 name: impl AsRef<str>,
142 ) -> Option<&SchemaNamedType> {
143 self.inner
144 .schemas_by_name
145 .get(name.as_ref())
146 .map(|fingerprint| self.find_named_type_by_fingerprint(*fingerprint))
147 .flatten()
148 }
149
150 pub fn find_named_type_by_fingerprint(
151 &self,
152 fingerprint: SchemaFingerprint,
153 ) -> Option<&SchemaNamedType> {
154 self.inner.schemas.get(&fingerprint)
155 }
156}