hydrate_pipeline/build/
builder_registry.rs

1use hydrate_data::{BuilderId, HashMap, SchemaFingerprint, SchemaSet};
2use std::sync::Arc;
3
4use super::build_types::*;
5
6// Keeps track of all known builders
7pub struct BuilderRegistryInner {
8    registered_builders: Vec<Box<dyn Builder>>,
9    asset_type_to_builder: HashMap<SchemaFingerprint, BuilderId>,
10}
11
12#[derive(Clone)]
13pub struct BuilderRegistry {
14    inner: Arc<BuilderRegistryInner>,
15}
16
17impl BuilderRegistry {
18    pub fn builder_for_asset(
19        &self,
20        fingerprint: SchemaFingerprint,
21    ) -> Option<&Box<dyn Builder>> {
22        self.inner
23            .asset_type_to_builder
24            .get(&fingerprint)
25            .copied()
26            .map(|x| &self.inner.registered_builders[x.0])
27    }
28}
29
30// Keeps track of all known builders
31#[derive(Default)]
32pub struct BuilderRegistryBuilder {
33    registered_builders: Vec<Box<dyn Builder>>,
34}
35
36impl BuilderRegistryBuilder {
37    //
38    // Called before creating the schema to add handlers
39    //
40    pub fn register_handler<T: Builder + Default + 'static>(&mut self) {
41        let handler = Box::new(T::default());
42        self.registered_builders.push(handler);
43    }
44
45    pub fn register_handler_instance<T: Builder + 'static>(
46        &mut self,
47        instance: T,
48    ) {
49        let handler = Box::new(instance);
50        self.registered_builders.push(handler);
51    }
52
53    //
54    // Called after finished linking the schema so we can associate schema fingerprints with handlers
55    //
56    pub fn build(
57        self,
58        schema_set: &SchemaSet,
59    ) -> BuilderRegistry {
60        let mut asset_type_to_builder = HashMap::default();
61
62        for (builder_index, builder) in self.registered_builders.iter().enumerate() {
63            let builder_id = BuilderId(builder_index);
64            let asset_type = schema_set
65                .find_named_type(builder.asset_type())
66                .unwrap()
67                .fingerprint();
68            let insert_result = asset_type_to_builder.insert(asset_type, builder_id);
69            // println!(
70            //     "builder {} handles asset fingerprint {}",
71            //     builder_id.0,
72            //     asset_type.as_uuid()
73            // );
74            if insert_result.is_some() {
75                panic!("Multiple handlers registered to handle the same asset")
76            }
77        }
78
79        let inner = BuilderRegistryInner {
80            registered_builders: self.registered_builders,
81            asset_type_to_builder,
82        };
83
84        BuilderRegistry {
85            inner: Arc::new(inner),
86        }
87    }
88}