hydrate_pipeline/thumbnails/
thumbnail_provider_registry.rs1use 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 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}