use crate::{App, SharedString, SharedUri}; use futures::Future; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::path::{Path, PathBuf}; use std::sync::Arc; /// An enum representing #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum Resource { /// This resource is at a given URI Uri(SharedUri), /// This resource is at a given path in the file system Path(Arc), /// This resource is embedded in the application binary Embedded(SharedString), } impl From for Resource { fn from(value: SharedUri) -> Self { Self::Uri(value) } } impl From for Resource { fn from(value: PathBuf) -> Self { Self::Path(value.into()) } } impl From> for Resource { fn from(value: Arc) -> Self { Self::Path(value) } } /// A trait for asynchronous asset loading. pub trait Asset: 'static { /// The source of the asset. type Source: Clone + Hash + Send; /// The loaded asset type Output: Clone + Send; /// Load the asset asynchronously fn load( source: Self::Source, cx: &mut App, ) -> impl Future + Send + 'static; } /// An asset Loader that logs whatever passes through it pub enum AssetLogger { #[doc(hidden)] _Phantom(PhantomData, &'static dyn crate::seal::Sealed), } impl>> Asset for AssetLogger { type Source = T::Source; type Output = T::Output; fn load( source: Self::Source, cx: &mut App, ) -> impl Future + Send + 'static { let load = T::load(source, cx); async { load.await .inspect_err(|e| log::error!("Failed to load asset: {}", e)) } } } /// Use a quick, non-cryptographically secure hash function to get an identifier from data pub fn hash(data: &T) -> u64 { let mut hasher = collections::FxHasher::default(); data.hash(&mut hasher); hasher.finish() }