hydrate_data/
data_set_view.rs

1use crate::data_set::DataSetResult;
2use crate::{AssetId, DataSet, NullOverride, OverrideBehavior, SchemaSet, SingleObject, Value};
3use std::sync::Arc;
4use uuid::Uuid;
5
6trait DataContainerRead {
7    fn get_null_override(
8        &self,
9        path: impl AsRef<str>,
10    ) -> DataSetResult<NullOverride>;
11
12    fn resolve_null_override(
13        &self,
14        path: impl AsRef<str>,
15    ) -> DataSetResult<NullOverride>;
16
17    // get_property_override
18
19    fn resolve_property(
20        &self,
21        path: impl AsRef<str>,
22    ) -> DataSetResult<&Value>;
23
24    //get_dynamic_array_entries
25    //get_map_entries
26    //add_dynamic_array_entry
27    //add_map_entry
28    //insert_dynamic_array_entry
29    //remove_dynamic_array_entry
30    //remove_map_entry
31
32    fn resolve_dynamic_array_entries(
33        &self,
34        path: impl AsRef<str>,
35    ) -> DataSetResult<Box<[Uuid]>>;
36
37    fn resolve_map_entries(
38        &self,
39        path: impl AsRef<str>,
40    ) -> DataSetResult<Box<[Uuid]>>;
41
42    fn get_override_behavior(
43        &self,
44        path: impl AsRef<str>,
45    ) -> DataSetResult<OverrideBehavior>;
46
47    //read_properties_bundle
48}
49
50trait DataContainerWrite {
51    //get_null_override
52    fn set_null_override(
53        &mut self,
54        path: impl AsRef<str>,
55        null_override: NullOverride,
56    ) -> DataSetResult<()>;
57    //resolve_null_override
58
59    //get_property_override
60    fn set_property_override(
61        &mut self,
62        path: impl AsRef<str>,
63        value: Option<Value>,
64    ) -> DataSetResult<Option<Value>>;
65    //resolve_property
66
67    //get_dynamic_array_entries
68    //get_map_entries
69    fn add_dynamic_array_entry(
70        &mut self,
71        path: impl AsRef<str>,
72    ) -> DataSetResult<Uuid>;
73
74    fn add_map_entry(
75        &mut self,
76        path: impl AsRef<str>,
77    ) -> DataSetResult<Uuid>;
78    //insert_dynamic_array_entry
79    //remove_dynamic_array_entry
80    //remove_map_entry
81
82    //get_override_behavior
83    fn set_override_behavior(
84        &mut self,
85        path: impl AsRef<str>,
86        behavior: OverrideBehavior,
87    ) -> DataSetResult<()>;
88}
89
90/// Provides a read-only view into a DataSet or SingleObject. A schema can be used to write into
91/// both forms.
92#[derive(Clone)]
93pub enum DataContainerRef<'a> {
94    DataSet(&'a DataSet, &'a SchemaSet, AssetId),
95    SingleObjectRef(&'a SingleObject, &'a SchemaSet),
96    SingleObjectArc(Arc<SingleObject>, &'a SchemaSet),
97}
98
99impl<'a> DataContainerRef<'a> {
100    pub fn from_single_object(
101        single_object: &'a SingleObject,
102        schema_set: &'a SchemaSet,
103    ) -> Self {
104        DataContainerRef::SingleObjectRef(single_object, schema_set)
105    }
106
107    pub fn from_single_object_arc(
108        single_object: Arc<SingleObject>,
109        schema_set: &'a SchemaSet,
110    ) -> Self {
111        DataContainerRef::SingleObjectArc(single_object, schema_set)
112    }
113
114    pub fn from_dataset(
115        data_set: &'a DataSet,
116        schema_set: &'a SchemaSet,
117        asset_id: AssetId,
118    ) -> Self {
119        DataContainerRef::DataSet(data_set, schema_set, asset_id)
120    }
121
122    pub fn schema_set(&self) -> &SchemaSet {
123        match *self {
124            DataContainerRef::DataSet(_, schema_set, _) => schema_set,
125            DataContainerRef::SingleObjectRef(_, schema_set) => schema_set,
126            DataContainerRef::SingleObjectArc(_, schema_set) => schema_set,
127        }
128    }
129
130    pub fn resolve_property(
131        &self,
132        path: impl AsRef<str>,
133    ) -> DataSetResult<&Value> {
134        match self {
135            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
136                data_set.resolve_property(schema_set, *asset_id, path)
137            }
138            DataContainerRef::SingleObjectRef(single_object, schema_set) => {
139                single_object.resolve_property(schema_set, path)
140            }
141            DataContainerRef::SingleObjectArc(single_object, schema_set) => {
142                single_object.resolve_property(schema_set, path)
143            }
144        }
145    }
146
147    pub fn get_null_override(
148        &self,
149        path: impl AsRef<str>,
150    ) -> DataSetResult<NullOverride> {
151        match self {
152            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
153                data_set.get_null_override(schema_set, *asset_id, path)
154            }
155            DataContainerRef::SingleObjectRef(single_object, schema_set) => {
156                single_object.get_null_override(schema_set, path)
157            }
158            DataContainerRef::SingleObjectArc(single_object, schema_set) => {
159                single_object.get_null_override(schema_set, path)
160            }
161        }
162    }
163
164    pub fn resolve_null_override(
165        &self,
166        path: impl AsRef<str>,
167    ) -> DataSetResult<NullOverride> {
168        match self {
169            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
170                data_set.resolve_null_override(schema_set, *asset_id, path)
171            }
172            DataContainerRef::SingleObjectRef(single_object, schema_set) => {
173                single_object.resolve_null_override(schema_set, path)
174            }
175            DataContainerRef::SingleObjectArc(single_object, schema_set) => {
176                single_object.resolve_null_override(schema_set, path)
177            }
178        }
179    }
180
181    pub fn resolve_dynamic_array_entries(
182        &self,
183        path: impl AsRef<str>,
184    ) -> DataSetResult<Box<[Uuid]>> {
185        match self {
186            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
187                data_set.resolve_dynamic_array_entries(schema_set, *asset_id, path)
188            }
189            DataContainerRef::SingleObjectRef(single_object, schema_set) => {
190                single_object.resolve_dynamic_array_entries(schema_set, path)
191            }
192            DataContainerRef::SingleObjectArc(single_object, schema_set) => {
193                single_object.resolve_dynamic_array_entries(schema_set, path)
194            }
195        }
196    }
197
198    pub fn resolve_map_entries(
199        &self,
200        path: impl AsRef<str>,
201    ) -> DataSetResult<Box<[Uuid]>> {
202        match self {
203            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
204                data_set.resolve_map_entries(schema_set, *asset_id, path)
205            }
206            DataContainerRef::SingleObjectRef(single_object, schema_set) => {
207                single_object.resolve_map_entries(schema_set, path)
208            }
209            DataContainerRef::SingleObjectArc(single_object, schema_set) => {
210                single_object.resolve_map_entries(schema_set, path)
211            }
212        }
213    }
214
215    pub fn get_override_behavior(
216        &self,
217        path: impl AsRef<str>,
218    ) -> DataSetResult<OverrideBehavior> {
219        match self {
220            DataContainerRef::DataSet(data_set, schema_set, asset_id) => {
221                data_set.get_override_behavior(schema_set, *asset_id, path)
222            }
223            DataContainerRef::SingleObjectRef(_, _) => Ok(OverrideBehavior::Replace),
224            DataContainerRef::SingleObjectArc(_, _) => Ok(OverrideBehavior::Replace),
225        }
226    }
227}
228
229impl<'a> DataContainerRead for DataContainerRef<'a> {
230    fn resolve_property(
231        &self,
232        path: impl AsRef<str>,
233    ) -> DataSetResult<&Value> {
234        self.resolve_property(path)
235    }
236
237    fn get_null_override(
238        &self,
239        path: impl AsRef<str>,
240    ) -> DataSetResult<NullOverride> {
241        self.get_null_override(path)
242    }
243
244    fn resolve_null_override(
245        &self,
246        path: impl AsRef<str>,
247    ) -> DataSetResult<NullOverride> {
248        self.resolve_null_override(path)
249    }
250
251    fn resolve_dynamic_array_entries(
252        &self,
253        path: impl AsRef<str>,
254    ) -> DataSetResult<Box<[Uuid]>> {
255        self.resolve_dynamic_array_entries(path)
256    }
257
258    fn resolve_map_entries(
259        &self,
260        path: impl AsRef<str>,
261    ) -> DataSetResult<Box<[Uuid]>> {
262        self.resolve_dynamic_array_entries(path)
263    }
264
265    fn get_override_behavior(
266        &self,
267        path: impl AsRef<str>,
268    ) -> DataSetResult<OverrideBehavior> {
269        self.get_override_behavior(path)
270    }
271}
272
273/// Provides a read/write view into a DataSet or SingleObject. A schema can be used to write into
274/// both forms.
275pub enum DataContainerRefMut<'a> {
276    DataSet(&'a mut DataSet, &'a SchemaSet, AssetId),
277    SingleObject(&'a mut SingleObject, &'a SchemaSet),
278}
279
280impl<'a> DataContainerRefMut<'a> {
281    pub fn from_single_object(
282        single_object: &'a mut SingleObject,
283        schema_set: &'a SchemaSet,
284    ) -> Self {
285        DataContainerRefMut::SingleObject(single_object, schema_set)
286    }
287
288    pub fn from_dataset(
289        data_set: &'a mut DataSet,
290        schema_set: &'a SchemaSet,
291        asset_id: AssetId,
292    ) -> Self {
293        DataContainerRefMut::DataSet(data_set, schema_set, asset_id)
294    }
295
296    pub fn read(&'a self) -> DataContainerRef<'a> {
297        match &*self {
298            DataContainerRefMut::DataSet(a, b, c) => DataContainerRef::DataSet(a, b, *c),
299            DataContainerRefMut::SingleObject(a, b) => DataContainerRef::SingleObjectRef(a, b),
300        }
301    }
302
303    pub fn resolve_property(
304        &self,
305        path: impl AsRef<str>,
306    ) -> DataSetResult<&Value> {
307        // We can't simply call read().resolve_property() because rust can't prove the borrowing safety
308        match self {
309            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
310                data_set.resolve_property(schema_set, *asset_id, path)
311            }
312            DataContainerRefMut::SingleObject(single_object, schema_set) => {
313                single_object.resolve_property(schema_set, path)
314            }
315        }
316    }
317
318    pub fn get_null_override(
319        &self,
320        path: impl AsRef<str>,
321    ) -> DataSetResult<NullOverride> {
322        self.read().get_null_override(path)
323    }
324
325    pub fn set_null_override(
326        &mut self,
327        path: impl AsRef<str>,
328        null_override: NullOverride,
329    ) -> DataSetResult<()> {
330        match self {
331            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
332                data_set.set_null_override(schema_set, *asset_id, path, null_override)
333            }
334            DataContainerRefMut::SingleObject(single_object, schema_set) => {
335                single_object.set_null_override(schema_set, path, null_override)
336            }
337        }
338    }
339
340    pub fn resolve_null_override(
341        &self,
342        path: impl AsRef<str>,
343    ) -> DataSetResult<NullOverride> {
344        self.read().resolve_null_override(path)
345    }
346
347    pub fn resolve_dynamic_array_entries(
348        &self,
349        path: impl AsRef<str>,
350    ) -> DataSetResult<Box<[Uuid]>> {
351        self.read().resolve_dynamic_array_entries(path)
352    }
353
354    pub fn resolve_map_entries(
355        &self,
356        path: impl AsRef<str>,
357    ) -> DataSetResult<Box<[Uuid]>> {
358        self.read().resolve_map_entries(path)
359    }
360
361    pub fn get_override_behavior(
362        &self,
363        path: impl AsRef<str>,
364    ) -> DataSetResult<OverrideBehavior> {
365        self.read().get_override_behavior(path)
366    }
367
368    pub fn add_dynamic_array_entry(
369        &mut self,
370        path: impl AsRef<str>,
371    ) -> DataSetResult<Uuid> {
372        match self {
373            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
374                data_set.add_dynamic_array_entry(schema_set, *asset_id, path)
375            }
376            DataContainerRefMut::SingleObject(single_object, schema_set) => {
377                single_object.add_dynamic_array_entry(schema_set, path)
378            }
379        }
380    }
381
382    pub fn add_map_entry(
383        &mut self,
384        path: impl AsRef<str>,
385    ) -> DataSetResult<Uuid> {
386        match self {
387            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
388                data_set.add_map_entry(schema_set, *asset_id, path)
389            }
390            DataContainerRefMut::SingleObject(single_object, schema_set) => {
391                single_object.add_map_entry(schema_set, path)
392            }
393        }
394    }
395
396    pub fn remove_dynamic_array_entry(
397        &mut self,
398        path: impl AsRef<str>,
399        entry_id: Uuid,
400    ) -> DataSetResult<bool> {
401        match self {
402            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
403                data_set.remove_dynamic_array_entry(schema_set, *asset_id, path, entry_id)
404            }
405            DataContainerRefMut::SingleObject(single_object, schema_set) => {
406                single_object.remove_dynamic_array_entry(schema_set, path, entry_id)
407            }
408        }
409    }
410
411    pub fn remove_map_entry(
412        &mut self,
413        path: impl AsRef<str>,
414        entry_id: Uuid,
415    ) -> DataSetResult<bool> {
416        match self {
417            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
418                data_set.remove_map_entry(schema_set, *asset_id, path, entry_id)
419            }
420            DataContainerRefMut::SingleObject(single_object, schema_set) => {
421                single_object.remove_map_entry(schema_set, path, entry_id)
422            }
423        }
424    }
425
426    pub fn set_property_override(
427        &mut self,
428        path: impl AsRef<str>,
429        value: Option<Value>,
430    ) -> DataSetResult<Option<Value>> {
431        match self {
432            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
433                data_set.set_property_override(schema_set, *asset_id, path, value)
434            }
435            DataContainerRefMut::SingleObject(single_object, schema_set) => {
436                single_object.set_property_override(schema_set, path, value)
437            }
438        }
439    }
440
441    pub fn set_override_behavior(
442        &mut self,
443        path: impl AsRef<str>,
444        behavior: OverrideBehavior,
445    ) -> DataSetResult<()> {
446        match self {
447            DataContainerRefMut::DataSet(data_set, schema_set, asset_id) => {
448                data_set.set_override_behavior(schema_set, *asset_id, path, behavior)
449            }
450            DataContainerRefMut::SingleObject(_, _) => Ok(()),
451        }
452    }
453}
454
455impl<'a> DataContainerRead for DataContainerRefMut<'a> {
456    fn resolve_property(
457        &self,
458        path: impl AsRef<str>,
459    ) -> DataSetResult<&Value> {
460        self.resolve_property(path)
461    }
462
463    fn get_null_override(
464        &self,
465        path: impl AsRef<str>,
466    ) -> DataSetResult<NullOverride> {
467        self.get_null_override(path)
468    }
469
470    fn resolve_null_override(
471        &self,
472        path: impl AsRef<str>,
473    ) -> DataSetResult<NullOverride> {
474        self.resolve_null_override(path)
475    }
476
477    fn resolve_dynamic_array_entries(
478        &self,
479        path: impl AsRef<str>,
480    ) -> DataSetResult<Box<[Uuid]>> {
481        self.resolve_dynamic_array_entries(path)
482    }
483
484    fn resolve_map_entries(
485        &self,
486        path: impl AsRef<str>,
487    ) -> DataSetResult<Box<[Uuid]>> {
488        self.resolve_map_entries(path)
489    }
490
491    fn get_override_behavior(
492        &self,
493        path: impl AsRef<str>,
494    ) -> DataSetResult<OverrideBehavior> {
495        self.get_override_behavior(path)
496    }
497}
498
499impl<'a> DataContainerWrite for DataContainerRefMut<'a> {
500    fn set_null_override(
501        &mut self,
502        path: impl AsRef<str>,
503        null_override: NullOverride,
504    ) -> DataSetResult<()> {
505        self.set_null_override(path, null_override)
506    }
507
508    fn set_property_override(
509        &mut self,
510        path: impl AsRef<str>,
511        value: Option<Value>,
512    ) -> DataSetResult<Option<Value>> {
513        self.set_property_override(path, value)
514    }
515
516    fn set_override_behavior(
517        &mut self,
518        path: impl AsRef<str>,
519        behavior: OverrideBehavior,
520    ) -> DataSetResult<()> {
521        self.set_override_behavior(path, behavior)
522    }
523
524    fn add_dynamic_array_entry(
525        &mut self,
526        path: impl AsRef<str>,
527    ) -> DataSetResult<Uuid> {
528        self.add_dynamic_array_entry(path)
529    }
530
531    fn add_map_entry(
532        &mut self,
533        path: impl AsRef<str>,
534    ) -> DataSetResult<Uuid> {
535        self.add_map_entry(path)
536    }
537}
538
539/// Provides a read/write view into a DataSet or SingleObject. A schema can be used to write into
540/// both forms.
541pub enum DataContainer {
542    SingleObject(SingleObject, SchemaSet),
543}
544
545impl DataContainer {
546    pub fn into_inner(self) -> SingleObject {
547        match self {
548            DataContainer::SingleObject(a, _b) => a,
549        }
550    }
551
552    pub fn from_single_object(
553        single_object: SingleObject,
554        schema_set: SchemaSet,
555    ) -> Self {
556        DataContainer::SingleObject(single_object, schema_set)
557    }
558
559    pub fn read<'a>(&'a self) -> DataContainerRef<'a> {
560        match self {
561            DataContainer::SingleObject(a, b) => DataContainerRef::SingleObjectRef(&a, &b),
562        }
563    }
564
565    pub fn to_mut(&mut self) -> DataContainerRefMut {
566        match self {
567            DataContainer::SingleObject(a, b) => DataContainerRefMut::SingleObject(a, b),
568        }
569    }
570
571    pub fn resolve_property(
572        &self,
573        path: impl AsRef<str>,
574    ) -> DataSetResult<&Value> {
575        // We can't simply call read().resolve_property() because rust can't prove the borrowing safety
576        match self {
577            DataContainer::SingleObject(single_object, schema_set) => {
578                single_object.resolve_property(schema_set, path)
579            }
580        }
581    }
582
583    pub fn get_null_override(
584        &self,
585        path: impl AsRef<str>,
586    ) -> DataSetResult<NullOverride> {
587        self.read().get_null_override(path)
588    }
589
590    pub fn set_null_override(
591        &mut self,
592        path: impl AsRef<str>,
593        null_override: NullOverride,
594    ) -> DataSetResult<()> {
595        match self {
596            DataContainer::SingleObject(single_object, schema_set) => {
597                single_object.set_null_override(schema_set, path, null_override)
598            }
599        }
600    }
601
602    pub fn resolve_null_override(
603        &self,
604        path: impl AsRef<str>,
605    ) -> DataSetResult<NullOverride> {
606        self.read().resolve_null_override(path)
607    }
608
609    pub fn resolve_dynamic_array_entries(
610        &self,
611        path: impl AsRef<str>,
612    ) -> DataSetResult<Box<[Uuid]>> {
613        self.read().resolve_dynamic_array_entries(path)
614    }
615
616    pub fn resolve_map_entries(
617        &self,
618        path: impl AsRef<str>,
619    ) -> DataSetResult<Box<[Uuid]>> {
620        self.read().resolve_map_entries(path)
621    }
622
623    pub fn set_property_override(
624        &mut self,
625        path: impl AsRef<str>,
626        value: Option<Value>,
627    ) -> DataSetResult<Option<Value>> {
628        match self {
629            DataContainer::SingleObject(single_object, schema_set) => {
630                single_object.set_property_override(schema_set, path, value)
631            }
632        }
633    }
634
635    pub fn add_dynamic_array_entry(
636        &mut self,
637        path: impl AsRef<str>,
638    ) -> DataSetResult<Uuid> {
639        match self {
640            DataContainer::SingleObject(single_object, schema_set) => {
641                single_object.add_dynamic_array_entry(schema_set, path)
642            }
643        }
644    }
645
646    pub fn add_map_entry(
647        &mut self,
648        path: impl AsRef<str>,
649    ) -> DataSetResult<Uuid> {
650        match self {
651            DataContainer::SingleObject(single_object, schema_set) => {
652                single_object.add_map_entry(schema_set, path)
653            }
654        }
655    }
656
657    pub fn remove_dynamic_array_entry(
658        &mut self,
659        path: impl AsRef<str>,
660        element_id: Uuid,
661    ) -> DataSetResult<bool> {
662        match self {
663            DataContainer::SingleObject(single_object, schema_set) => {
664                single_object.remove_dynamic_array_entry(schema_set, path, element_id)
665            }
666        }
667    }
668
669    pub fn remove_map_entry(
670        &mut self,
671        path: impl AsRef<str>,
672        element_id: Uuid,
673    ) -> DataSetResult<bool> {
674        match self {
675            DataContainer::SingleObject(single_object, schema_set) => {
676                single_object.remove_map_entry(schema_set, path, element_id)
677            }
678        }
679    }
680
681    pub fn get_override_behavior(
682        &self,
683        path: impl AsRef<str>,
684    ) -> DataSetResult<OverrideBehavior> {
685        self.read().get_override_behavior(path)
686    }
687
688    pub fn set_override_behavior(
689        &mut self,
690        _path: impl AsRef<str>,
691        _behavior: OverrideBehavior,
692    ) -> DataSetResult<()> {
693        match self {
694            DataContainer::SingleObject(_, _) => Ok(()),
695        }
696    }
697}
698
699impl DataContainerRead for DataContainer {
700    fn resolve_property(
701        &self,
702        path: impl AsRef<str>,
703    ) -> DataSetResult<&Value> {
704        self.resolve_property(path)
705    }
706
707    fn get_null_override(
708        &self,
709        path: impl AsRef<str>,
710    ) -> DataSetResult<NullOverride> {
711        self.get_null_override(path)
712    }
713
714    fn resolve_null_override(
715        &self,
716        path: impl AsRef<str>,
717    ) -> DataSetResult<NullOverride> {
718        self.resolve_null_override(path)
719    }
720
721    fn resolve_dynamic_array_entries(
722        &self,
723        path: impl AsRef<str>,
724    ) -> DataSetResult<Box<[Uuid]>> {
725        self.resolve_dynamic_array_entries(path)
726    }
727
728    fn resolve_map_entries(
729        &self,
730        path: impl AsRef<str>,
731    ) -> DataSetResult<Box<[Uuid]>> {
732        self.resolve_map_entries(path)
733    }
734
735    fn get_override_behavior(
736        &self,
737        path: impl AsRef<str>,
738    ) -> DataSetResult<OverrideBehavior> {
739        self.get_override_behavior(path)
740    }
741}
742
743impl DataContainerWrite for DataContainer {
744    fn set_null_override(
745        &mut self,
746        path: impl AsRef<str>,
747        null_override: NullOverride,
748    ) -> DataSetResult<()> {
749        self.set_null_override(path, null_override)
750    }
751
752    fn set_property_override(
753        &mut self,
754        path: impl AsRef<str>,
755        value: Option<Value>,
756    ) -> DataSetResult<Option<Value>> {
757        self.set_property_override(path, value)
758    }
759
760    fn set_override_behavior(
761        &mut self,
762        path: impl AsRef<str>,
763        behavior: OverrideBehavior,
764    ) -> DataSetResult<()> {
765        self.set_override_behavior(path, behavior)
766    }
767
768    fn add_dynamic_array_entry(
769        &mut self,
770        path: impl AsRef<str>,
771    ) -> DataSetResult<Uuid> {
772        self.add_dynamic_array_entry(path)
773    }
774
775    fn add_map_entry(
776        &mut self,
777        path: impl AsRef<str>,
778    ) -> DataSetResult<Uuid> {
779        self.add_map_entry(path)
780    }
781}