aboutsummaryrefslogtreecommitdiff
path: root/src/classes/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/mod.rs')
-rw-r--r--src/classes/mod.rs109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/classes/mod.rs b/src/classes/mod.rs
new file mode 100644
index 0000000..bfde8ad
--- /dev/null
+++ b/src/classes/mod.rs
@@ -0,0 +1,109 @@
+pub mod assetinfo;
+pub mod gameobject;
+pub mod pptr;
+pub mod transform;
+
+use crate::object::Value;
+use anyhow::Result;
+use assetinfo::AssetInfo;
+use gameobject::GameObject;
+use pptr::PPtr;
+use serde::Serialize;
+use std::collections::BTreeMap;
+use transform::Transform;
+
+#[derive(Debug, Serialize)]
+pub enum HValue {
+ AssetInfo(AssetInfo),
+ GameObject(GameObject),
+ Transform(Transform),
+ PPtr(PPtr),
+
+ Pair(Box<HValue>, Box<HValue>),
+ Value([Value; 1]),
+ Map(BTreeMap<String, HValue>),
+ Array(Vec<HValue>),
+ Object {
+ class: String,
+ fields: BTreeMap<String, HValue>,
+ },
+}
+
+impl HValue {
+ pub fn from_value(v: Value) -> Result<HValue> {
+ Ok(match v {
+ value @ Value::Object { .. } => {
+ let class = value.class_name().unwrap();
+ match class.as_str() {
+ x if x.starts_with("PPtr<") => Self::PPtr(PPtr::from_value(value)?),
+ "AssetInfo" => Self::AssetInfo(AssetInfo::from_value(value)?),
+ "GameObject" => Self::GameObject(GameObject::from_value(value)?),
+ _ => {
+ let Value::Object { class, fields } = value else {
+ unreachable!()
+ };
+ let mut fields = fields
+ .into_iter()
+ .map(|(k, v)| Ok((k, HValue::from_value(v)?)))
+ .collect::<Result<BTreeMap<_, _>>>()?;
+ match class.as_str() {
+ "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 },
+ }
+ }
+ }
+ }
+ Value::Array(a) => Self::Array(
+ a.into_iter()
+ .map(|e| HValue::from_value(e))
+ .collect::<Result<Vec<_>>>()?,
+ ),
+ 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
+ }
+ }
+ pub fn as_array(self) -> Option<Vec<HValue>> {
+ if let HValue::Array(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+ pub fn as_class(self, name: &str) -> Option<BTreeMap<String, HValue>> {
+ if let HValue::Object { class, fields } = self {
+ if class == name { Some(fields) } else { None }
+ } else {
+ None
+ }
+ }
+}