1use futures::future::BoxFuture;
2
3use {
4 goods::{
5 source::{AssetData, Source},
6 Asset, AssetField, AssetId, Loader,
7 },
8 std::{collections::HashMap, convert::Infallible, future::ready},
9};
10
11#[derive(Clone, Asset)]
12#[asset(name = "unit")]
13pub struct UnitAsset;
14
15#[derive(Clone, Asset)]
16#[asset(name = "simple")]
17pub struct SimpleAsset {
18 field: SimpleFieldType,
19}
20
21#[derive(Clone, Asset)]
22#[asset(name = "two-level")]
23pub struct TwoLevelAsset {
24 #[asset(external)]
25 a: SimpleAsset,
26}
27
28#[derive(Clone, AssetField)]
29pub struct Container {
30 #[asset(external)]
31 a: UnitAsset,
32}
33
34#[derive(Clone, Asset)]
35#[asset(name = "complex")]
36pub struct ComplexAsset {
37 #[asset(container)]
38 c: Container,
39
40 #[asset(external)]
41 a: SimpleAsset,
42}
43
44#[derive(Clone, Asset)]
45#[asset(name = "wrapper")]
46pub struct WrapperAsset {
47 wrapped: u32,
48}
49
50impl From<WrapperAsset> for u32 {
51 fn from(w: WrapperAsset) -> Self {
52 w.wrapped
53 }
54}
55
56#[derive(Clone, Asset)]
57#[asset(name = "with-wrapper")]
58pub struct AssetWithWrapper {
59 #[asset(external(as WrapperAsset))]
60 a: u32,
61}
62
63#[derive(Clone, Asset)]
64#[asset(name = "with-serde")]
65#[serde(rename_all = "UPPERCASE")]
66pub struct AssetWithSerdeAttribute {
67 #[serde(default = "default_a")]
68 a: u32,
69}
70
71fn default_a() -> u32 {
72 42
73}
74
75#[derive(Clone, Asset)]
76#[asset(name = "with-option")]
77pub struct AssetWithOption {
78 #[serde(default)]
79 #[asset(external)]
80 foo: Option<SimpleAsset>,
81}
82
83#[derive(Clone, serde::Deserialize)]
84struct SimpleFieldType {}
85
86struct HashMapSource(HashMap<AssetId, Box<[u8]>>);
88
89impl Source for HashMapSource {
90 type Error = Infallible;
91
92 fn find(&self, path: &str, _asset: &str) -> BoxFuture<Option<AssetId>> {
93 let id = AssetId(path.parse().unwrap());
94 Box::pin(ready(Some(id)))
95 }
96
97 fn load(&self, id: AssetId) -> BoxFuture<Result<Option<AssetData>, Infallible>> {
98 Box::pin(ready(Ok(match self.0.get(&id) {
99 Some(data) => Some(AssetData {
100 bytes: data.clone(),
101 version: 0,
102 }),
103 None => None,
104 })))
105 }
106
107 fn update(
108 &self,
109 _id: AssetId,
110 _version: u64,
111 ) -> BoxFuture<Result<Option<AssetData>, Infallible>> {
112 Box::pin(ready(Ok(None)))
113 }
114}
115
116fn main() {
117 tokio::runtime::Builder::new_current_thread()
118 .build()
119 .unwrap()
120 .block_on(async move { run().await.unwrap() })
121}
122
123async fn run() -> Result<(), Box<dyn std::error::Error>> {
124 let source = HashMapSource(
126 vec![
127 (
128 AssetId::new(2).unwrap(),
129 b"null".to_vec().into_boxed_slice(),
130 ),
131 (
132 AssetId::new(3).unwrap(),
133 b"{\"field\": {}}".to_vec().into_boxed_slice(),
134 ),
135 (
136 AssetId::new(4).unwrap(),
137 b"{\"a\": 3}".to_vec().into_boxed_slice(),
138 ),
139 (
140 AssetId::new(5).unwrap(),
141 b"{\"c\": {\"a\": 2}, \"a\": 3}".to_vec().into_boxed_slice(),
142 ),
143 (
144 AssetId::new(6).unwrap(),
145 b"{\"wrapped\": 42}".to_vec().into_boxed_slice(),
146 ),
147 (
148 AssetId::new(7).unwrap(),
149 b"{\"a\": 6}".to_vec().into_boxed_slice(),
150 ),
151 (AssetId::new(8).unwrap(), b"{}".to_vec().into_boxed_slice()),
152 ]
153 .into_iter()
154 .collect(),
155 );
156
157 let loader = Loader::builder().with(source).build();
158
159 let _: &UnitAsset = loader.load("2").await.build(&mut ())?;
160 println!("UnitAsset loaded");
161
162 let _: &SimpleAsset = loader.load("3").await.build(&mut ())?;
163 println!("SimpleAsset loaded");
164
165 let _: &TwoLevelAsset = loader.load("4").await.build(&mut ())?;
166 println!("TwoLevelAsset loaded");
167
168 let _: &ComplexAsset = loader.load("5").await.build(&mut ())?;
169 println!("ComplexAsset loaded");
170
171 let _: &WrapperAsset = loader.load("6").await.build(&mut ())?;
172 println!("WrapperAsset loaded");
173
174 let _: &AssetWithWrapper = loader.load("7").await.build(&mut ())?;
175 println!("AssetWithWrapper loaded");
176
177 let _: &AssetWithSerdeAttribute = loader.load("8").await.build(&mut ())?;
178 println!("AssetWithSerdeAttribute loaded");
179
180 let _: &AssetWithOption = loader.load("8").await.build(&mut ())?;
181 println!("AssetWithOption loaded");
182
183 Ok(())
184}