pub mod assetinfo; pub mod gameobject; pub mod mesh; pub mod pptr; pub mod streaminginfo; pub mod texture2d; pub mod transform; pub mod vectors; use crate::object::{Value, parser::FromValue}; use anyhow::Result; use assetinfo::AssetInfo; use gameobject::GameObject; use mesh::{ChannelInfo, Mesh, SubMesh, VertexData}; use pptr::PPtr; use serde::Serialize; use std::collections::BTreeMap; use streaminginfo::StreamingInfo; use texture2d::Texture2D; use transform::Transform; #[derive(Debug, Serialize)] pub enum HValue { AssetInfo(AssetInfo), GameObject(GameObject), Transform(Transform), PPtr(PPtr), Texture2D(Texture2D), StreamingInfo(StreamingInfo), SubMesh(SubMesh), Mesh(Mesh), VertexData(VertexData), ChannelInfo(ChannelInfo), Pair(Box, Box), Value([Value; 1]), Map(BTreeMap), Array(Vec), Object { class: String, fields: BTreeMap, }, } impl HValue { pub fn from_value(v: Value) -> Result { 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)?), "Transform" => Self::Transform(Transform::from_value(value)?), "Texture2D" => Self::Texture2D(Texture2D::from_value(value)?), "StreamingInfo" => Self::StreamingInfo(StreamingInfo::from_value(value)?), // "SubMesh" => Self::SubMesh(SubMesh::from_value(value)?), "Mesh" => Self::Mesh(Mesh::from_value(value)?), // "VertexData" => Self::VertexData(VertexData::from_value(value)?), // "ChannelInfo" => Self::ChannelInfo(ChannelInfo::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::>>()?; 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::>>()?, ), 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 { if let HValue::PPtr(v) = self { Some(v) } else { None } } pub fn as_array(self) -> Option> { if let HValue::Array(v) = self { Some(v) } else { None } } pub fn as_class(self, name: &str) -> Option> { if let HValue::Object { class, fields } = self { if class == name { Some(fields) } else { None } } else { None } } }