asset_cache.rs

 1use crate::{App, SharedString, SharedUri};
 2use futures::{Future, TryFutureExt};
 3
 4use std::fmt::Debug;
 5use std::hash::{Hash, Hasher};
 6use std::marker::PhantomData;
 7use std::path::{Path, PathBuf};
 8use std::sync::Arc;
 9
10/// An enum representing
11#[derive(Debug, PartialEq, Eq, Hash, Clone)]
12pub enum Resource {
13    /// This resource is at a given URI
14    Uri(SharedUri),
15    /// This resource is at a given path in the file system
16    Path(Arc<Path>),
17    /// This resource is embedded in the application binary
18    Embedded(SharedString),
19}
20
21impl From<SharedUri> for Resource {
22    fn from(value: SharedUri) -> Self {
23        Self::Uri(value)
24    }
25}
26
27impl From<PathBuf> for Resource {
28    fn from(value: PathBuf) -> Self {
29        Self::Path(value.into())
30    }
31}
32
33impl From<Arc<Path>> for Resource {
34    fn from(value: Arc<Path>) -> Self {
35        Self::Path(value)
36    }
37}
38
39/// A trait for asynchronous asset loading.
40pub trait Asset: 'static {
41    /// The source of the asset.
42    type Source: Clone + Hash + Send;
43
44    /// The loaded asset
45    type Output: Clone + Send;
46
47    /// Load the asset asynchronously
48    fn load(
49        source: Self::Source,
50        cx: &mut App,
51    ) -> impl Future<Output = Self::Output> + Send + 'static;
52}
53
54/// An asset Loader which logs the [`Err`] variant of a [`Result`] during loading
55pub enum AssetLogger<T> {
56    #[doc(hidden)]
57    _Phantom(PhantomData<T>, &'static dyn crate::seal::Sealed),
58}
59
60impl<T, R, E> Asset for AssetLogger<T>
61where
62    T: Asset<Output = Result<R, E>>,
63    R: Clone + Send,
64    E: Clone + Send + std::fmt::Display,
65{
66    type Source = T::Source;
67
68    type Output = T::Output;
69
70    fn load(
71        source: Self::Source,
72        cx: &mut App,
73    ) -> impl Future<Output = Self::Output> + Send + 'static {
74        let load = T::load(source, cx);
75        load.inspect_err(|e| log::error!("Failed to load asset: {}", e))
76    }
77}
78
79/// Use a quick, non-cryptographically secure hash function to get an identifier from data
80pub fn hash<T: Hash>(data: &T) -> u64 {
81    let mut hasher = collections::FxHasher::default();
82    data.hash(&mut hasher);
83    hasher.finish()
84}