1use derive_more::Display;
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9use crate::keyvalue::KeyValue;
10
11#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
12pub enum Type {
13 #[serde(rename = "unit")]
14 Unit,
15 #[serde(rename = "bool")]
16 Boolean,
17 #[serde(rename = "u8")]
18 U8,
19 #[serde(rename = "u16")]
20 U16,
21 #[serde(rename = "u32")]
22 U32,
23 #[serde(rename = "u64")]
24 U64,
25 #[serde(rename = "i8")]
26 I8,
27 #[serde(rename = "i16")]
28 I16,
29 #[serde(rename = "i32")]
30 I32,
31 #[serde(rename = "i64")]
32 I64,
33 #[serde(rename = "f32")]
34 F32,
35 #[serde(rename = "f64")]
36 F64,
37 #[serde(rename = "str")]
38 String,
39 #[serde(rename = "option")]
40 Option,
41 #[serde(rename = "struct")]
42 Structure,
43 #[serde(rename = "enum")]
44 Enumeration,
45 #[serde(rename = "bools")]
46 ArrayBoolean,
47 #[serde(rename = "u8s")]
48 ArrayU8,
49 #[serde(rename = "u16s")]
50 ArrayU16,
51 #[serde(rename = "u32s")]
52 ArrayU32,
53 #[serde(rename = "u64s")]
54 ArrayU64,
55 #[serde(rename = "i8s")]
56 ArrayI8,
57 #[serde(rename = "i16s")]
58 ArrayI16,
59 #[serde(rename = "i32s")]
60 ArrayI32,
61 #[serde(rename = "i64s")]
62 ArrayI64,
63 #[serde(rename = "f32s")]
64 ArrayF32,
65 #[serde(rename = "f64s")]
66 ArrayF64,
67 #[serde(rename = "strs")]
68 ArrayString,
69 #[serde(rename = "values")]
70 ArrayValue,
71 #[serde(rename = "structs")]
72 ArrayStructure,
73 #[serde(rename = "enums")]
74 ArrayEnumeration,
75 #[serde(rename = "keyvalues")]
76 KeyValue,
77 #[serde(rename = "uuids")]
78 Uuid,
79}
80
81#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
84pub enum Value {
85 #[serde(rename = "unit")]
86 #[display("()")]
87 Unit,
88 #[serde(rename = "bool")]
89 Boolean(bool),
90 #[serde(rename = "u8")]
91 #[display("{}u8", _0)]
92 U8(u8),
93 #[serde(rename = "u16")]
94 #[display("{}u16", _0)]
95 U16(u16),
96 #[serde(rename = "u32")]
97 #[display("{}u32", _0)]
98 U32(u32),
99 #[serde(rename = "u64")]
100 #[display("{}u64", _0)]
101 U64(u64),
102 #[serde(rename = "i8")]
103 #[display("{}i8", _0)]
104 I8(i8),
105 #[serde(rename = "i16")]
106 #[display("{}i16", _0)]
107 I16(i16),
108 #[serde(rename = "i32")]
109 #[display("{}i32", _0)]
110 I32(i32),
111 #[serde(rename = "i64")]
112 #[display("{}i64", _0)]
113 I64(i64),
114 #[serde(rename = "f32")]
115 #[display("{}f32", _0)]
116 F32(f32),
117 #[serde(rename = "f64")]
118 #[display("{}f64", _0)]
119 F64(f64),
120 #[serde(rename = "str")]
121 #[display("\"{}\"", _0)]
122 String(String),
123 #[serde(rename = "option")]
124 #[display("[{}]", if let Some(v) = _0.as_ref() { format!("{}", v) } else { "null".to_string() })]
125 Option(Option<Box<Value>>),
126 #[serde(rename = "struct")]
127 Structure(Structure),
128 #[serde(rename = "enum")]
129 Enumeration(Enumeration),
130 #[serde(rename = "bools")]
131 #[display("[{:?}]", _0)]
132 ArrayBoolean(Vec<bool>),
133 #[serde(rename = "u8s")]
134 #[display("u8[{:?}]", _0)]
135 ArrayU8(Vec<u8>),
136 #[serde(rename = "u16s")]
137 #[display("u16[{:?}]", _0)]
138 ArrayU16(Vec<u16>),
139 #[serde(rename = "u32s")]
140 #[display("u32[{:?}]", _0)]
141 ArrayU32(Vec<u32>),
142 #[serde(rename = "u64s")]
143 #[display("u64[{:?}]", _0)]
144 ArrayU64(Vec<u64>),
145 #[serde(rename = "i8s")]
146 #[display("i8[{:?}]", _0)]
147 ArrayI8(Vec<i8>),
148 #[serde(rename = "i16s")]
149 #[display("i16[{:?}]", _0)]
150 ArrayI16(Vec<i16>),
151 #[serde(rename = "i32s")]
152 #[display("i32[{:?}]", _0)]
153 ArrayI32(Vec<i32>),
154 #[serde(rename = "i64s")]
155 #[display("i64[{:?}]", _0)]
156 ArrayI64(Vec<i64>),
157 #[serde(rename = "f32s")]
158 #[display("f32[{:?}]", _0)]
159 ArrayF32(Vec<f32>),
160 #[serde(rename = "f64s")]
161 #[display("f64[{:?}]", _0)]
162 ArrayF64(Vec<f64>),
163 #[serde(rename = "strs")]
164 #[display("[{:?}]", _0)]
165 ArrayString(Vec<String>),
166 #[serde(rename = "values")]
167 #[display("[{:?}]", _0)]
168 ArrayValue(Vec<Value>),
169 #[serde(rename = "structs")]
170 #[display("structs({}, {:?})", id, elements)]
171 ArrayStructure {
172 id: Uuid,
173 elements: Vec<StructureWithoutId>,
174 },
175 #[serde(rename = "enums")]
176 #[display("enums({}, {:?})", id, elements)]
177 ArrayEnumeration {
178 id: Uuid,
179 elements: Vec<EnumerationWithoutId>,
180 },
181 #[serde(rename = "keyvalue")]
182 KeyValue(KeyValue),
183 #[serde(rename = "uuid")]
184 #[display("uuid({})", _0)]
185 Uuid(Uuid),
186}
187
188impl Value {
189 pub fn type_uuid(&self) -> Uuid {
195 use crate::ty;
196 match self {
197 Value::Unit => *ty::UNIT_ID,
198 Value::Boolean(_) => *ty::BOOLEAN_ID,
199 Value::I8(_) => *ty::I8_ID,
200 Value::I16(_) => *ty::I16_ID,
201 Value::I32(_) => *ty::I32_ID,
202 Value::I64(_) => *ty::I64_ID,
203 Value::U8(_) => *ty::U8_ID,
204 Value::U16(_) => *ty::U16_ID,
205 Value::U32(_) => *ty::U32_ID,
206 Value::U64(_) => *ty::U64_ID,
207 Value::F32(_) => *ty::F32_ID,
208 Value::F64(_) => *ty::F64_ID,
209 Value::String(_) => *ty::STRING_ID,
210 Value::Option(_) => *ty::OPTION_ID,
211 Value::Structure(s) => s.id,
212 Value::Enumeration(e) => e.id,
213 Value::ArrayBoolean(_) => *ty::ARRAY_BOOLEAN_ID,
214 Value::ArrayU8(_) => *ty::ARRAY_U8_ID,
215 Value::ArrayU16(_) => *ty::ARRAY_U16_ID,
216 Value::ArrayU32(_) => *ty::ARRAY_U32_ID,
217 Value::ArrayU64(_) => *ty::ARRAY_U64_ID,
218 Value::ArrayI8(_) => *ty::ARRAY_I8_ID,
219 Value::ArrayI16(_) => *ty::ARRAY_I16_ID,
220 Value::ArrayI32(_) => *ty::ARRAY_I32_ID,
221 Value::ArrayI64(_) => *ty::ARRAY_I64_ID,
222 Value::ArrayF32(_) => *ty::ARRAY_F32_ID,
223 Value::ArrayF64(_) => *ty::ARRAY_F64_ID,
224 Value::ArrayString(_) => *ty::ARRAY_STRING_ID,
225 Value::ArrayValue(_) => *ty::ARRAY_VALUE_ID,
226 Value::ArrayStructure { id, .. } => *id,
227 Value::ArrayEnumeration { id, .. } => *id,
228 Value::KeyValue(_) => *ty::KEY_VALUE_ID,
229 Value::Uuid(_) => *ty::UUID_ID,
230 }
231 }
232}
233
234#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
235#[display("{}::{}({})", id, variant_id, value)]
236pub struct Enumeration {
237 pub id: Uuid,
238 pub variant_id: Uuid,
239 pub value: Box<Value>,
240}
241
242#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
243#[display("{}({:?})", id, fields)]
244pub struct Structure {
245 pub id: Uuid,
246 pub fields: Vec<StructureField>,
247}
248
249#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
250#[display("{}: {}", id, value)]
251pub struct StructureField {
252 pub id: Uuid,
253 pub value: Box<Value>,
254}
255
256#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
257#[display("({:?})", fields)]
258pub struct StructureWithoutId {
259 pub fields: Vec<StructureField>,
261}
262
263#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
264#[display("{}({})", variant_id, value)]
265pub struct EnumerationWithoutId {
266 pub variant_id: Uuid,
267 pub value: Box<Value>,
268}
269
270#[derive(Display, Debug)]
272pub struct ConversionError {
273 pub message: String,
274}
275
276impl std::error::Error for ConversionError {}
277
278impl From<()> for Value {
279 fn from(_: ()) -> Self {
280 Value::Unit
281 }
282}
283
284impl From<bool> for Value {
285 fn from(v: bool) -> Self {
286 Value::Boolean(v)
287 }
288}
289
290impl From<u8> for Value {
291 fn from(v: u8) -> Self {
292 Value::U8(v)
293 }
294}
295
296impl From<u16> for Value {
297 fn from(v: u16) -> Self {
298 Value::U16(v)
299 }
300}
301
302impl From<u32> for Value {
303 fn from(v: u32) -> Self {
304 Value::U32(v)
305 }
306}
307
308impl From<u64> for Value {
309 fn from(v: u64) -> Self {
310 Value::U64(v)
311 }
312}
313
314impl From<i8> for Value {
315 fn from(v: i8) -> Self {
316 Value::I8(v)
317 }
318}
319
320impl From<i16> for Value {
321 fn from(v: i16) -> Self {
322 Value::I16(v)
323 }
324}
325
326impl From<i32> for Value {
327 fn from(v: i32) -> Self {
328 Value::I32(v)
329 }
330}
331
332impl From<i64> for Value {
333 fn from(v: i64) -> Self {
334 Value::I64(v)
335 }
336}
337
338impl From<f32> for Value {
339 fn from(v: f32) -> Self {
340 Value::F32(v)
341 }
342}
343
344impl From<f64> for Value {
345 fn from(v: f64) -> Self {
346 Value::F64(v)
347 }
348}
349
350impl From<String> for Value {
351 fn from(v: String) -> Self {
352 Value::String(v)
353 }
354}
355
356impl From<&str> for Value {
357 fn from(v: &str) -> Self {
358 Value::String(v.to_string())
359 }
360}
361
362impl From<Uuid> for Value {
363 fn from(v: Uuid) -> Self {
364 Value::Uuid(v)
365 }
366}
367
368impl<T> From<Option<T>> for Value
370where
371 T: Into<Value>,
372{
373 fn from(opt: Option<T>) -> Self {
374 match opt {
375 Some(value) => Value::Option(Some(Box::new(value.into()))),
376 None => Value::Option(None),
377 }
378 }
379}
380
381impl From<Vec<Value>> for Value {
383 fn from(vec: Vec<Value>) -> Self {
384 Value::ArrayValue(vec)
385 }
386}
387
388impl From<&[Value]> for Value {
390 fn from(slice: &[Value]) -> Self {
391 Value::ArrayValue(slice.to_vec())
392 }
393}
394
395macro_rules! impl_array_conversions {
397 ($(($rust_type:ty, $variant:ident)),* $(,)?) => {
398 $(
399 impl From<Vec<$rust_type>> for Value {
401 fn from(vec: Vec<$rust_type>) -> Self {
402 Value::$variant(vec)
403 }
404 }
405
406 impl From<&[$rust_type]> for Value {
408 fn from(slice: &[$rust_type]) -> Self {
409 Value::$variant(slice.to_vec())
410 }
411 }
412
413 impl From<std::collections::HashSet<$rust_type>> for Value {
415 fn from(set: std::collections::HashSet<$rust_type>) -> Self {
416 Value::$variant(set.into_iter().collect())
417 }
418 }
419 )*
420 };
421}
422
423impl_array_conversions! {
425 (bool, ArrayBoolean),
426 (u8, ArrayU8),
427 (u16, ArrayU16),
428 (u32, ArrayU32),
429 (u64, ArrayU64),
430 (i8, ArrayI8),
431 (i16, ArrayI16),
432 (i32, ArrayI32),
433 (i64, ArrayI64),
434 (String, ArrayString),
435}
436
437macro_rules! impl_float_array_conversions {
439 ($(($rust_type:ty, $variant:ident)),* $(,)?) => {
440 $(
441 impl From<Vec<$rust_type>> for Value {
443 fn from(vec: Vec<$rust_type>) -> Self {
444 Value::$variant(vec)
445 }
446 }
447
448 impl From<&[$rust_type]> for Value {
450 fn from(slice: &[$rust_type]) -> Self {
451 Value::$variant(slice.to_vec())
452 }
453 }
454 )*
455 };
456}
457
458impl_float_array_conversions! {
460 (f32, ArrayF32),
461 (f64, ArrayF64),
462}
463
464#[cfg(test)]
467mod tests {
468 use super::*;
469 use json5;
470 use pretty_assertions::assert_eq;
471
472 fn test_serde_roundtrip<T>(value: &T, name: &str)
474 where
475 T: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug + Clone,
476 {
477 let json = json5::to_string(value).unwrap();
479 println!("{} JSON:\n{}", name, json);
480
481 let deserialized: T = json5::from_str(&json).unwrap();
482 assert_eq!(
483 value, &deserialized,
484 "Roundtrip JSON serialization failed for {name}"
485 );
486
487 let ron = ron::to_string(value).unwrap();
489 println!("{} RON:\n{}", name, ron);
490 let deserialized: T = ron::from_str(&ron).unwrap();
491 assert_eq!(
492 value, &deserialized,
493 "Roundtrip RON serialization failed for {name}"
494 );
495 }
496
497 #[test]
498 fn test_type_serialization() {
499 for typ in [
501 Type::Unit,
502 Type::Boolean,
503 Type::U8,
504 Type::U16,
505 Type::U32,
506 Type::U64,
507 Type::I8,
508 Type::I16,
509 Type::I32,
510 Type::I64,
511 Type::F32,
512 Type::F64,
513 Type::String,
514 Type::Option,
515 Type::Structure,
516 Type::Enumeration,
517 Type::ArrayBoolean,
518 Type::ArrayU8,
519 Type::ArrayU16,
520 Type::ArrayU32,
521 Type::ArrayU64,
522 Type::ArrayI8,
523 Type::ArrayI16,
524 Type::ArrayI32,
525 Type::ArrayI64,
526 Type::ArrayF32,
527 Type::ArrayF64,
528 Type::ArrayString,
529 Type::ArrayValue,
530 Type::ArrayStructure,
531 Type::ArrayEnumeration,
532 Type::KeyValue,
533 Type::Uuid,
534 ] {
535 test_serde_roundtrip(&typ, &format!("Type::{:?}", typ));
536 }
537 }
538
539 #[test]
540 fn test_value_primitive_serialization() {
541 let primitives = vec![
543 ("Unit", Value::Unit),
544 ("Boolean_true", Value::Boolean(true)),
545 ("Boolean_false", Value::Boolean(false)),
546 ("U8_min", Value::U8(0)),
547 ("U8_max", Value::U8(u8::MAX)),
548 ("U16_max", Value::U16(u16::MAX)),
549 ("U32_max", Value::U32(u32::MAX)),
550 ("U64_max", Value::U64(u64::MAX)),
551 ("I8_min", Value::I8(i8::MIN)),
552 ("I8_max", Value::I8(i8::MAX)),
553 ("I16_min", Value::I16(i16::MIN)),
554 ("I32_min", Value::I32(i32::MIN)),
555 ("I64_min", Value::I64(i64::MIN)),
556 ("F32_zero", Value::F32(0.0)),
557 ("F32_inf", Value::F32(f32::INFINITY)),
558 ("F32_neg_inf", Value::F32(f32::NEG_INFINITY)),
559 ("F64_zero", Value::F64(0.0)),
560 ("F64_inf", Value::F64(f64::INFINITY)),
561 ("F64_neg_inf", Value::F64(f64::NEG_INFINITY)),
562 ("String_empty", Value::String("".to_string())),
563 ("String_hello", Value::String("Hello, world!".to_string())),
564 (
565 "String_special",
566 Value::String("Special chars: \n\t\r\"\\".to_string()),
567 ),
568 ];
569
570 for (name, value) in primitives {
571 test_serde_roundtrip(&value, name);
572 }
573
574 let f32_nan = Value::F32(f32::NAN);
576 let f32_json = json5::to_string(&f32_nan).unwrap();
577 println!("F32_NaN JSON:\n{}", f32_json);
578 let deserialized_f32: Value = json5::from_str(&f32_json).unwrap();
579 if let Value::F32(val) = deserialized_f32 {
580 assert!(val.is_nan(), "Deserialized F32 should be NaN");
581 }
582
583 let f64_nan = Value::F64(f64::NAN);
584 let f64_json = json5::to_string(&f64_nan).unwrap();
585 println!("F64_NaN JSON:\n{}", f64_json);
586 let deserialized_f64: Value = json5::from_str(&f64_json).unwrap();
587 if let Value::F64(val) = deserialized_f64 {
588 assert!(val.is_nan(), "Deserialized F64 should be NaN");
589 }
590 }
591
592 #[test]
593 fn test_value_array_serialization() {
594 let arrays = vec![
596 ("ArrayBoolean_empty", Value::ArrayBoolean(vec![])),
597 ("ArrayBoolean", Value::ArrayBoolean(vec![true, false])),
598 ("ArrayU8", Value::ArrayU8(vec![0, 123, 255])),
599 ("ArrayI32", Value::ArrayI32(vec![i32::MIN, 0, i32::MAX])),
600 (
601 "ArrayF64",
602 Value::ArrayF64(vec![-1.0, 0.0, 1.0, f64::INFINITY]),
603 ),
604 (
605 "ArrayString",
606 Value::ArrayString(vec!["a".to_string(), "b".to_string()]),
607 ),
608 ];
609
610 for (name, value) in arrays {
611 test_serde_roundtrip(&value, name);
612 }
613 }
614
615 #[test]
616 fn test_structure_field_serialization() {
617 let field = StructureField {
618 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
619 value: Box::new(Value::String("test field".to_string())),
620 };
621
622 test_serde_roundtrip(&field, "StructureField");
623 }
624
625 #[test]
626 fn test_structure_serialization() {
627 let empty_structure = Structure {
629 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
630 fields: vec![],
631 };
632
633 test_serde_roundtrip(&empty_structure, "EmptyStructure");
634
635 let structure = Structure {
637 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
638 fields: vec![
639 StructureField {
640 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
641 value: Box::new(Value::String("field1".to_string())),
642 },
643 StructureField {
644 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440002").unwrap(),
645 value: Box::new(Value::I32(42)),
646 },
647 ],
648 };
649
650 test_serde_roundtrip(&structure, "Structure");
651 }
652
653 #[test]
654 fn test_structure_without_id_serialization() {
655 let structure_without_id = StructureWithoutId {
656 fields: vec![StructureField {
657 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
658 value: Box::new(Value::String("field1".to_string())),
659 }],
660 };
661
662 test_serde_roundtrip(&structure_without_id, "StructureWithoutId");
663 }
664
665 #[test]
666 fn test_enumeration_serialization() {
667 let enumeration = Enumeration {
668 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
669 variant_id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
670 value: Box::new(Value::String("variant value".to_string())),
671 };
672
673 test_serde_roundtrip(&enumeration, "Enumeration");
674 }
675
676 #[test]
677 fn test_enumeration_without_id_serialization() {
678 let enumeration_without_id = EnumerationWithoutId {
679 variant_id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
680 value: Box::new(Value::String("variant value".to_string())),
681 };
682
683 test_serde_roundtrip(&enumeration_without_id, "EnumerationWithoutId");
684 }
685
686 #[test]
687 fn test_complex_nested_values() {
688 let complex_value = Value::Structure(Structure {
690 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
691 fields: vec![
692 StructureField {
693 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
694 value: Box::new(Value::String("name".to_string())),
695 },
696 StructureField {
697 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440002").unwrap(),
698 value: Box::new(Value::Enumeration(Enumeration {
699 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440003").unwrap(),
700 variant_id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440004").unwrap(),
701 value: Box::new(Value::Boolean(true)),
702 })),
703 },
704 ],
705 });
706
707 test_serde_roundtrip(&complex_value, "ComplexNestedValue");
708 }
709
710 #[test]
711 fn test_array_structure_and_enumeration() {
712 let array_structure = Value::ArrayStructure {
714 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
715 elements: vec![
716 StructureWithoutId {
717 fields: vec![StructureField {
718 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
719 value: Box::new(Value::String("element1".to_string())),
720 }],
721 },
722 StructureWithoutId { fields: vec![] }, ],
724 };
725
726 test_serde_roundtrip(&array_structure, "ArrayStructure");
727
728 let array_enumeration = Value::ArrayEnumeration {
730 id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
731 elements: vec![
732 EnumerationWithoutId {
733 variant_id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440001").unwrap(),
734 value: Box::new(Value::String("variant1".to_string())),
735 },
736 EnumerationWithoutId {
737 variant_id: Uuid::parse_str("550e8400-e29b-41d4-a716-446655440002").unwrap(),
738 value: Box::new(Value::U32(42)),
739 },
740 ],
741 };
742
743 test_serde_roundtrip(&array_enumeration, "ArrayEnumeration");
744 }
745
746 #[test]
747 fn test_from_conversions_primitives() {
748 assert_eq!(Value::from(()), Value::Unit);
750 assert_eq!(Value::from(true), Value::Boolean(true));
751 assert_eq!(Value::from(false), Value::Boolean(false));
752
753 assert_eq!(Value::from(42u8), Value::U8(42));
754 assert_eq!(Value::from(1234u16), Value::U16(1234));
755 assert_eq!(Value::from(123456u32), Value::U32(123456));
756 assert_eq!(Value::from(12345678901234u64), Value::U64(12345678901234));
757
758 assert_eq!(Value::from(-42i8), Value::I8(-42));
759 assert_eq!(Value::from(-1234i16), Value::I16(-1234));
760 assert_eq!(Value::from(-123456i32), Value::I32(-123456));
761 assert_eq!(Value::from(-12345678901234i64), Value::I64(-12345678901234));
762
763 assert_eq!(
764 Value::from(std::f32::consts::PI),
765 Value::F32(std::f32::consts::PI)
766 );
767 assert_eq!(
768 Value::from(std::f64::consts::PI),
769 Value::F64(std::f64::consts::PI)
770 );
771
772 assert_eq!(
773 Value::from("hello".to_string()),
774 Value::String("hello".to_string())
775 );
776 assert_eq!(Value::from("world"), Value::String("world".to_string()));
777
778 let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
779 assert_eq!(Value::from(uuid), Value::Uuid(uuid));
780 }
781
782 #[test]
783 fn test_from_conversions_arrays_vec() {
784 assert_eq!(
786 Value::from(vec![true, false, true]),
787 Value::ArrayBoolean(vec![true, false, true])
788 );
789 assert_eq!(
790 Value::from(vec![1u8, 2u8, 3u8]),
791 Value::ArrayU8(vec![1, 2, 3])
792 );
793 assert_eq!(
794 Value::from(vec![100u16, 200u16]),
795 Value::ArrayU16(vec![100, 200])
796 );
797 assert_eq!(
798 Value::from(vec![1000u32, 2000u32]),
799 Value::ArrayU32(vec![1000, 2000])
800 );
801 assert_eq!(
802 Value::from(vec![10000u64, 20000u64]),
803 Value::ArrayU64(vec![10000, 20000])
804 );
805
806 assert_eq!(Value::from(vec![-1i8, -2i8]), Value::ArrayI8(vec![-1, -2]));
807 assert_eq!(
808 Value::from(vec![-100i16, -200i16]),
809 Value::ArrayI16(vec![-100, -200])
810 );
811 assert_eq!(
812 Value::from(vec![-1000i32, -2000i32]),
813 Value::ArrayI32(vec![-1000, -2000])
814 );
815 assert_eq!(
816 Value::from(vec![-10000i64, -20000i64]),
817 Value::ArrayI64(vec![-10000, -20000])
818 );
819
820 assert_eq!(
821 Value::from(vec![1.5f32, 2.5f32]),
822 Value::ArrayF32(vec![1.5, 2.5])
823 );
824 assert_eq!(
825 Value::from(vec![1.5f64, 2.5f64]),
826 Value::ArrayF64(vec![1.5, 2.5])
827 );
828
829 assert_eq!(
830 Value::from(vec!["hello".to_string(), "world".to_string()]),
831 Value::ArrayString(vec!["hello".to_string(), "world".to_string()])
832 );
833 }
834
835 #[test]
836 fn test_from_conversions_arrays_slices() {
837 let bool_slice = &[true, false, true][..];
839 assert_eq!(
840 Value::from(bool_slice),
841 Value::ArrayBoolean(vec![true, false, true])
842 );
843
844 let u32_slice = &[1u32, 2u32, 3u32][..];
845 assert_eq!(Value::from(u32_slice), Value::ArrayU32(vec![1, 2, 3]));
846
847 let string_slice = &["a".to_string(), "b".to_string()][..];
848 assert_eq!(
849 Value::from(string_slice),
850 Value::ArrayString(vec!["a".to_string(), "b".to_string()])
851 );
852 }
853
854 #[test]
855 fn test_from_conversions_hashset() {
856 use std::collections::HashSet;
857
858 let bool_set: HashSet<bool> = [true, false].into_iter().collect();
860 if let Value::ArrayBoolean(vec) = Value::from(bool_set) {
861 assert_eq!(vec.len(), 2);
862 assert!(vec.contains(&true));
863 assert!(vec.contains(&false));
864 } else {
865 panic!("Expected ArrayBoolean");
866 }
867
868 let u32_set: HashSet<u32> = [1, 2, 3].into_iter().collect();
869 if let Value::ArrayU32(vec) = Value::from(u32_set) {
870 assert_eq!(vec.len(), 3);
871 assert!(vec.contains(&1));
872 assert!(vec.contains(&2));
873 assert!(vec.contains(&3));
874 } else {
875 panic!("Expected ArrayU32");
876 }
877
878 let string_set: HashSet<String> = ["a".to_string(), "b".to_string()].into_iter().collect();
879 if let Value::ArrayString(vec) = Value::from(string_set) {
880 assert_eq!(vec.len(), 2);
881 assert!(vec.contains(&"a".to_string()));
882 assert!(vec.contains(&"b".to_string()));
883 } else {
884 panic!("Expected ArrayString");
885 }
886
887 let empty_set: HashSet<u32> = HashSet::new();
889 assert_eq!(Value::from(empty_set), Value::ArrayU32(vec![]));
890 }
891
892 #[test]
893 fn test_from_conversions_empty_arrays() {
894 assert_eq!(Value::from(Vec::<bool>::new()), Value::ArrayBoolean(vec![]));
896 assert_eq!(Value::from(Vec::<u8>::new()), Value::ArrayU8(vec![]));
897 assert_eq!(Value::from(Vec::<u16>::new()), Value::ArrayU16(vec![]));
898 assert_eq!(Value::from(Vec::<u32>::new()), Value::ArrayU32(vec![]));
899 assert_eq!(Value::from(Vec::<u64>::new()), Value::ArrayU64(vec![]));
900 assert_eq!(Value::from(Vec::<i8>::new()), Value::ArrayI8(vec![]));
901 assert_eq!(Value::from(Vec::<i16>::new()), Value::ArrayI16(vec![]));
902 assert_eq!(Value::from(Vec::<i32>::new()), Value::ArrayI32(vec![]));
903 assert_eq!(Value::from(Vec::<i64>::new()), Value::ArrayI64(vec![]));
904 assert_eq!(Value::from(Vec::<f32>::new()), Value::ArrayF32(vec![]));
905 assert_eq!(Value::from(Vec::<f64>::new()), Value::ArrayF64(vec![]));
906 assert_eq!(
907 Value::from(Vec::<String>::new()),
908 Value::ArrayString(vec![])
909 );
910 }
911
912 #[test]
913 fn test_from_conversions_option() {
914 assert_eq!(
918 Value::from(Some(42u32)),
919 Value::Option(Some(Box::new(Value::U32(42))))
920 );
921 assert_eq!(
922 Value::from(Some(true)),
923 Value::Option(Some(Box::new(Value::Boolean(true))))
924 );
925 assert_eq!(
926 Value::from(Some("hello".to_string())),
927 Value::Option(Some(Box::new(Value::String("hello".to_string()))))
928 );
929 assert_eq!(
930 Value::from(Some(std::f64::consts::PI)),
931 Value::Option(Some(Box::new(Value::F64(std::f64::consts::PI))))
932 );
933
934 assert_eq!(Value::from(None::<u32>), Value::Option(None));
936 assert_eq!(Value::from(None::<bool>), Value::Option(None));
937 assert_eq!(Value::from(None::<String>), Value::Option(None));
938 assert_eq!(Value::from(None::<f64>), Value::Option(None));
939
940 let nested_value = Value::ArrayU32(vec![1, 2, 3]);
942 assert_eq!(
943 Value::from(Some(nested_value.clone())),
944 Value::Option(Some(Box::new(nested_value)))
945 );
946 assert_eq!(Value::from(None::<Value>), Value::Option(None));
947 }
948
949 #[test]
950 fn test_from_conversions_array_value() {
951 assert_eq!(Value::from(Vec::<Value>::new()), Value::ArrayValue(vec![]));
955
956 let mixed_values = vec![
958 Value::U32(42),
959 Value::Boolean(true),
960 Value::String("test".to_string()),
961 Value::F64(std::f64::consts::PI),
962 Value::Unit,
963 ];
964 assert_eq!(
965 Value::from(mixed_values.clone()),
966 Value::ArrayValue(mixed_values.clone())
967 );
968
969 let values_slice = &[
971 Value::I32(-10),
972 Value::Boolean(false),
973 Value::String("slice".to_string()),
974 ][..];
975 assert_eq!(
976 Value::from(values_slice),
977 Value::ArrayValue(vec![
978 Value::I32(-10),
979 Value::Boolean(false),
980 Value::String("slice".to_string()),
981 ])
982 );
983
984 let nested_array = vec![
986 Value::ArrayU32(vec![1, 2, 3]),
987 Value::ArrayString(vec!["a".to_string(), "b".to_string()]),
988 Value::ArrayBoolean(vec![true, false]),
989 ];
990 assert_eq!(
991 Value::from(nested_array.clone()),
992 Value::ArrayValue(nested_array)
993 );
994
995 let option_array = vec![
997 Value::Option(Some(Box::new(Value::U32(1)))),
998 Value::Option(None),
999 Value::Option(Some(Box::new(Value::String("test".to_string())))),
1000 ];
1001 assert_eq!(
1002 Value::from(option_array.clone()),
1003 Value::ArrayValue(option_array)
1004 );
1005 }
1006
1007 #[test]
1008 fn test_type_uuid() {
1009 use crate::ty;
1010
1011 assert_eq!(Value::Unit.type_uuid(), *ty::UNIT_ID);
1013 assert_eq!(Value::Boolean(false).type_uuid(), *ty::BOOLEAN_ID);
1014 assert_eq!(Value::I8(0).type_uuid(), *ty::I8_ID);
1015 assert_eq!(Value::I16(0).type_uuid(), *ty::I16_ID);
1016 assert_eq!(Value::I32(0).type_uuid(), *ty::I32_ID);
1017 assert_eq!(Value::I64(0).type_uuid(), *ty::I64_ID);
1018 assert_eq!(Value::U8(0).type_uuid(), *ty::U8_ID);
1019 assert_eq!(Value::U16(0).type_uuid(), *ty::U16_ID);
1020 assert_eq!(Value::U32(0).type_uuid(), *ty::U32_ID);
1021 assert_eq!(Value::U64(0).type_uuid(), *ty::U64_ID);
1022 assert_eq!(Value::F32(0.0).type_uuid(), *ty::F32_ID);
1023 assert_eq!(Value::F64(0.0).type_uuid(), *ty::F64_ID);
1024 assert_eq!(Value::String("".into()).type_uuid(), *ty::STRING_ID);
1025
1026 let test_id = uuid::Uuid::from_u128(0xdeadbeef);
1028 let variant_id = uuid::Uuid::from_u128(0xcafebabe);
1029
1030 assert_eq!(
1031 Value::Structure(Structure {
1032 id: test_id,
1033 fields: vec![],
1034 })
1035 .type_uuid(),
1036 test_id
1037 );
1038 assert_eq!(
1039 Value::Enumeration(Enumeration {
1040 id: test_id,
1041 variant_id,
1042 value: Box::new(Value::Unit),
1043 })
1044 .type_uuid(),
1045 test_id
1046 );
1047 assert_eq!(
1048 Value::ArrayStructure {
1049 id: test_id,
1050 elements: vec![],
1051 }
1052 .type_uuid(),
1053 test_id
1054 );
1055 assert_eq!(
1056 Value::ArrayEnumeration {
1057 id: test_id,
1058 elements: vec![],
1059 }
1060 .type_uuid(),
1061 test_id
1062 );
1063
1064 assert_eq!(Value::Option(None).type_uuid(), *ty::OPTION_ID);
1066 assert_eq!(
1067 Value::Option(Some(Box::new(Value::Unit))).type_uuid(),
1068 *ty::OPTION_ID
1069 );
1070 assert_eq!(
1071 Value::ArrayBoolean(vec![]).type_uuid(),
1072 *ty::ARRAY_BOOLEAN_ID
1073 );
1074 assert_eq!(Value::ArrayU8(vec![]).type_uuid(), *ty::ARRAY_U8_ID);
1075 assert_eq!(Value::ArrayU16(vec![]).type_uuid(), *ty::ARRAY_U16_ID);
1076 assert_eq!(Value::ArrayU32(vec![]).type_uuid(), *ty::ARRAY_U32_ID);
1077 assert_eq!(Value::ArrayU64(vec![]).type_uuid(), *ty::ARRAY_U64_ID);
1078 assert_eq!(Value::ArrayI8(vec![]).type_uuid(), *ty::ARRAY_I8_ID);
1079 assert_eq!(Value::ArrayI16(vec![]).type_uuid(), *ty::ARRAY_I16_ID);
1080 assert_eq!(Value::ArrayI32(vec![]).type_uuid(), *ty::ARRAY_I32_ID);
1081 assert_eq!(Value::ArrayI64(vec![]).type_uuid(), *ty::ARRAY_I64_ID);
1082 assert_eq!(Value::ArrayF32(vec![]).type_uuid(), *ty::ARRAY_F32_ID);
1083 assert_eq!(Value::ArrayF64(vec![]).type_uuid(), *ty::ARRAY_F64_ID);
1084 assert_eq!(Value::ArrayString(vec![]).type_uuid(), *ty::ARRAY_STRING_ID);
1085 assert_eq!(Value::ArrayValue(vec![]).type_uuid(), *ty::ARRAY_VALUE_ID);
1086 assert_eq!(
1087 Value::KeyValue(KeyValue::default()).type_uuid(),
1088 *ty::KEY_VALUE_ID
1089 );
1090 assert_eq!(Value::Uuid(uuid::Uuid::nil()).type_uuid(), *ty::UUID_ID);
1091
1092 let all_wellknown: Vec<uuid::Uuid> = ty::WELL_KNOWN_IDS.iter().copied().collect();
1094 assert_eq!(all_wellknown.len(), 29); }
1096}