1use std::any::{Any, TypeId};
13use std::collections::HashMap;
14use glam::{Vec2, Vec3};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum DeserializeError {
23 WrongType { expected: &'static str, got: &'static str },
25 MissingKey(String),
27 IndexOutOfBounds { index: usize, len: usize },
29 ParseError(String),
31 Custom(String),
33}
34
35impl std::fmt::Display for DeserializeError {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 DeserializeError::WrongType { expected, got } => {
39 write!(f, "type mismatch: expected {expected}, got {got}")
40 }
41 DeserializeError::MissingKey(k) => write!(f, "missing key: '{k}'"),
42 DeserializeError::IndexOutOfBounds { index, len } => {
43 write!(f, "index {index} out of bounds (len {len})")
44 }
45 DeserializeError::ParseError(s) => write!(f, "parse error: {s}"),
46 DeserializeError::Custom(s) => write!(f, "{s}"),
47 }
48 }
49}
50
51impl std::error::Error for DeserializeError {}
52
53#[derive(Debug, Clone, PartialEq)]
59pub enum SerializedValue {
60 Null,
61 Bool(bool),
62 Int(i64),
63 Float(f64),
64 Str(String),
65 Bytes(Vec<u8>),
66 List(Vec<SerializedValue>),
67 Map(HashMap<String, SerializedValue>),
68}
69
70impl SerializedValue {
71 pub fn null() -> Self { SerializedValue::Null }
74 pub fn bool(b: bool) -> Self { SerializedValue::Bool(b) }
75 pub fn int(i: i64) -> Self { SerializedValue::Int(i) }
76 pub fn float(f: f64) -> Self { SerializedValue::Float(f) }
77 pub fn str(s: impl Into<String>) -> Self { SerializedValue::Str(s.into()) }
78 pub fn bytes(b: Vec<u8>) -> Self { SerializedValue::Bytes(b) }
79 pub fn list(v: Vec<SerializedValue>) -> Self { SerializedValue::List(v) }
80 pub fn map(m: HashMap<String, SerializedValue>) -> Self { SerializedValue::Map(m) }
81
82 pub fn empty_map() -> Self {
83 SerializedValue::Map(HashMap::new())
84 }
85
86 pub fn empty_list() -> Self {
87 SerializedValue::List(Vec::new())
88 }
89
90 pub fn as_bool(&self) -> Option<bool> {
93 if let SerializedValue::Bool(b) = self { Some(*b) } else { None }
94 }
95
96 pub fn as_int(&self) -> Option<i64> {
97 match self {
98 SerializedValue::Int(i) => Some(*i),
99 SerializedValue::Float(f) => Some(*f as i64),
100 _ => None,
101 }
102 }
103
104 pub fn as_float(&self) -> Option<f64> {
105 match self {
106 SerializedValue::Float(f) => Some(*f),
107 SerializedValue::Int(i) => Some(*i as f64),
108 _ => None,
109 }
110 }
111
112 pub fn as_str(&self) -> Option<&str> {
113 if let SerializedValue::Str(s) = self { Some(s.as_str()) } else { None }
114 }
115
116 pub fn as_bytes(&self) -> Option<&[u8]> {
117 if let SerializedValue::Bytes(b) = self { Some(b.as_slice()) } else { None }
118 }
119
120 pub fn as_list(&self) -> Option<&[SerializedValue]> {
121 if let SerializedValue::List(v) = self { Some(v.as_slice()) } else { None }
122 }
123
124 pub fn as_map(&self) -> Option<&HashMap<String, SerializedValue>> {
125 if let SerializedValue::Map(m) = self { Some(m) } else { None }
126 }
127
128 pub fn as_map_mut(&mut self) -> Option<&mut HashMap<String, SerializedValue>> {
129 if let SerializedValue::Map(m) = self { Some(m) } else { None }
130 }
131
132 pub fn is_null(&self) -> bool {
133 matches!(self, SerializedValue::Null)
134 }
135
136 pub fn get(&self, key: &str) -> Option<&SerializedValue> {
140 self.as_map()?.get(key)
141 }
142
143 pub fn index(&self, i: usize) -> Option<&SerializedValue> {
145 self.as_list()?.get(i)
146 }
147
148 pub fn insert(&mut self, key: impl Into<String>, value: SerializedValue) -> bool {
150 if let SerializedValue::Map(m) = self {
151 m.insert(key.into(), value);
152 true
153 } else {
154 false
155 }
156 }
157
158 pub fn push(&mut self, value: SerializedValue) -> bool {
160 if let SerializedValue::List(v) = self {
161 v.push(value);
162 true
163 } else {
164 false
165 }
166 }
167
168 pub fn type_name(&self) -> &'static str {
170 match self {
171 SerializedValue::Null => "Null",
172 SerializedValue::Bool(_) => "Bool",
173 SerializedValue::Int(_) => "Int",
174 SerializedValue::Float(_) => "Float",
175 SerializedValue::Str(_) => "Str",
176 SerializedValue::Bytes(_) => "Bytes",
177 SerializedValue::List(_) => "List",
178 SerializedValue::Map(_) => "Map",
179 }
180 }
181
182 pub fn to_json_string(&self) -> String {
191 serde_json::to_string(&self.to_json_value()).expect("a JSON value always serializes")
192 }
193
194 pub fn to_json_value(&self) -> serde_json::Value {
197 use serde_json::Value as J;
198 match self {
199 SerializedValue::Null => J::Null,
200 SerializedValue::Bool(b) => J::Bool(*b),
201 SerializedValue::Int(i) => J::from(*i),
202 SerializedValue::Float(f) => {
203 let f = if f.is_infinite() { f.signum() * 1e308 } else { *f };
204 serde_json::Number::from_f64(f).map(J::Number).unwrap_or(J::Null)
206 }
207 SerializedValue::Str(s) => J::String(s.clone()),
208 SerializedValue::Bytes(bytes) => {
209 use std::fmt::Write;
210 let mut hex = String::with_capacity(bytes.len() * 2);
211 for b in bytes {
212 let _ = write!(hex, "{b:02x}");
213 }
214 J::String(hex)
215 }
216 SerializedValue::List(items) => J::Array(items.iter().map(Self::to_json_value).collect()),
217 SerializedValue::Map(m) => {
218 let mut keys: Vec<&String> = m.keys().collect();
219 keys.sort();
220 J::Object(keys.into_iter().map(|k| (k.clone(), m[k].to_json_value())).collect())
221 }
222 }
223 }
224
225 pub fn from_json_str(s: &str) -> Result<Self, DeserializeError> {
234 let v: serde_json::Value =
235 serde_json::from_str(s).map_err(|e| DeserializeError::ParseError(e.to_string()))?;
236 Ok(Self::from_json_value(v))
237 }
238
239 pub fn from_json_value(v: serde_json::Value) -> Self {
241 use serde_json::Value as J;
242 match v {
243 J::Null => SerializedValue::Null,
244 J::Bool(b) => SerializedValue::Bool(b),
245 J::Number(n) => match n.as_i64() {
246 Some(i) => SerializedValue::Int(i),
247 None => SerializedValue::Float(n.as_f64().unwrap_or(f64::NAN)),
248 },
249 J::String(s) => SerializedValue::Str(s),
250 J::Array(items) => SerializedValue::List(items.into_iter().map(Self::from_json_value).collect()),
251 J::Object(m) => SerializedValue::Map(m.into_iter().map(|(k, v)| (k, Self::from_json_value(v))).collect()),
252 }
253 }
254}
255
256impl Default for SerializedValue {
257 fn default() -> Self {
258 SerializedValue::Null
259 }
260}
261
262pub trait Serialize {
268 fn serialize(&self) -> SerializedValue;
269}
270
271pub trait Deserialize: Sized {
273 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError>;
274}
275
276impl Serialize for bool {
279 fn serialize(&self) -> SerializedValue { SerializedValue::Bool(*self) }
280}
281
282impl Deserialize for bool {
283 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
284 v.as_bool().ok_or(DeserializeError::WrongType { expected: "Bool", got: v.type_name() })
285 }
286}
287
288impl Serialize for i32 {
291 fn serialize(&self) -> SerializedValue { SerializedValue::Int(*self as i64) }
292}
293
294impl Deserialize for i32 {
295 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
296 v.as_int().map(|i| i as i32)
297 .ok_or(DeserializeError::WrongType { expected: "Int", got: v.type_name() })
298 }
299}
300
301impl Serialize for i64 {
304 fn serialize(&self) -> SerializedValue { SerializedValue::Int(*self) }
305}
306
307impl Deserialize for i64 {
308 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
309 v.as_int().ok_or(DeserializeError::WrongType { expected: "Int", got: v.type_name() })
310 }
311}
312
313impl Serialize for u32 {
316 fn serialize(&self) -> SerializedValue { SerializedValue::Int(*self as i64) }
317}
318
319impl Deserialize for u32 {
320 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
321 v.as_int().map(|i| i as u32)
322 .ok_or(DeserializeError::WrongType { expected: "Int", got: v.type_name() })
323 }
324}
325
326impl Serialize for u64 {
329 fn serialize(&self) -> SerializedValue { SerializedValue::Int(*self as i64) }
330}
331
332impl Deserialize for u64 {
333 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
334 v.as_int().map(|i| i as u64)
335 .ok_or(DeserializeError::WrongType { expected: "Int", got: v.type_name() })
336 }
337}
338
339impl Serialize for f32 {
342 fn serialize(&self) -> SerializedValue { SerializedValue::Float(*self as f64) }
343}
344
345impl Deserialize for f32 {
346 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
347 v.as_float().map(|f| f as f32)
348 .ok_or(DeserializeError::WrongType { expected: "Float", got: v.type_name() })
349 }
350}
351
352impl Serialize for f64 {
355 fn serialize(&self) -> SerializedValue { SerializedValue::Float(*self) }
356}
357
358impl Deserialize for f64 {
359 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
360 v.as_float().ok_or(DeserializeError::WrongType { expected: "Float", got: v.type_name() })
361 }
362}
363
364impl Serialize for String {
367 fn serialize(&self) -> SerializedValue { SerializedValue::Str(self.clone()) }
368}
369
370impl Deserialize for String {
371 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
372 v.as_str().map(|s| s.to_string())
373 .ok_or(DeserializeError::WrongType { expected: "Str", got: v.type_name() })
374 }
375}
376
377impl Serialize for &str {
380 fn serialize(&self) -> SerializedValue { SerializedValue::Str(self.to_string()) }
381}
382
383impl<T: Serialize> Serialize for Vec<T> {
386 fn serialize(&self) -> SerializedValue {
387 SerializedValue::List(self.iter().map(|v| v.serialize()).collect())
388 }
389}
390
391impl<T: Deserialize> Deserialize for Vec<T> {
392 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
393 let list = v.as_list()
394 .ok_or(DeserializeError::WrongType { expected: "List", got: v.type_name() })?;
395 list.iter().map(T::deserialize).collect()
396 }
397}
398
399impl<V: Serialize> Serialize for HashMap<String, V> {
402 fn serialize(&self) -> SerializedValue {
403 let mut m = HashMap::new();
404 for (k, v) in self {
405 m.insert(k.clone(), v.serialize());
406 }
407 SerializedValue::Map(m)
408 }
409}
410
411impl<V: Deserialize> Deserialize for HashMap<String, V> {
412 fn deserialize(sv: &SerializedValue) -> Result<Self, DeserializeError> {
413 let map = sv.as_map()
414 .ok_or(DeserializeError::WrongType { expected: "Map", got: sv.type_name() })?;
415 let mut out = HashMap::new();
416 for (k, v) in map {
417 out.insert(k.clone(), V::deserialize(v)?);
418 }
419 Ok(out)
420 }
421}
422
423impl<T: Serialize> Serialize for Option<T> {
426 fn serialize(&self) -> SerializedValue {
427 match self {
428 Some(v) => v.serialize(),
429 None => SerializedValue::Null,
430 }
431 }
432}
433
434impl<T: Deserialize> Deserialize for Option<T> {
435 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
436 if v.is_null() {
437 Ok(None)
438 } else {
439 T::deserialize(v).map(Some)
440 }
441 }
442}
443
444impl Serialize for Vec2 {
447 fn serialize(&self) -> SerializedValue {
448 let mut m = HashMap::new();
449 m.insert("x".to_string(), SerializedValue::Float(self.x as f64));
450 m.insert("y".to_string(), SerializedValue::Float(self.y as f64));
451 SerializedValue::Map(m)
452 }
453}
454
455impl Deserialize for Vec2 {
456 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
457 let x = v.get("x")
458 .and_then(|v| v.as_float())
459 .ok_or_else(|| DeserializeError::MissingKey("x".into()))? as f32;
460 let y = v.get("y")
461 .and_then(|v| v.as_float())
462 .ok_or_else(|| DeserializeError::MissingKey("y".into()))? as f32;
463 Ok(Vec2::new(x, y))
464 }
465}
466
467impl Serialize for Vec3 {
470 fn serialize(&self) -> SerializedValue {
471 let mut m = HashMap::new();
472 m.insert("x".to_string(), SerializedValue::Float(self.x as f64));
473 m.insert("y".to_string(), SerializedValue::Float(self.y as f64));
474 m.insert("z".to_string(), SerializedValue::Float(self.z as f64));
475 SerializedValue::Map(m)
476 }
477}
478
479impl Deserialize for Vec3 {
480 fn deserialize(v: &SerializedValue) -> Result<Self, DeserializeError> {
481 let x = v.get("x").and_then(|v| v.as_float())
482 .ok_or_else(|| DeserializeError::MissingKey("x".into()))? as f32;
483 let y = v.get("y").and_then(|v| v.as_float())
484 .ok_or_else(|| DeserializeError::MissingKey("y".into()))? as f32;
485 let z = v.get("z").and_then(|v| v.as_float())
486 .ok_or_else(|| DeserializeError::MissingKey("z".into()))? as f32;
487 Ok(Vec3::new(x, y, z))
488 }
489}
490
491type SerializeFn = Box<dyn Fn(*const u8) -> SerializedValue + Send + Sync>;
496type DeserializeFn = Box<dyn Fn(&SerializedValue) -> Box<dyn Any + Send + Sync> + Send + Sync>;
497
498struct ComponentEntry {
499 type_id: TypeId,
500 name: String,
501 serialize: SerializeFn,
502 deserialize: DeserializeFn,
503}
504
505pub struct ComponentSerializer {
509 by_name: HashMap<String, usize>,
510 by_type: HashMap<TypeId, usize>,
511 entries: Vec<ComponentEntry>,
512}
513
514impl ComponentSerializer {
515 pub fn new() -> Self {
516 Self {
517 by_name: HashMap::new(),
518 by_type: HashMap::new(),
519 entries: Vec::new(),
520 }
521 }
522
523 pub fn register<T: Serialize + Deserialize + Any + Send + Sync + 'static>(
525 &mut self,
526 name: impl Into<String>,
527 ) {
528 let name = name.into();
529 let type_id = TypeId::of::<T>();
530 let idx = self.entries.len();
531 self.by_name.insert(name.clone(), idx);
532 self.by_type.insert(type_id, idx);
533 self.entries.push(ComponentEntry {
534 type_id,
535 name,
536 serialize: Box::new(|ptr| {
537 let reference = unsafe { &*(ptr as *const T) };
539 reference.serialize()
540 }),
541 deserialize: Box::new(|v| {
542 match T::deserialize(v) {
543 Ok(t) => Box::new(t) as Box<dyn Any + Send + Sync>,
544 Err(_) => Box::new(()) as Box<dyn Any + Send + Sync>,
545 }
546 }),
547 });
548 }
549
550 pub unsafe fn serialize_any(&self, type_id: TypeId, ptr: *const u8) -> Option<SerializedValue> {
555 let idx = self.by_type.get(&type_id)?;
556 Some((self.entries[*idx].serialize)(ptr))
557 }
558
559 pub fn deserialize_any(&self, name: &str, v: &SerializedValue) -> Option<Box<dyn Any + Send + Sync>> {
561 let idx = self.by_name.get(name)?;
562 Some((self.entries[*idx].deserialize)(v))
563 }
564
565 pub fn has_name(&self, name: &str) -> bool {
567 self.by_name.contains_key(name)
568 }
569
570 pub fn registered_names(&self) -> impl Iterator<Item = &str> {
572 self.by_name.keys().map(String::as_str)
573 }
574
575 pub fn len(&self) -> usize {
577 self.entries.len()
578 }
579}
580
581impl Default for ComponentSerializer {
582 fn default() -> Self {
583 Self::new()
584 }
585}
586
587#[cfg(test)]
592mod tests {
593 use super::*;
594
595 #[test]
596 fn serialize_primitives() {
597 assert_eq!(true.serialize(), SerializedValue::Bool(true));
598 assert_eq!(42i64.serialize(), SerializedValue::Int(42));
599 assert_eq!(3.14f64.serialize(), SerializedValue::Float(3.14));
600 assert_eq!("hello".serialize(), SerializedValue::Str("hello".into()));
601 }
602
603 #[test]
604 fn deserialize_primitives() {
605 assert_eq!(bool::deserialize(&SerializedValue::Bool(false)).unwrap(), false);
606 assert_eq!(i64::deserialize(&SerializedValue::Int(7)).unwrap(), 7);
607 assert_eq!(f64::deserialize(&SerializedValue::Float(1.5)).unwrap(), 1.5);
608 assert_eq!(String::deserialize(&SerializedValue::Str("hi".into())).unwrap(), "hi");
609 }
610
611 #[test]
612 fn serialize_vec2_roundtrip() {
613 let v = Vec2::new(1.0, 2.5);
614 let sv = v.serialize();
615 let v2 = Vec2::deserialize(&sv).unwrap();
616 assert!((v.x - v2.x).abs() < 1e-5);
617 assert!((v.y - v2.y).abs() < 1e-5);
618 }
619
620 #[test]
621 fn serialize_vec3_roundtrip() {
622 let v = Vec3::new(1.0, 2.0, 3.0);
623 let sv = v.serialize();
624 let v2 = Vec3::deserialize(&sv).unwrap();
625 assert!((v - v2).length() < 1e-5);
626 }
627
628 #[test]
629 fn serialize_vec_of_ints() {
630 let v: Vec<i64> = vec![10, 20, 30];
631 let sv = v.serialize();
632 let v2: Vec<i64> = Vec::deserialize(&sv).unwrap();
633 assert_eq!(v, v2);
634 }
635
636 #[test]
637 fn serialize_option_some_none() {
638 let some: Option<i64> = Some(99);
639 let none: Option<i64> = None;
640 assert_eq!(some.serialize(), SerializedValue::Int(99));
641 assert_eq!(none.serialize(), SerializedValue::Null);
642 assert_eq!(Option::<i64>::deserialize(&SerializedValue::Null).unwrap(), None);
643 assert_eq!(Option::<i64>::deserialize(&SerializedValue::Int(5)).unwrap(), Some(5));
644 }
645
646 #[test]
647 fn json_roundtrip_simple() {
648 let original = SerializedValue::Map({
649 let mut m = HashMap::new();
650 m.insert("name".into(), SerializedValue::Str("Alice".into()));
651 m.insert("score".into(), SerializedValue::Int(1000));
652 m.insert("alive".into(), SerializedValue::Bool(true));
653 m
654 });
655 let json = original.to_json_string();
656 let parsed = SerializedValue::from_json_str(&json).unwrap();
657 assert_eq!(parsed.get("name").and_then(|v| v.as_str()), Some("Alice"));
658 assert_eq!(parsed.get("score").and_then(|v| v.as_int()), Some(1000));
659 assert_eq!(parsed.get("alive").and_then(|v| v.as_bool()), Some(true));
660 }
661
662 #[test]
663 fn json_roundtrip_nested() {
664 let sv = SerializedValue::List(vec![
665 SerializedValue::Int(1),
666 SerializedValue::Float(2.5),
667 SerializedValue::Null,
668 SerializedValue::Bool(true),
669 ]);
670 let json = sv.to_json_string();
671 let parsed = SerializedValue::from_json_str(&json).unwrap();
672 assert_eq!(parsed.index(0).and_then(|v| v.as_int()), Some(1));
673 assert_eq!(parsed.index(2).map(|v| v.is_null()), Some(true));
674 }
675
676 #[test]
677 fn json_string_escape() {
678 let sv = SerializedValue::Str("say \"hello\"\nnewline".into());
679 let json = sv.to_json_string();
680 let parsed = SerializedValue::from_json_str(&json).unwrap();
681 assert_eq!(parsed.as_str(), Some("say \"hello\"\nnewline"));
682 }
683
684 #[test]
685 fn json_keeps_non_ascii_text_intact() {
686 let name = "Zoë, 東京, \u{1F525}";
689 let sv = SerializedValue::Str(name.into());
690 let parsed = SerializedValue::from_json_str(&sv.to_json_string()).unwrap();
691 assert_eq!(parsed.as_str(), Some(name));
692 let parsed = SerializedValue::from_json_str(r#""🔥""#).unwrap();
694 assert_eq!(parsed.as_str(), Some("\u{1F525}"));
695 }
696
697 #[test]
698 fn json_output_is_deterministic_and_handles_odd_floats() {
699 let mut m = HashMap::new();
700 for k in ["zeta", "alpha", "mid"] {
701 m.insert(k.to_string(), SerializedValue::Float(1.0));
702 }
703 m.insert("nan".into(), SerializedValue::Float(f64::NAN));
704 m.insert("inf".into(), SerializedValue::Float(f64::NEG_INFINITY));
705 m.insert("raw".into(), SerializedValue::Bytes(vec![0, 15, 255]));
706 let json = SerializedValue::Map(m).to_json_string();
707 assert_eq!(
708 json,
709 r#"{"alpha":1.0,"inf":-1e+308,"mid":1.0,"nan":null,"raw":"000fff","zeta":1.0}"#
710 );
711 let back = SerializedValue::from_json_str(&json).unwrap();
713 assert_eq!(back.get("alpha"), Some(&SerializedValue::Float(1.0)));
714 assert_eq!(SerializedValue::from_json_str("42").unwrap(), SerializedValue::Int(42));
715 assert_eq!(SerializedValue::from_json_str("1e3").unwrap(), SerializedValue::Float(1000.0));
716 }
717
718 #[test]
719 fn json_rejects_malformed_input() {
720 for bad in ["{\"a\":1} trailing", "[1,2", "{\"a\" 1}", "\"unterminated", "nul", ""] {
721 assert!(
722 matches!(SerializedValue::from_json_str(bad), Err(DeserializeError::ParseError(_))),
723 "{bad:?} should not parse"
724 );
725 }
726 }
727
728 #[test]
729 fn component_serializer_register_and_use() {
730 let mut cs = ComponentSerializer::new();
731 cs.register::<i64>("health");
732 assert!(cs.has_name("health"));
733 assert_eq!(cs.len(), 1);
734
735 let sv = SerializedValue::Int(100);
736 let boxed = cs.deserialize_any("health", &sv).unwrap();
737 let val = boxed.downcast_ref::<i64>().unwrap();
738 assert_eq!(*val, 100);
739 }
740
741 #[test]
742 fn wrong_type_error() {
743 let sv = SerializedValue::Str("not a bool".into());
744 let err = bool::deserialize(&sv).unwrap_err();
745 assert!(matches!(err, DeserializeError::WrongType { .. }));
746 }
747}