use futures::future::BoxFuture; use { goods::{ source::{AssetData, Source}, Asset, AssetField, AssetId, Loader, }, std::{collections::HashMap, convert::Infallible, future::ready}, }; #[derive(Clone, Asset)] #[asset(name = "unit")] pub struct UnitAsset; #[derive(Clone, Asset)] #[asset(name = "simple")] pub struct SimpleAsset { field: SimpleFieldType, } #[derive(Clone, Asset)] #[asset(name = "two-level")] pub struct TwoLevelAsset { #[asset(external)] a: SimpleAsset, } #[derive(Clone, AssetField)] pub struct Container { #[asset(external)] a: UnitAsset, } #[derive(Clone, Asset)] #[asset(name = "complex")] pub struct ComplexAsset { #[asset(container)] c: Container, #[asset(external)] a: SimpleAsset, } #[derive(Clone, Asset)] #[asset(name = "wrapper")] pub struct WrapperAsset { wrapped: u32, } impl From for u32 { fn from(w: WrapperAsset) -> Self { w.wrapped } } #[derive(Clone, Asset)] #[asset(name = "with-wrapper")] pub struct AssetWithWrapper { #[asset(external(as WrapperAsset))] a: u32, } #[derive(Clone, Asset)] #[asset(name = "with-serde")] #[serde(rename_all = "UPPERCASE")] pub struct AssetWithSerdeAttribute { #[serde(default = "default_a")] a: u32, } fn default_a() -> u32 { 42 } #[derive(Clone, Asset)] #[asset(name = "with-option")] pub struct AssetWithOption { #[serde(default)] #[asset(external)] foo: Option, } #[derive(Clone, serde::Deserialize)] struct SimpleFieldType {} /// Dummy source which just gives bytes from map. struct HashMapSource(HashMap>); impl Source for HashMapSource { type Error = Infallible; fn find(&self, path: &str, _asset: &str) -> BoxFuture> { let id = AssetId(path.parse().unwrap()); Box::pin(ready(Some(id))) } fn load(&self, id: AssetId) -> BoxFuture, Infallible>> { Box::pin(ready(Ok(match self.0.get(&id) { Some(data) => Some(AssetData { bytes: data.clone(), version: 0, }), None => None, }))) } fn update( &self, _id: AssetId, _version: u64, ) -> BoxFuture, Infallible>> { Box::pin(ready(Ok(None))) } } fn main() { tokio::runtime::Builder::new_current_thread() .build() .unwrap() .block_on(async move { run().await.unwrap() }) } async fn run() -> Result<(), Box> { // Fill map. let source = HashMapSource( vec![ ( AssetId::new(2).unwrap(), b"null".to_vec().into_boxed_slice(), ), ( AssetId::new(3).unwrap(), b"{\"field\": {}}".to_vec().into_boxed_slice(), ), ( AssetId::new(4).unwrap(), b"{\"a\": 3}".to_vec().into_boxed_slice(), ), ( AssetId::new(5).unwrap(), b"{\"c\": {\"a\": 2}, \"a\": 3}".to_vec().into_boxed_slice(), ), ( AssetId::new(6).unwrap(), b"{\"wrapped\": 42}".to_vec().into_boxed_slice(), ), ( AssetId::new(7).unwrap(), b"{\"a\": 6}".to_vec().into_boxed_slice(), ), (AssetId::new(8).unwrap(), b"{}".to_vec().into_boxed_slice()), ] .into_iter() .collect(), ); let loader = Loader::builder().with(source).build(); let _: &UnitAsset = loader.load("2").await.build(&mut ())?; println!("UnitAsset loaded"); let _: &SimpleAsset = loader.load("3").await.build(&mut ())?; println!("SimpleAsset loaded"); let _: &TwoLevelAsset = loader.load("4").await.build(&mut ())?; println!("TwoLevelAsset loaded"); let _: &ComplexAsset = loader.load("5").await.build(&mut ())?; println!("ComplexAsset loaded"); let _: &WrapperAsset = loader.load("6").await.build(&mut ())?; println!("WrapperAsset loaded"); let _: &AssetWithWrapper = loader.load("7").await.build(&mut ())?; println!("AssetWithWrapper loaded"); let _: &AssetWithSerdeAttribute = loader.load("8").await.build(&mut ())?; println!("AssetWithSerdeAttribute loaded"); let _: &AssetWithOption = loader.load("8").await.build(&mut ())?; println!("AssetWithOption loaded"); Ok(()) }