unity_asset_core/
unity_value.rs1use indexmap::IndexMap;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12#[serde(untagged)]
13pub enum UnityValue {
14 Null,
15 Bool(bool),
16 Integer(i64),
17 Float(f64),
18 String(String),
19 Array(Vec<UnityValue>),
20 #[serde(with = "serde_bytes")]
21 Bytes(Vec<u8>),
22 Object(IndexMap<String, UnityValue>),
23}
24
25impl UnityValue {
26 pub fn is_null(&self) -> bool {
28 matches!(self, UnityValue::Null)
29 }
30
31 pub fn as_bool(&self) -> Option<bool> {
33 match self {
34 UnityValue::Bool(b) => Some(*b),
35 _ => None,
36 }
37 }
38
39 pub fn as_i64(&self) -> Option<i64> {
41 match self {
42 UnityValue::Integer(i) => Some(*i),
43 _ => None,
44 }
45 }
46
47 pub fn as_f64(&self) -> Option<f64> {
49 match self {
50 UnityValue::Float(f) => Some(*f),
51 UnityValue::Integer(i) => Some(*i as f64),
52 _ => None,
53 }
54 }
55
56 pub fn as_str(&self) -> Option<&str> {
58 match self {
59 UnityValue::String(s) => Some(s),
60 _ => None,
61 }
62 }
63
64 pub fn as_array(&self) -> Option<&Vec<UnityValue>> {
66 match self {
67 UnityValue::Array(arr) => Some(arr),
68 _ => None,
69 }
70 }
71
72 pub fn as_bytes(&self) -> Option<&[u8]> {
74 match self {
75 UnityValue::Bytes(b) => Some(b.as_slice()),
76 _ => None,
77 }
78 }
79
80 pub fn as_object(&self) -> Option<&IndexMap<String, UnityValue>> {
82 match self {
83 UnityValue::Object(obj) => Some(obj),
84 _ => None,
85 }
86 }
87
88 pub fn as_object_mut(&mut self) -> Option<&mut IndexMap<String, UnityValue>> {
90 match self {
91 UnityValue::Object(obj) => Some(obj),
92 _ => None,
93 }
94 }
95}
96
97impl fmt::Display for UnityValue {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 match self {
100 UnityValue::Null => write!(f, "null"),
101 UnityValue::Bool(b) => write!(f, "{}", b),
102 UnityValue::Integer(i) => write!(f, "{}", i),
103 UnityValue::Float(fl) => write!(f, "{}", fl),
104 UnityValue::String(s) => write!(f, "{}", s),
105 UnityValue::Array(arr) => {
106 write!(f, "[")?;
107 for (i, item) in arr.iter().enumerate() {
108 if i > 0 {
109 write!(f, ", ")?;
110 }
111 write!(f, "{}", item)?;
112 }
113 write!(f, "]")
114 }
115 UnityValue::Bytes(b) => write!(f, "<bytes len={}>", b.len()),
116 UnityValue::Object(obj) => {
117 write!(f, "{{")?;
118 for (i, (key, value)) in obj.iter().enumerate() {
119 if i > 0 {
120 write!(f, ", ")?;
121 }
122 write!(f, "{}: {}", key, value)?;
123 }
124 write!(f, "}}")
125 }
126 }
127 }
128}
129
130impl From<bool> for UnityValue {
132 fn from(b: bool) -> Self {
133 UnityValue::Bool(b)
134 }
135}
136
137impl From<i32> for UnityValue {
138 fn from(i: i32) -> Self {
139 UnityValue::Integer(i as i64)
140 }
141}
142
143impl From<i64> for UnityValue {
144 fn from(i: i64) -> Self {
145 UnityValue::Integer(i)
146 }
147}
148
149impl From<f32> for UnityValue {
150 fn from(f: f32) -> Self {
151 UnityValue::Float(f as f64)
152 }
153}
154
155impl From<f64> for UnityValue {
156 fn from(f: f64) -> Self {
157 UnityValue::Float(f)
158 }
159}
160
161impl From<String> for UnityValue {
162 fn from(s: String) -> Self {
163 UnityValue::String(s)
164 }
165}
166
167impl From<&str> for UnityValue {
168 fn from(s: &str) -> Self {
169 UnityValue::String(s.to_string())
170 }
171}
172
173impl From<Vec<UnityValue>> for UnityValue {
174 fn from(arr: Vec<UnityValue>) -> Self {
175 UnityValue::Array(arr)
176 }
177}
178
179impl From<IndexMap<String, UnityValue>> for UnityValue {
180 fn from(obj: IndexMap<String, UnityValue>) -> Self {
181 UnityValue::Object(obj)
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188
189 #[test]
190 fn test_unity_value_creation() {
191 let val = UnityValue::String("test".to_string());
192 assert_eq!(val.as_str(), Some("test"));
193 }
194
195 #[test]
196 fn test_unity_value_conversions() {
197 let bool_val: UnityValue = true.into();
199 assert_eq!(bool_val.as_bool(), Some(true));
200
201 let int_val: UnityValue = 42i32.into();
202 assert_eq!(int_val.as_i64(), Some(42));
203
204 let float_val: UnityValue = std::f64::consts::PI.into();
205 assert_eq!(float_val.as_f64(), Some(std::f64::consts::PI));
206
207 let string_val: UnityValue = "test".into();
208 assert_eq!(string_val.as_str(), Some("test"));
209
210 let null_val = UnityValue::Null;
212 assert!(null_val.is_null());
213 }
214
215 #[test]
216 fn test_unity_value_display() {
217 let val = UnityValue::String("test".to_string());
218 assert_eq!(format!("{}", val), "test");
219
220 let val = UnityValue::Integer(42);
221 assert_eq!(format!("{}", val), "42");
222
223 let val = UnityValue::Bool(true);
224 assert_eq!(format!("{}", val), "true");
225 }
226}