hydrate_pipeline/import/
importer_registry.rs

1use hydrate_data::{HashMap, ImporterId};
2use std::sync::Arc;
3use type_uuid::TypeUuid;
4use uuid::Uuid;
5
6use super::import_types::*;
7
8// Keeps track of all known importers
9pub struct ImporterRegistryInner {
10    registered_importers: HashMap<ImporterId, Arc<dyn Importer>>,
11    file_extension_associations: HashMap<String, Vec<ImporterId>>,
12}
13
14#[derive(Clone)]
15pub struct ImporterRegistry {
16    inner: Arc<ImporterRegistryInner>,
17}
18
19impl ImporterRegistry {
20    pub fn importers_for_file_extension(
21        &self,
22        extension: &str,
23    ) -> &[ImporterId] {
24        const EMPTY_LIST: &'static [ImporterId] = &[];
25        self.inner
26            .file_extension_associations
27            .get(extension)
28            .map(|x| x.as_slice())
29            .unwrap_or(EMPTY_LIST)
30    }
31
32    pub fn importer(
33        &self,
34        importer_id: ImporterId,
35    ) -> Option<&Arc<dyn Importer>> {
36        self.inner.registered_importers.get(&importer_id)
37    }
38}
39
40#[derive(Default)]
41pub struct ImporterRegistryBuilder {
42    registered_importers: HashMap<ImporterId, Arc<dyn Importer>>,
43    file_extension_associations: HashMap<String, Vec<ImporterId>>,
44}
45
46impl ImporterRegistryBuilder {
47    //
48    // Called before creating the schema to add handlers
49    //
50    pub fn register_handler<T: TypeUuid + Importer + Default + 'static>(&mut self) {
51        self.register_handler_instance(T::default())
52    }
53
54    pub fn register_handler_instance<T: TypeUuid + Importer + 'static>(
55        &mut self,
56        importer: T,
57    ) {
58        let handler = Arc::new(importer);
59        let importer_id = ImporterId(Uuid::from_bytes(T::UUID));
60        self.registered_importers.insert(importer_id, handler);
61
62        for extension in self.registered_importers[&importer_id].supported_file_extensions() {
63            self.file_extension_associations
64                .entry(extension.to_string())
65                .or_default()
66                .push(importer_id);
67        }
68    }
69
70    pub fn build(self) -> ImporterRegistry {
71        let inner = ImporterRegistryInner {
72            registered_importers: self.registered_importers,
73            file_extension_associations: self.file_extension_associations,
74        };
75
76        ImporterRegistry {
77            inner: Arc::new(inner),
78        }
79    }
80}