hydrate_pipeline/thumbnails/
thumbnail_provider_registry.rs

1use crate::thumbnails::{
2    ThumbnailProvider, ThumbnailProviderAbstract, ThumbnailProviderId, ThumbnailProviderWrapper,
3};
4use crate::ThumbnailImage;
5use hydrate_base::hashing::HashMap;
6use hydrate_data::SchemaSet;
7use hydrate_schema::SchemaFingerprint;
8use std::hash::Hash;
9use std::sync::Arc;
10
11#[derive(Default)]
12pub struct ThumbnailProviderRegistryBuilder {
13    thumbnail_providers: Vec<Arc<dyn ThumbnailProviderAbstract>>,
14    default_thumbnails: HashMap<String, Arc<ThumbnailImage>>,
15}
16
17impl ThumbnailProviderRegistryBuilder {
18    pub fn register_thumbnail_provider<T: ThumbnailProvider + Send + Sync + Default + 'static>(
19        &mut self
20    ) where
21        T::GatheredDataT: Hash + for<'a> serde::Deserialize<'a> + serde::Serialize,
22    {
23        self.thumbnail_providers
24            .push(Arc::new(ThumbnailProviderWrapper(T::default())));
25    }
26
27    pub fn register_thumbnail_provider_instance<T: ThumbnailProvider + Send + Sync + 'static>(
28        &mut self,
29        thumbnail_provider: T,
30    ) where
31        T::GatheredDataT: Hash + for<'a> serde::Deserialize<'a> + serde::Serialize,
32    {
33        self.thumbnail_providers
34            .push(Arc::new(ThumbnailProviderWrapper(thumbnail_provider)));
35    }
36
37    pub fn build(
38        self,
39        schema_set: &SchemaSet,
40    ) -> ThumbnailProviderRegistry {
41        let mut asset_type_to_provider = HashMap::default();
42
43        for (provider_index, provider) in self.thumbnail_providers.iter().enumerate() {
44            let provider_id = ThumbnailProviderId(provider_index);
45            let asset_type = schema_set
46                .find_named_type(provider.asset_type_inner())
47                .unwrap()
48                .fingerprint();
49            let insert_result = asset_type_to_provider.insert(asset_type, provider_id);
50            // println!(
51            //     "provider {} handles asset fingerprint {}",
52            //     provider_id.0,
53            //     asset_type.as_uuid()
54            // );
55            if insert_result.is_some() {
56                panic!(
57                    "Multiple handlers registered to handle the same asset {}",
58                    provider.asset_type_inner()
59                );
60            }
61        }
62
63        let mut default_thumbnails = HashMap::default();
64        for (k, v) in self.default_thumbnails {
65            let named_type = schema_set.find_named_type(k).unwrap().fingerprint();
66            default_thumbnails.insert(named_type, v);
67        }
68
69        let inner = ThumbnailProviderRegistryInner {
70            asset_type_to_provider,
71            thumbnail_providers: self.thumbnail_providers,
72        };
73
74        ThumbnailProviderRegistry {
75            inner: Arc::new(inner),
76        }
77    }
78}
79
80pub struct ThumbnailProviderRegistryInner {
81    thumbnail_providers: Vec<Arc<dyn ThumbnailProviderAbstract>>,
82    asset_type_to_provider: HashMap<SchemaFingerprint, ThumbnailProviderId>,
83}
84
85#[derive(Clone)]
86pub struct ThumbnailProviderRegistry {
87    inner: Arc<ThumbnailProviderRegistryInner>,
88}
89
90impl ThumbnailProviderRegistry {
91    pub fn has_provider_for_asset(
92        &self,
93        fingerprint: SchemaFingerprint,
94    ) -> bool {
95        self.inner.asset_type_to_provider.contains_key(&fingerprint)
96    }
97
98    pub fn provider_for_asset(
99        &self,
100        fingerprint: SchemaFingerprint,
101    ) -> Option<&Arc<dyn ThumbnailProviderAbstract>> {
102        self.inner
103            .asset_type_to_provider
104            .get(&fingerprint)
105            .copied()
106            .map(|x| &self.inner.thumbnail_providers[x.0])
107    }
108}