summaryrefslogtreecommitdiffstats
path: root/src/assets.rs
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2025-01-15 00:55:05 -0600
committerLibravatar bigfoot547 <[email protected]>2025-01-15 00:55:05 -0600
commit7db451eab4de13ac2dfd1b570a9e01a6afded919 (patch)
tree3f3e216e0e447367b25a78558b006716ad0a7c38 /src/assets.rs
parentfix stuff (diff)
get started on assets
Diffstat (limited to 'src/assets.rs')
-rw-r--r--src/assets.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/assets.rs b/src/assets.rs
new file mode 100644
index 0000000..9b0b7a7
--- /dev/null
+++ b/src/assets.rs
@@ -0,0 +1,84 @@
+use std::fmt::Formatter;
+use std::marker::PhantomData;
+use serde::{Deserialize, Deserializer};
+use serde::de::{MapAccess, Visitor};
+use sha1_smol::Digest;
+
+#[derive(Debug, Deserialize)]
+pub struct Asset {
+ #[serde(skip)]
+ pub name: String,
+ pub hash: Digest,
+ pub size: usize
+}
+
+#[derive(Debug, Deserialize)]
+pub struct AssetIndex {
+ #[serde(rename = "virtual", default)]
+ pub virtual_assets: bool,
+ #[serde(default)]
+ pub map_to_resources: bool,
+
+ #[serde(deserialize_with = "deserialize_assets")]
+ pub objects: Vec<Asset>
+}
+
+trait SetName {
+ fn set_name(&mut self, name: String);
+}
+
+impl SetName for Asset {
+ fn set_name(&mut self, name: String) {
+ self.name = name;
+ }
+}
+
+fn deserialize_assets<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
+where
+ D: Deserializer<'de>,
+ T: SetName + Deserialize<'de>
+{
+ struct AssetVisitor<T>(PhantomData<T>);
+
+ impl<'de, T> Visitor<'de> for AssetVisitor<T>
+ where
+ T: SetName + Deserialize<'de>
+ {
+ type Value = Vec<T>;
+
+ fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
+ formatter.write_str("asset objects map")
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut out = Vec::new();
+
+ while let Some((key, mut asset)) = map.next_entry::<String, T>()? {
+ asset.set_name(key);
+ out.push(asset);
+ }
+
+ Ok(out)
+ }
+ }
+
+ deserializer.deserialize_any(AssetVisitor(PhantomData))
+}
+
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_it() {
+ dbg!(serde_json::from_str::<AssetIndex>(r#"{
+ "virtual": true,
+ "objects": {
+ "object1": { "hash": "0d000710b71ca9aafabd8f587768431d0b560b32", "size": 100 },
+ "object2/abc": { "hash": "0e000710b71ca9aafabd8f587768431d0b560b32", "size": 10000 }
+ }
+ }"#).unwrap());
+ }
+}