hydrate_schema/schema_cache/
mod.rs1use crate::{
7 HashMap, Schema, SchemaDefRecordFieldMarkup, SchemaDefRecordMarkup, SchemaDynamicArray,
8 SchemaEnum, SchemaEnumSymbol, SchemaFingerprint, SchemaMap, SchemaNamedType, SchemaRecord,
9 SchemaRecordField, SchemaStaticArray,
10};
11use serde::{Deserialize, Serialize};
12use uuid::Uuid;
13
14#[derive(Debug, Serialize, Deserialize)]
15struct CachedSchemaStaticArray {
16 item_type: Box<CachedSchema>,
17 length: usize,
18}
19
20impl CachedSchemaStaticArray {
21 fn new_from_schema(schema: &SchemaStaticArray) -> Self {
22 CachedSchemaStaticArray {
23 item_type: Box::new(CachedSchema::new_from_schema(schema.item_type())),
24 length: schema.length,
25 }
26 }
27
28 fn to_schema(self) -> SchemaStaticArray {
29 SchemaStaticArray::new(Box::new(self.item_type.to_schema()), self.length)
30 }
31}
32
33#[derive(Debug, Serialize, Deserialize)]
34struct CachedSchemaDynamicArray {
35 item_type: Box<CachedSchema>,
36}
37
38impl CachedSchemaDynamicArray {
39 fn new_from_schema(schema: &SchemaDynamicArray) -> Self {
40 CachedSchemaDynamicArray {
41 item_type: Box::new(CachedSchema::new_from_schema(schema.item_type())),
42 }
43 }
44
45 fn to_schema(self) -> SchemaDynamicArray {
46 SchemaDynamicArray::new(Box::new(self.item_type.to_schema()))
47 }
48}
49
50#[derive(Debug, Serialize, Deserialize)]
51struct CachedSchemaMap {
52 key_type: Box<CachedSchema>,
53 value_type: Box<CachedSchema>,
54}
55
56impl CachedSchemaMap {
57 fn new_from_schema(schema: &SchemaMap) -> Self {
58 CachedSchemaMap {
59 key_type: Box::new(CachedSchema::new_from_schema(schema.key_type())),
60 value_type: Box::new(CachedSchema::new_from_schema(schema.value_type())),
61 }
62 }
63
64 fn to_schema(self) -> SchemaMap {
65 SchemaMap::new(
66 Box::new(self.key_type.to_schema()),
67 Box::new(self.value_type.to_schema()),
68 )
69 }
70}
71
72#[derive(Debug, Serialize, Deserialize)]
73struct CachedSchemaRecordField {
74 name: String,
75 field_uuid: Uuid,
76 #[serde(skip_serializing_if = "Vec::is_empty", default)]
77 aliases: Vec<String>,
78 field_schema: Box<CachedSchema>,
79}
80
81impl CachedSchemaRecordField {
82 fn new_from_schema(schema: &SchemaRecordField) -> Self {
83 CachedSchemaRecordField {
84 name: schema.name().to_string(),
85 field_uuid: schema.field_uuid(),
86 aliases: schema.aliases().iter().cloned().collect(),
87 field_schema: Box::new(CachedSchema::new_from_schema(schema.field_schema())),
88 }
89 }
90
91 fn to_schema(self) -> SchemaRecordField {
92 SchemaRecordField::new(
93 self.name,
94 self.field_uuid,
95 self.aliases.into_boxed_slice(),
96 self.field_schema.to_schema(),
97 SchemaDefRecordFieldMarkup::default(),
98 )
99 }
100}
101
102#[derive(Debug, Serialize, Deserialize)]
103pub struct CachedSchemaRecord {
104 name: String,
105 type_uuid: Uuid,
106 fingerprint: Uuid,
107 #[serde(skip_serializing_if = "Vec::is_empty", default)]
108 aliases: Vec<String>,
109 fields: Vec<CachedSchemaRecordField>,
110}
111
112impl CachedSchemaRecord {
113 fn new_from_schema(schema: &SchemaRecord) -> Self {
114 let mut fields = Vec::with_capacity(schema.fields().len());
115 for field in schema.fields() {
116 fields.push(CachedSchemaRecordField::new_from_schema(field));
117 }
118
119 CachedSchemaRecord {
120 name: schema.name().to_string(),
121 type_uuid: schema.type_uuid(),
122 fingerprint: schema.fingerprint().as_uuid(),
123 aliases: schema.aliases().iter().cloned().collect(),
124 fields,
125 }
126 }
127
128 fn to_schema(self) -> SchemaRecord {
129 let mut fields = Vec::with_capacity(self.fields.len());
130 for field in self.fields {
131 fields.push(field.to_schema());
132 }
133
134 SchemaRecord::new(
135 self.name,
136 self.type_uuid,
137 SchemaFingerprint(self.fingerprint.as_u128()),
138 self.aliases.into_boxed_slice(),
139 fields,
140 SchemaDefRecordMarkup::default(),
141 )
142 }
143}
144
145#[derive(Debug, Serialize, Deserialize)]
146struct CachedSchemaEnumSymbol {
147 name: String,
148 symbol_uuid: Uuid,
149 #[serde(skip_serializing_if = "Vec::is_empty", default)]
150 aliases: Vec<String>,
151 }
153
154impl CachedSchemaEnumSymbol {
155 fn new_from_schema(schema: &SchemaEnumSymbol) -> Self {
156 CachedSchemaEnumSymbol {
157 name: schema.name().to_string(),
158 symbol_uuid: schema.symbol_uuid(),
159 aliases: schema.aliases().iter().cloned().collect(),
160 }
162 }
163
164 fn to_schema(self) -> SchemaEnumSymbol {
165 SchemaEnumSymbol::new(
166 self.name,
167 self.symbol_uuid,
168 self.aliases.into_boxed_slice(), )
170 }
171}
172
173#[derive(Debug, Serialize, Deserialize)]
174pub struct CachedSchemaEnum {
175 name: String,
176 type_uuid: Uuid,
177 fingerprint: Uuid,
178 #[serde(skip_serializing_if = "Vec::is_empty", default)]
179 aliases: Vec<String>,
180 symbols: Vec<CachedSchemaEnumSymbol>,
181}
182
183impl CachedSchemaEnum {
184 fn new_from_schema(schema: &SchemaEnum) -> Self {
185 let mut symbols = Vec::with_capacity(schema.symbols().len());
186 for field in schema.symbols() {
187 symbols.push(CachedSchemaEnumSymbol::new_from_schema(field));
188 }
189
190 CachedSchemaEnum {
191 name: schema.name().to_string(),
192 type_uuid: schema.type_uuid(),
193 fingerprint: schema.fingerprint().as_uuid(),
194 aliases: schema.aliases().iter().cloned().collect(),
195 symbols,
196 }
197 }
198
199 fn to_schema(self) -> SchemaEnum {
200 let mut symbols = Vec::with_capacity(self.symbols.len());
201 for symbol in self.symbols {
202 symbols.push(symbol.to_schema());
203 }
204
205 SchemaEnum::new(
206 self.name,
207 self.type_uuid,
208 SchemaFingerprint(self.fingerprint.as_u128()),
209 self.aliases.into_boxed_slice(),
210 symbols.into_boxed_slice(),
211 )
212 }
213}
214
215#[derive(Debug, Serialize, Deserialize)]
216pub enum CachedSchemaNamedType {
217 Record(CachedSchemaRecord),
218 Enum(CachedSchemaEnum),
219}
220
221impl CachedSchemaNamedType {
222 pub fn fingerprint(&self) -> Uuid {
223 match self {
224 CachedSchemaNamedType::Record(x) => x.fingerprint,
225 CachedSchemaNamedType::Enum(x) => x.fingerprint,
226 }
227 }
228
229 pub fn new_from_schema(schema: &SchemaNamedType) -> CachedSchemaNamedType {
230 match schema {
231 SchemaNamedType::Record(x) => {
232 CachedSchemaNamedType::Record(CachedSchemaRecord::new_from_schema(x))
233 }
234 SchemaNamedType::Enum(x) => {
235 CachedSchemaNamedType::Enum(CachedSchemaEnum::new_from_schema(x))
236 }
237 }
238 }
239
240 pub fn to_schema(self) -> SchemaNamedType {
241 match self {
242 CachedSchemaNamedType::Record(x) => SchemaNamedType::Record(x.to_schema()),
243 CachedSchemaNamedType::Enum(x) => SchemaNamedType::Enum(x.to_schema()),
244 }
245 }
246}
247
248#[derive(Debug, Serialize, Deserialize)]
249enum CachedSchema {
250 Nullable(Box<CachedSchema>),
252 Boolean,
253 I32,
254 I64,
255 U32,
256 U64,
257 F32,
258 F64,
259 Bytes,
261 String,
263 StaticArray(CachedSchemaStaticArray),
265 DynamicArray(CachedSchemaDynamicArray),
266 Map(CachedSchemaMap),
267 AssetRef(Uuid),
269 Record(Uuid),
271 Enum(Uuid),
272}
273
274impl CachedSchema {
275 fn new_from_schema(schema: &Schema) -> CachedSchema {
276 match schema {
277 Schema::Nullable(inner_schema) => {
278 CachedSchema::Nullable(Box::new(CachedSchema::new_from_schema(&*inner_schema)))
279 }
280 Schema::Boolean => CachedSchema::Boolean,
281 Schema::I32 => CachedSchema::I32,
282 Schema::I64 => CachedSchema::I64,
283 Schema::U32 => CachedSchema::U32,
284 Schema::U64 => CachedSchema::U64,
285 Schema::F32 => CachedSchema::F32,
286 Schema::F64 => CachedSchema::F64,
287 Schema::Bytes => CachedSchema::Bytes,
288 Schema::String => CachedSchema::String,
289 Schema::StaticArray(x) => {
290 CachedSchema::StaticArray(CachedSchemaStaticArray::new_from_schema(x))
291 }
292 Schema::DynamicArray(x) => {
293 CachedSchema::DynamicArray(CachedSchemaDynamicArray::new_from_schema(x))
294 }
295 Schema::Map(x) => CachedSchema::Map(CachedSchemaMap::new_from_schema(x)),
296 Schema::AssetRef(x) => CachedSchema::AssetRef(x.as_uuid()),
298 Schema::Record(x) => CachedSchema::Record(x.as_uuid()),
299 Schema::Enum(x) => CachedSchema::Enum(x.as_uuid()),
300 }
301 }
302
303 fn to_schema(self) -> Schema {
304 match self {
305 CachedSchema::Nullable(x) => Schema::Nullable(Box::new(x.to_schema())),
306 CachedSchema::Boolean => Schema::Boolean,
307 CachedSchema::I32 => Schema::I32,
308 CachedSchema::I64 => Schema::I64,
309 CachedSchema::U32 => Schema::U32,
310 CachedSchema::U64 => Schema::U64,
311 CachedSchema::F32 => Schema::F32,
312 CachedSchema::F64 => Schema::F64,
313 CachedSchema::Bytes => Schema::Bytes,
314 CachedSchema::String => Schema::String,
315 CachedSchema::StaticArray(x) => Schema::StaticArray(x.to_schema()),
316 CachedSchema::DynamicArray(x) => Schema::DynamicArray(x.to_schema()),
317 CachedSchema::Map(x) => Schema::Map(x.to_schema()),
318 CachedSchema::AssetRef(x) => Schema::AssetRef(SchemaFingerprint(x.as_u128())),
319 CachedSchema::Record(x) => Schema::Record(SchemaFingerprint(x.as_u128())),
320 CachedSchema::Enum(x) => Schema::Enum(SchemaFingerprint(x.as_u128())),
321 }
322 }
323}
324
325#[derive(Debug, Serialize, Deserialize, Default)]
328pub struct SchemaCacheSingleFile {
329 cached_schemas: Vec<CachedSchemaNamedType>,
330}
331
332impl SchemaCacheSingleFile {
333 pub fn store_string(schemas: &HashMap<SchemaFingerprint, SchemaNamedType>) -> String {
334 let mut cached_schemas: Vec<CachedSchemaNamedType> = Default::default();
335
336 for (_, schema) in schemas {
337 cached_schemas.push(CachedSchemaNamedType::new_from_schema(schema));
338 }
339
340 cached_schemas.sort_by_key(|x| x.fingerprint());
341
342 let cache = SchemaCacheSingleFile { cached_schemas };
343
344 profiling::scope!("serde_json::to_string_pretty");
345 serde_json::to_string_pretty(&cache).unwrap()
346 }
347
348 pub fn load_string(cache: &str) -> Vec<SchemaNamedType> {
349 let cache: SchemaCacheSingleFile = {
350 profiling::scope!("serde_json::from_str");
351 serde_json::from_str(cache).unwrap()
352 };
353 cache
354 .cached_schemas
355 .into_iter()
356 .map(|x| x.to_schema())
357 .collect()
358 }
359}