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}