diff options
Diffstat (limited to 'src/classes.rs')
-rw-r--r-- | src/classes.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/classes.rs b/src/classes.rs new file mode 100644 index 0000000..87bce8c --- /dev/null +++ b/src/classes.rs @@ -0,0 +1,101 @@ +use crate::object::Value; +use anyhow::Result; +use serde::Serialize; +use std::collections::BTreeMap; + +#[derive(Serialize)] +pub enum HValue { + PPtr(PPtr), + Pair(Box<HValue>, Box<HValue>), + Value([Value; 1]), + Map(BTreeMap<String, HValue>), + AssetInfo(AssetInfo), + + Array(Vec<HValue>), + Object { + class: String, + fields: BTreeMap<String, HValue>, + }, +} + +impl HValue { + pub fn from_value(v: Value) -> Result<HValue> { + Ok(match v { + Value::Array(a) => Self::Array( + a.into_iter() + .map(|e| HValue::from_value(e)) + .collect::<Result<Vec<_>>>()?, + ), + Value::Object { class, fields } => { + let mut fields = fields + .into_iter() + .map(|(k, v)| Ok((k, HValue::from_value(v)?))) + .collect::<Result<BTreeMap<_, _>>>()?; + + match class.as_str() { + x if x.starts_with("PPtr<") => { + let inner = x.strip_prefix("PPtr<").unwrap().strip_suffix(">").unwrap(); + Self::PPtr(PPtr { + class: inner.to_owned(), + file_id: fields["m_FileID"].as_value().unwrap().as_i32().unwrap(), + path_id: fields["m_PathID"].as_value().unwrap().as_i64().unwrap(), + }) + } + "AssetInfo" => Self::AssetInfo(AssetInfo { + preload_index: fields["preloadIndex"].as_value().unwrap().as_i32().unwrap(), + preload_size: fields["preloadSize"].as_value().unwrap().as_i32().unwrap(), + asset: fields.remove("asset").unwrap().as_pptr().unwrap(), + }), + "map" => { + let Self::Array(a) = fields.remove("Array").unwrap() else { + unreachable!() + }; + Self::Map( + a.into_iter() + .map(|e| { + let Self::Pair(k, v) = e else { unreachable!() }; + (k.as_value().unwrap().clone().as_string().unwrap(), *v) + }) + .collect(), + ) + } + "pair" => Self::Pair( + Box::new(fields.remove("first").unwrap()), + Box::new(fields.remove("second").unwrap()), + ), + "vector" => fields.remove("Array").unwrap(), + _ => Self::Object { class, fields }, + } + } + x => Self::Value([x]), + }) + } + pub fn as_value(&self) -> Option<&Value> { + if let HValue::Value(v) = self { + Some(&v[0]) + } else { + None + } + } + pub fn as_pptr(self) -> Option<PPtr> { + if let HValue::PPtr(v) = self { + Some(v) + } else { + None + } + } +} + +#[derive(Debug, Serialize)] +pub struct PPtr { + class: String, + file_id: i32, + path_id: i64, +} + +#[derive(Debug, Serialize)] +pub struct AssetInfo { + preload_index: i32, + preload_size: i32, + asset: PPtr, +} |