1use std::collections::BTreeMap;
2use std::sync::Arc;
3
4#[cfg(feature = "image")]
5use photon_rs::PhotonImage;
6
7use serde::{
8 Deserialize, Deserializer, Serialize, Serializer,
9 ser::{SerializeMap, SerializeSeq},
10};
11
12use super::error::AgentError;
13
14#[cfg(feature = "image")]
15const IMAGE_BASE64_PREFIX: &str = "data:image/png;base64,";
16
17#[derive(Debug, Clone)]
18pub enum AgentValue {
19 Unit,
21 Boolean(bool),
22 Integer(i64),
23 Number(f64),
24
25 String(Arc<String>),
27
28 #[cfg(feature = "image")]
29 Image(Arc<PhotonImage>),
30
31 Array(Arc<Vec<AgentValue>>),
33 Object(Arc<AgentValueMap<String, AgentValue>>),
34}
35
36pub type AgentValueMap<S, T> = BTreeMap<S, T>;
37
38impl AgentValue {
39 pub fn unit() -> Self {
40 AgentValue::Unit
41 }
42
43 pub fn boolean(value: bool) -> Self {
44 AgentValue::Boolean(value)
45 }
46
47 pub fn integer(value: i64) -> Self {
48 AgentValue::Integer(value)
49 }
50
51 pub fn number(value: f64) -> Self {
52 AgentValue::Number(value)
53 }
54
55 pub fn string(value: impl Into<String>) -> Self {
56 AgentValue::String(Arc::new(value.into()))
57 }
58
59 #[cfg(feature = "image")]
60 pub fn image(value: PhotonImage) -> Self {
61 AgentValue::Image(Arc::new(value))
62 }
63
64 #[cfg(feature = "image")]
65 pub fn image_arc(value: Arc<PhotonImage>) -> Self {
66 AgentValue::Image(value)
67 }
68
69 pub fn object(value: AgentValueMap<String, AgentValue>) -> Self {
70 AgentValue::Object(Arc::new(value))
71 }
72
73 pub fn array(value: Vec<AgentValue>) -> Self {
74 AgentValue::Array(Arc::new(value))
75 }
76
77 pub fn boolean_default() -> Self {
78 AgentValue::Boolean(false)
79 }
80
81 pub fn integer_default() -> Self {
82 AgentValue::Integer(0)
83 }
84
85 pub fn number_default() -> Self {
86 AgentValue::Number(0.0)
87 }
88
89 pub fn string_default() -> Self {
90 AgentValue::String(Arc::new(String::new()))
91 }
92
93 #[cfg(feature = "image")]
94 pub fn image_default() -> Self {
95 AgentValue::Image(Arc::new(PhotonImage::new(vec![0u8, 0u8, 0u8, 0u8], 1, 1)))
96 }
97
98 pub fn array_default() -> Self {
99 AgentValue::Array(Arc::new(Vec::new()))
100 }
101
102 pub fn object_default() -> Self {
103 AgentValue::Object(Arc::new(AgentValueMap::new()))
104 }
105
106 pub fn from_json(value: serde_json::Value) -> Result<Self, AgentError> {
107 match value {
108 serde_json::Value::Null => Ok(AgentValue::Unit),
109 serde_json::Value::Bool(b) => Ok(AgentValue::Boolean(b)),
110 serde_json::Value::Number(n) => {
111 if let Some(i) = n.as_i64() {
112 Ok(AgentValue::Integer(i))
113 } else if let Some(f) = n.as_f64() {
114 Ok(AgentValue::Number(f))
115 } else {
116 Err(AgentError::InvalidValue(
117 "Invalid numeric value for AgentValue".into(),
118 ))
119 }
120 }
121 serde_json::Value::String(s) => {
122 #[cfg(feature = "image")]
123 if s.starts_with(IMAGE_BASE64_PREFIX) {
124 let img =
125 PhotonImage::new_from_base64(&s.trim_start_matches(IMAGE_BASE64_PREFIX));
126 Ok(AgentValue::Image(Arc::new(img)))
127 } else {
128 Ok(AgentValue::String(Arc::new(s)))
129 }
130 #[cfg(not(feature = "image"))]
131 Ok(AgentValue::String(Arc::new(s)))
132 }
133 serde_json::Value::Array(arr) => {
134 let mut agent_arr = Vec::new();
135 for v in arr {
136 agent_arr.push(AgentValue::from_json(v)?);
137 }
138 Ok(AgentValue::array(agent_arr))
139 }
140 serde_json::Value::Object(obj) => {
141 let mut map = AgentValueMap::new();
142 for (k, v) in obj {
143 map.insert(k, AgentValue::from_json(v)?);
144 }
145 Ok(AgentValue::object(map))
146 }
147 }
148 }
149
150 pub fn to_json(&self) -> serde_json::Value {
151 match self {
152 AgentValue::Unit => serde_json::Value::Null,
153 AgentValue::Boolean(b) => (*b).into(),
154 AgentValue::Integer(i) => (*i).into(),
155 AgentValue::Number(n) => (*n).into(),
156 AgentValue::String(s) => s.as_str().into(),
157 #[cfg(feature = "image")]
158 AgentValue::Image(img) => img.get_base64().into(),
159 AgentValue::Object(o) => {
160 let mut map = serde_json::Map::new();
161 for (k, v) in o.iter() {
162 map.insert(k.clone(), v.to_json());
163 }
164 serde_json::Value::Object(map)
165 }
166 AgentValue::Array(a) => {
167 let arr: Vec<serde_json::Value> = a.iter().map(|v| v.to_json()).collect();
168 serde_json::Value::Array(arr)
169 }
170 }
171 }
172
173 pub fn from_serialize<T: Serialize>(value: &T) -> Result<Self, AgentError> {
175 let json_value = serde_json::to_value(value)
176 .map_err(|e| AgentError::InvalidValue(format!("Failed to serialize: {}", e)))?;
177 Self::from_json(json_value)
178 }
179
180 pub fn to_deserialize<T: for<'de> Deserialize<'de>>(&self) -> Result<T, AgentError> {
182 let json_value = self.to_json();
183 serde_json::from_value(json_value)
184 .map_err(|e| AgentError::InvalidValue(format!("Failed to deserialize: {}", e)))
185 }
186
187 pub fn is_unit(&self) -> bool {
188 matches!(self, AgentValue::Unit)
189 }
190
191 pub fn is_boolean(&self) -> bool {
192 matches!(self, AgentValue::Boolean(_))
193 }
194
195 pub fn is_integer(&self) -> bool {
196 matches!(self, AgentValue::Integer(_))
197 }
198
199 pub fn is_number(&self) -> bool {
200 matches!(self, AgentValue::Number(_))
201 }
202
203 pub fn is_string(&self) -> bool {
204 matches!(self, AgentValue::String(_))
205 }
206
207 #[cfg(feature = "image")]
208 pub fn is_image(&self) -> bool {
209 matches!(self, AgentValue::Image(_))
210 }
211
212 pub fn is_array(&self) -> bool {
213 matches!(self, AgentValue::Array(_))
214 }
215
216 pub fn is_object(&self) -> bool {
217 matches!(self, AgentValue::Object(_))
218 }
219
220 pub fn as_bool(&self) -> Option<bool> {
221 match self {
222 AgentValue::Boolean(b) => Some(*b),
223 _ => None,
224 }
225 }
226
227 pub fn as_i64(&self) -> Option<i64> {
228 match self {
229 AgentValue::Integer(i) => Some(*i),
230 AgentValue::Number(n) => Some(*n as i64),
231 _ => None,
232 }
233 }
234
235 pub fn as_f64(&self) -> Option<f64> {
236 match self {
237 AgentValue::Integer(i) => Some(*i as f64),
238 AgentValue::Number(n) => Some(*n),
239 _ => None,
240 }
241 }
242
243 pub fn as_str(&self) -> Option<&str> {
244 match self {
245 AgentValue::String(s) => Some(s),
246 _ => None,
247 }
248 }
249
250 #[cfg(feature = "image")]
251 pub fn as_image(&self) -> Option<Arc<PhotonImage>> {
252 match self {
253 AgentValue::Image(img) => Some(img.clone()),
254 _ => None,
255 }
256 }
257
258 pub fn as_object(&self) -> Option<&AgentValueMap<String, AgentValue>> {
259 match self {
260 AgentValue::Object(o) => Some(o),
261 _ => None,
262 }
263 }
264
265 pub fn as_object_mut(&mut self) -> Option<&mut AgentValueMap<String, AgentValue>> {
266 match self {
267 AgentValue::Object(o) => Some(Arc::make_mut(o)),
268 _ => None,
269 }
270 }
271
272 pub fn as_array(&self) -> Option<&Vec<AgentValue>> {
273 match self {
274 AgentValue::Array(a) => Some(a),
275 _ => None,
276 }
277 }
278
279 pub fn as_array_mut(&mut self) -> Option<&mut Vec<AgentValue>> {
280 match self {
281 AgentValue::Array(a) => Some(Arc::make_mut(a)),
282 _ => None,
283 }
284 }
285
286 pub fn get(&self, key: &str) -> Option<&AgentValue> {
287 self.as_object().and_then(|o| o.get(key))
288 }
289
290 pub fn get_mut(&mut self, key: &str) -> Option<&mut AgentValue> {
291 self.as_object_mut().and_then(|o| o.get_mut(key))
292 }
293
294 pub fn get_bool(&self, key: &str) -> Option<bool> {
295 self.get(key).and_then(|v| v.as_bool())
296 }
297
298 pub fn get_i64(&self, key: &str) -> Option<i64> {
299 self.get(key).and_then(|v| v.as_i64())
300 }
301
302 pub fn get_f64(&self, key: &str) -> Option<f64> {
303 self.get(key).and_then(|v| v.as_f64())
304 }
305
306 pub fn get_str(&self, key: &str) -> Option<&str> {
307 self.get(key).and_then(|v| v.as_str())
308 }
309
310 #[cfg(feature = "image")]
311 pub fn get_image(&self, key: &str) -> Option<Arc<PhotonImage>> {
312 self.get(key).and_then(|v| v.as_image())
313 }
314
315 pub fn get_object(&self, key: &str) -> Option<&AgentValueMap<String, AgentValue>> {
316 self.get(key).and_then(|v| v.as_object())
317 }
318
319 pub fn get_object_mut(&mut self, key: &str) -> Option<&mut AgentValueMap<String, AgentValue>> {
320 self.get_mut(key).and_then(|v| v.as_object_mut())
321 }
322
323 pub fn get_array(&self, key: &str) -> Option<&Vec<AgentValue>> {
324 self.get(key).and_then(|v| v.as_array())
325 }
326
327 pub fn get_array_mut(&mut self, key: &str) -> Option<&mut Vec<AgentValue>> {
328 self.get_mut(key).and_then(|v| v.as_array_mut())
329 }
330
331 pub fn set(&mut self, key: String, value: AgentValue) -> Result<(), AgentError> {
332 if let Some(obj) = self.as_object_mut() {
333 obj.insert(key, value);
334 Ok(())
335 } else {
336 Err(AgentError::InvalidValue(
337 "set can only be called on Object AgentValue".into(),
338 ))
339 }
340 }
341}
342
343impl Default for AgentValue {
344 fn default() -> Self {
345 AgentValue::Unit
346 }
347}
348
349impl PartialEq for AgentValue {
350 fn eq(&self, other: &Self) -> bool {
351 match (self, other) {
352 (AgentValue::Unit, AgentValue::Unit) => true,
353 (AgentValue::Boolean(b1), AgentValue::Boolean(b2)) => b1 == b2,
354 (AgentValue::Integer(i1), AgentValue::Integer(i2)) => i1 == i2,
355 (AgentValue::Number(n1), AgentValue::Number(n2)) => n1 == n2,
356 (AgentValue::String(s1), AgentValue::String(s2)) => s1 == s2,
357 #[cfg(feature = "image")]
358 (AgentValue::Image(i1), AgentValue::Image(i2)) => {
359 i1.get_width() == i2.get_width()
360 && i1.get_height() == i2.get_height()
361 && i1.get_raw_pixels() == i2.get_raw_pixels()
362 }
363 (AgentValue::Object(o1), AgentValue::Object(o2)) => o1 == o2,
364 (AgentValue::Array(a1), AgentValue::Array(a2)) => a1 == a2,
365 _ => false,
366 }
367 }
368}
369
370impl Serialize for AgentValue {
371 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
372 where
373 S: Serializer,
374 {
375 match self {
376 AgentValue::Unit => serializer.serialize_none(),
377 AgentValue::Boolean(b) => serializer.serialize_bool(*b),
378 AgentValue::Integer(i) => serializer.serialize_i64(*i),
379 AgentValue::Number(n) => serializer.serialize_f64(*n),
380 AgentValue::String(s) => serializer.serialize_str(s),
381 #[cfg(feature = "image")]
382 AgentValue::Image(img) => serializer.serialize_str(&img.get_base64()),
383 AgentValue::Object(o) => {
384 let mut map = serializer.serialize_map(Some(o.len()))?;
385 for (k, v) in o.iter() {
386 map.serialize_entry(k, v)?;
387 }
388 map.end()
389 }
390 AgentValue::Array(a) => {
391 let mut seq = serializer.serialize_seq(Some(a.len()))?;
392 for e in a.iter() {
393 seq.serialize_element(e)?;
394 }
395 seq.end()
396 }
397 }
398 }
399}
400
401impl<'de> Deserialize<'de> for AgentValue {
402 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
403 where
404 D: Deserializer<'de>,
405 {
406 let value = serde_json::Value::deserialize(deserializer)?;
407 AgentValue::from_json(value).map_err(|e| {
408 serde::de::Error::custom(format!("Failed to deserialize AgentValue: {}", e))
409 })
410 }
411}
412
413impl From<()> for AgentValue {
414 fn from(_: ()) -> Self {
415 AgentValue::unit()
416 }
417}
418
419impl From<bool> for AgentValue {
420 fn from(value: bool) -> Self {
421 AgentValue::boolean(value)
422 }
423}
424
425impl From<i32> for AgentValue {
426 fn from(value: i32) -> Self {
427 AgentValue::integer(value as i64)
428 }
429}
430
431impl From<i64> for AgentValue {
432 fn from(value: i64) -> Self {
433 AgentValue::integer(value)
434 }
435}
436
437impl From<f64> for AgentValue {
438 fn from(value: f64) -> Self {
439 AgentValue::number(value)
440 }
441}
442
443impl From<String> for AgentValue {
444 fn from(value: String) -> Self {
445 AgentValue::string(value)
446 }
447}
448
449impl From<&str> for AgentValue {
450 fn from(value: &str) -> Self {
451 AgentValue::string(value)
452 }
453}
454
455#[cfg(test)]
456mod tests {
457 use super::*;
458 use serde_json::json;
459
460 #[test]
461 fn test_partial_eq() {
462 let unit1 = AgentValue::unit();
464 let unit2 = AgentValue::unit();
465 assert_eq!(unit1, unit2);
466
467 let boolean1 = AgentValue::boolean(true);
468 let boolean2 = AgentValue::boolean(true);
469 assert_eq!(boolean1, boolean2);
470
471 let integer1 = AgentValue::integer(42);
472 let integer2 = AgentValue::integer(42);
473 assert_eq!(integer1, integer2);
474 let different = AgentValue::integer(100);
475 assert_ne!(integer1, different);
476
477 let number1 = AgentValue::number(3.14);
478 let number2 = AgentValue::number(3.14);
479 assert_eq!(number1, number2);
480
481 let string1 = AgentValue::string("hello");
482 let string2 = AgentValue::string("hello");
483 assert_eq!(string1, string2);
484
485 #[cfg(feature = "image")]
486 {
487 let image1 = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
488 let image2 = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
489 assert_eq!(image1, image2);
490 }
491
492 let obj1 = AgentValue::object(
493 [
494 ("key1".to_string(), AgentValue::string("value1")),
495 ("key2".to_string(), AgentValue::integer(2)),
496 ]
497 .into(),
498 );
499 let obj2 = AgentValue::object(
500 [
501 ("key1".to_string(), AgentValue::string("value1")),
502 ("key2".to_string(), AgentValue::integer(2)),
503 ]
504 .into(),
505 );
506 assert_eq!(obj1, obj2);
507
508 let arr1 = AgentValue::array(vec![
509 AgentValue::integer(1),
510 AgentValue::string("two"),
511 AgentValue::boolean(true),
512 ]);
513 let arr2 = AgentValue::array(vec![
514 AgentValue::integer(1),
515 AgentValue::string("two"),
516 AgentValue::boolean(true),
517 ]);
518 assert_eq!(arr1, arr2);
519
520 let mixed_types_1 = AgentValue::boolean(true);
521 let mixed_types_2 = AgentValue::integer(1);
522 assert_ne!(mixed_types_1, mixed_types_2);
523 }
524
525 #[test]
526 fn test_agent_value_constructors() {
527 let unit = AgentValue::unit();
529 assert_eq!(unit, AgentValue::Unit);
530
531 let boolean = AgentValue::boolean(true);
532 assert_eq!(boolean, AgentValue::Boolean(true));
533
534 let integer = AgentValue::integer(42);
535 assert_eq!(integer, AgentValue::Integer(42));
536
537 let number = AgentValue::number(3.14);
538 assert!(matches!(number, AgentValue::Number(_)));
539 if let AgentValue::Number(num) = number {
540 assert!((num - 3.14).abs() < f64::EPSILON);
541 }
542
543 let string = AgentValue::string("hello");
544 assert!(matches!(string, AgentValue::String(_)));
545 assert_eq!(string.as_str().unwrap(), "hello");
546
547 let text = AgentValue::string("multiline\ntext");
548 assert!(matches!(text, AgentValue::String(_)));
549 assert_eq!(text.as_str().unwrap(), "multiline\ntext");
550
551 let array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
552 assert!(matches!(array, AgentValue::Array(_)));
553 if let AgentValue::Array(arr) = array {
554 assert_eq!(arr.len(), 2);
555 assert_eq!(arr[0].as_i64().unwrap(), 1);
556 assert_eq!(arr[1].as_i64().unwrap(), 2);
557 }
558
559 let obj = AgentValue::object(
560 [
561 ("key1".to_string(), AgentValue::string("string1")),
562 ("key2".to_string(), AgentValue::integer(2)),
563 ]
564 .into(),
565 );
566 assert!(matches!(obj, AgentValue::Object(_)));
567 if let AgentValue::Object(obj) = obj {
568 assert_eq!(obj.get("key1").and_then(|v| v.as_str()), Some("string1"));
569 assert_eq!(obj.get("key2").and_then(|v| v.as_i64()), Some(2));
570 } else {
571 panic!("Object was not deserialized correctly");
572 }
573 }
574
575 #[test]
576 fn test_agent_value_from_json_value() {
577 let null = AgentValue::from_json(json!(null)).unwrap();
579 assert_eq!(null, AgentValue::Unit);
580
581 let boolean = AgentValue::from_json(json!(true)).unwrap();
582 assert_eq!(boolean, AgentValue::Boolean(true));
583
584 let integer = AgentValue::from_json(json!(42)).unwrap();
585 assert_eq!(integer, AgentValue::Integer(42));
586
587 let number = AgentValue::from_json(json!(3.14)).unwrap();
588 assert!(matches!(number, AgentValue::Number(_)));
589 if let AgentValue::Number(num) = number {
590 assert!((num - 3.14).abs() < f64::EPSILON);
591 }
592
593 let string = AgentValue::from_json(json!("hello")).unwrap();
594 assert!(matches!(string, AgentValue::String(_)));
595 if let AgentValue::String(s) = string {
596 assert_eq!(*s, "hello");
597 } else {
598 panic!("Expected string value");
599 }
600
601 let array = AgentValue::from_json(json!([1, "test", true])).unwrap();
602 assert!(matches!(array, AgentValue::Array(_)));
603 if let AgentValue::Array(arr) = array {
604 assert_eq!(arr.len(), 3);
605 assert_eq!(arr[0], AgentValue::Integer(1));
606 assert!(matches!(&arr[1], AgentValue::String(_)));
607 if let AgentValue::String(s) = &arr[1] {
608 assert_eq!(**s, "test");
609 } else {
610 panic!("Expected string value");
611 }
612 assert_eq!(arr[2], AgentValue::Boolean(true));
613 }
614
615 let object = AgentValue::from_json(json!({"key1": "string1", "key2": 2})).unwrap();
616 assert!(matches!(object, AgentValue::Object(_)));
617 if let AgentValue::Object(obj) = object {
618 assert_eq!(obj.get("key1").and_then(|v| v.as_str()), Some("string1"));
619 assert_eq!(obj.get("key2").and_then(|v| v.as_i64()), Some(2));
620 } else {
621 panic!("Object was not deserialized correctly");
622 }
623 }
624
625 #[test]
626 fn test_agent_value_test_methods() {
627 let unit = AgentValue::unit();
629 assert_eq!(unit.is_unit(), true);
630 assert_eq!(unit.is_boolean(), false);
631 assert_eq!(unit.is_integer(), false);
632 assert_eq!(unit.is_number(), false);
633 assert_eq!(unit.is_string(), false);
634 assert_eq!(unit.is_array(), false);
635 assert_eq!(unit.is_object(), false);
636 #[cfg(feature = "image")]
637 assert_eq!(unit.is_image(), false);
638
639 let boolean = AgentValue::boolean(true);
640 assert_eq!(boolean.is_unit(), false);
641 assert_eq!(boolean.is_boolean(), true);
642 assert_eq!(boolean.is_integer(), false);
643 assert_eq!(boolean.is_number(), false);
644 assert_eq!(boolean.is_string(), false);
645 assert_eq!(boolean.is_array(), false);
646 assert_eq!(boolean.is_object(), false);
647 #[cfg(feature = "image")]
648 assert_eq!(boolean.is_image(), false);
649
650 let integer = AgentValue::integer(42);
651 assert_eq!(integer.is_unit(), false);
652 assert_eq!(integer.is_boolean(), false);
653 assert_eq!(integer.is_integer(), true);
654 assert_eq!(integer.is_number(), false);
655 assert_eq!(integer.is_string(), false);
656 assert_eq!(integer.is_array(), false);
657 assert_eq!(integer.is_object(), false);
658 #[cfg(feature = "image")]
659 assert_eq!(integer.is_image(), false);
660
661 let number = AgentValue::number(3.14);
662 assert_eq!(number.is_unit(), false);
663 assert_eq!(number.is_boolean(), false);
664 assert_eq!(number.is_integer(), false);
665 assert_eq!(number.is_number(), true);
666 assert_eq!(number.is_string(), false);
667 assert_eq!(number.is_array(), false);
668 assert_eq!(number.is_object(), false);
669 #[cfg(feature = "image")]
670 assert_eq!(number.is_image(), false);
671
672 let string = AgentValue::string("hello");
673 assert_eq!(string.is_unit(), false);
674 assert_eq!(string.is_boolean(), false);
675 assert_eq!(string.is_integer(), false);
676 assert_eq!(string.is_number(), false);
677 assert_eq!(string.is_string(), true);
678 assert_eq!(string.is_array(), false);
679 assert_eq!(string.is_object(), false);
680 #[cfg(feature = "image")]
681 assert_eq!(string.is_image(), false);
682
683 let array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
684 assert_eq!(array.is_unit(), false);
685 assert_eq!(array.is_boolean(), false);
686 assert_eq!(array.is_integer(), false);
687 assert_eq!(array.is_number(), false);
688 assert_eq!(array.is_string(), false);
689 assert_eq!(array.is_array(), true);
690 assert_eq!(array.is_object(), false);
691 #[cfg(feature = "image")]
692 assert_eq!(array.is_image(), false);
693
694 let obj = AgentValue::object(
695 [
696 ("key1".to_string(), AgentValue::string("string1")),
697 ("key2".to_string(), AgentValue::integer(2)),
698 ]
699 .into(),
700 );
701 assert_eq!(obj.is_unit(), false);
702 assert_eq!(obj.is_boolean(), false);
703 assert_eq!(obj.is_integer(), false);
704 assert_eq!(obj.is_number(), false);
705 assert_eq!(obj.is_string(), false);
706 assert_eq!(obj.is_array(), false);
707 assert_eq!(obj.is_object(), true);
708 #[cfg(feature = "image")]
709 assert_eq!(obj.is_image(), false);
710
711 #[cfg(feature = "image")]
712 {
713 let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
714 assert_eq!(img.is_unit(), false);
715 assert_eq!(img.is_boolean(), false);
716 assert_eq!(img.is_integer(), false);
717 assert_eq!(img.is_number(), false);
718 assert_eq!(img.is_string(), false);
719 assert_eq!(img.is_array(), false);
720 assert_eq!(img.is_object(), false);
721 assert_eq!(img.is_image(), true);
722 }
723 }
724
725 #[test]
726 fn test_agent_value_as_methods() {
727 let boolean = AgentValue::boolean(true);
729 assert_eq!(boolean.as_bool(), Some(true));
730 assert_eq!(boolean.as_i64(), None);
731 assert_eq!(boolean.as_f64(), None);
732 assert_eq!(boolean.as_str(), None);
733 assert!(boolean.as_array().is_none());
734 assert_eq!(boolean.as_object(), None);
735 #[cfg(feature = "image")]
736 assert!(boolean.as_image().is_none());
737
738 let integer = AgentValue::integer(42);
739 assert_eq!(integer.as_bool(), None);
740 assert_eq!(integer.as_i64(), Some(42));
741 assert_eq!(integer.as_f64(), Some(42.0));
742 assert_eq!(integer.as_str(), None);
743 assert!(integer.as_array().is_none());
744 assert_eq!(integer.as_object(), None);
745 #[cfg(feature = "image")]
746 assert!(integer.as_image().is_none());
747
748 let number = AgentValue::number(3.14);
749 assert_eq!(number.as_bool(), None);
750 assert_eq!(number.as_i64(), Some(3)); assert_eq!(number.as_f64().unwrap(), 3.14);
752 assert_eq!(number.as_str(), None);
753 assert!(number.as_array().is_none());
754 assert_eq!(number.as_object(), None);
755 #[cfg(feature = "image")]
756 assert!(number.as_image().is_none());
757
758 let string = AgentValue::string("hello");
759 assert_eq!(string.as_bool(), None);
760 assert_eq!(string.as_i64(), None);
761 assert_eq!(string.as_f64(), None);
762 assert_eq!(string.as_str(), Some("hello"));
763 assert!(string.as_array().is_none());
764 assert_eq!(string.as_object(), None);
765 #[cfg(feature = "image")]
766 assert!(string.as_image().is_none());
767
768 let array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
769 assert_eq!(array.as_bool(), None);
770 assert_eq!(array.as_i64(), None);
771 assert_eq!(array.as_f64(), None);
772 assert_eq!(array.as_str(), None);
773 assert!(array.as_array().is_some());
774 if let Some(arr) = array.as_array() {
775 assert_eq!(arr.len(), 2);
776 assert_eq!(arr[0].as_i64().unwrap(), 1);
777 assert_eq!(arr[1].as_i64().unwrap(), 2);
778 }
779 assert_eq!(array.as_object(), None);
780 #[cfg(feature = "image")]
781 assert!(array.as_image().is_none());
782
783 let mut array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
784 if let Some(arr) = array.as_array_mut() {
785 arr.push(AgentValue::integer(3));
786 }
787
788 let obj = AgentValue::object(
789 [
790 ("key1".to_string(), AgentValue::string("string1")),
791 ("key2".to_string(), AgentValue::integer(2)),
792 ]
793 .into(),
794 );
795 assert_eq!(obj.as_bool(), None);
796 assert_eq!(obj.as_i64(), None);
797 assert_eq!(obj.as_f64(), None);
798 assert_eq!(obj.as_str(), None);
799 assert!(obj.as_array().is_none());
800 assert!(obj.as_object().is_some());
801 if let Some(value) = obj.as_object() {
802 assert_eq!(value.get("key1").and_then(|v| v.as_str()), Some("string1"));
803 assert_eq!(value.get("key2").and_then(|v| v.as_i64()), Some(2));
804 }
805 #[cfg(feature = "image")]
806 assert!(obj.as_image().is_none());
807
808 let mut obj = AgentValue::object(
809 [
810 ("key1".to_string(), AgentValue::string("string1")),
811 ("key2".to_string(), AgentValue::integer(2)),
812 ]
813 .into(),
814 );
815 if let Some(value) = obj.as_object_mut() {
816 value.insert("key3".to_string(), AgentValue::boolean(true));
817 }
818
819 #[cfg(feature = "image")]
820 {
821 let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
822 assert_eq!(img.as_bool(), None);
823 assert_eq!(img.as_i64(), None);
824 assert_eq!(img.as_f64(), None);
825 assert_eq!(img.as_str(), None);
826 assert!(img.as_array().is_none());
827 assert_eq!(img.as_object(), None);
828 assert!(img.as_image().is_some());
829 }
830 }
831
832 #[test]
833 fn test_agent_value_get_methods() {
834 const KEY: &str = "key";
836
837 let boolean = AgentValue::boolean(true);
838 assert_eq!(boolean.get(KEY), None);
839
840 let integer = AgentValue::integer(42);
841 assert_eq!(integer.get(KEY), None);
842
843 let number = AgentValue::number(3.14);
844 assert_eq!(number.get(KEY), None);
845
846 let string = AgentValue::string("hello");
847 assert_eq!(string.get(KEY), None);
848
849 let array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
850 assert_eq!(array.get(KEY), None);
851
852 let mut array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::integer(2)]);
853 assert_eq!(array.get_mut(KEY), None);
854
855 let mut obj = AgentValue::object(
856 [
857 ("k_boolean".to_string(), AgentValue::boolean(true)),
858 ("k_integer".to_string(), AgentValue::integer(42)),
859 ("k_number".to_string(), AgentValue::number(3.14)),
860 ("k_string".to_string(), AgentValue::string("string1")),
861 (
862 "k_array".to_string(),
863 AgentValue::array(vec![AgentValue::integer(1)]),
864 ),
865 (
866 "k_object".to_string(),
867 AgentValue::object(
868 [("inner_key".to_string(), AgentValue::integer(100))].into(),
869 ),
870 ),
871 #[cfg(feature = "image")]
872 (
873 "k_image".to_string(),
874 AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1)),
875 ),
876 ]
877 .into(),
878 );
879 assert_eq!(obj.get(KEY), None);
880 assert_eq!(obj.get_bool("k_boolean"), Some(true));
881 assert_eq!(obj.get_i64("k_integer"), Some(42));
882 assert_eq!(obj.get_f64("k_number"), Some(3.14));
883 assert_eq!(obj.get_str("k_string"), Some("string1"));
884 assert!(obj.get_array("k_array").is_some());
885 assert!(obj.get_array_mut("k_array").is_some());
886 assert!(obj.get_object("k_object").is_some());
887 assert!(obj.get_object_mut("k_object").is_some());
888 #[cfg(feature = "image")]
889 assert!(obj.get_image("k_image").is_some());
890
891 #[cfg(feature = "image")]
892 {
893 let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
894 assert_eq!(img.get(KEY), None);
895 }
896 }
897
898 #[test]
899 fn test_agent_value_set() {
900 let mut obj = AgentValue::object(AgentValueMap::new());
902 assert!(obj.set("key1".to_string(), AgentValue::integer(42)).is_ok());
903 assert_eq!(obj.get_i64("key1"), Some(42));
904
905 let mut not_obj = AgentValue::integer(10);
906 assert!(
907 not_obj
908 .set("key1".to_string(), AgentValue::integer(42))
909 .is_err()
910 );
911 }
912
913 #[test]
914 fn test_agent_value_default() {
915 assert_eq!(AgentValue::default(), AgentValue::Unit);
916
917 assert_eq!(AgentValue::boolean_default(), AgentValue::Boolean(false));
918 assert_eq!(AgentValue::integer_default(), AgentValue::Integer(0));
919 assert_eq!(AgentValue::number_default(), AgentValue::Number(0.0));
920 assert_eq!(
921 AgentValue::string_default(),
922 AgentValue::String(Arc::new(String::new()))
923 );
924 assert_eq!(
925 AgentValue::array_default(),
926 AgentValue::Array(Arc::new(Vec::new()))
927 );
928 assert_eq!(
929 AgentValue::object_default(),
930 AgentValue::Object(Arc::new(AgentValueMap::new()))
931 );
932
933 #[cfg(feature = "image")]
934 {
935 assert_eq!(
936 AgentValue::image_default(),
937 AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1))
938 );
939 }
940 }
941
942 #[test]
943 fn test_to_json() {
944 let unit = AgentValue::unit();
946 assert_eq!(unit.to_json(), json!(null));
947
948 let boolean = AgentValue::boolean(true);
949 assert_eq!(boolean.to_json(), json!(true));
950
951 let integer = AgentValue::integer(42);
952 assert_eq!(integer.to_json(), json!(42));
953
954 let number = AgentValue::number(3.14);
955 assert_eq!(number.to_json(), json!(3.14));
956
957 let string = AgentValue::string("hello");
958 assert_eq!(string.to_json(), json!("hello"));
959
960 let array = AgentValue::array(vec![AgentValue::integer(1), AgentValue::string("test")]);
961 assert_eq!(array.to_json(), json!([1, "test"]));
962
963 let obj = AgentValue::object(
964 [
965 ("key1".to_string(), AgentValue::string("string1")),
966 ("key2".to_string(), AgentValue::integer(2)),
967 ]
968 .into(),
969 );
970 assert_eq!(obj.to_json(), json!({"key1": "string1", "key2": 2}));
971
972 #[cfg(feature = "image")]
973 {
974 let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
975 assert_eq!(
976 img.to_json(),
977 json!(
978 "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg=="
979 )
980 );
981 }
982 }
983
984 #[test]
985 fn test_agent_value_serialization() {
986 {
988 let null = AgentValue::Unit;
989 assert_eq!(serde_json::to_string(&null).unwrap(), "null");
990 }
991
992 {
994 let boolean_t = AgentValue::boolean(true);
995 assert_eq!(serde_json::to_string(&boolean_t).unwrap(), "true");
996
997 let boolean_f = AgentValue::boolean(false);
998 assert_eq!(serde_json::to_string(&boolean_f).unwrap(), "false");
999 }
1000
1001 {
1003 let integer = AgentValue::integer(42);
1004 assert_eq!(serde_json::to_string(&integer).unwrap(), "42");
1005 }
1006
1007 {
1009 let num = AgentValue::number(3.14);
1010 assert_eq!(serde_json::to_string(&num).unwrap(), "3.14");
1011
1012 let num = AgentValue::number(3.0);
1013 assert_eq!(serde_json::to_string(&num).unwrap(), "3.0");
1014 }
1015
1016 {
1018 let s = AgentValue::string("Hello, world!");
1019 assert_eq!(serde_json::to_string(&s).unwrap(), "\"Hello, world!\"");
1020
1021 let s = AgentValue::string("hello\nworld\n\n");
1022 assert_eq!(serde_json::to_string(&s).unwrap(), r#""hello\nworld\n\n""#);
1023 }
1024
1025 #[cfg(feature = "image")]
1027 {
1028 let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1029 assert_eq!(
1030 serde_json::to_string(&img).unwrap(),
1031 r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#
1032 );
1033 }
1034
1035 #[cfg(feature = "image")]
1037 {
1038 let img = AgentValue::image_arc(Arc::new(PhotonImage::new(vec![0u8; 4], 1, 1)));
1039 assert_eq!(
1040 serde_json::to_string(&img).unwrap(),
1041 r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#
1042 );
1043 }
1044
1045 {
1047 let array = AgentValue::array(vec![
1048 AgentValue::integer(1),
1049 AgentValue::string("test"),
1050 AgentValue::object(
1051 [
1052 ("key1".to_string(), AgentValue::string("test")),
1053 ("key2".to_string(), AgentValue::integer(2)),
1054 ]
1055 .into(),
1056 ),
1057 ]);
1058 assert_eq!(
1059 serde_json::to_string(&array).unwrap(),
1060 r#"[1,"test",{"key1":"test","key2":2}]"#
1061 );
1062 }
1063
1064 {
1066 let obj = AgentValue::object(
1067 [
1068 ("key1".to_string(), AgentValue::string("test")),
1069 ("key2".to_string(), AgentValue::integer(3)),
1070 ]
1071 .into(),
1072 );
1073 assert_eq!(
1074 serde_json::to_string(&obj).unwrap(),
1075 r#"{"key1":"test","key2":3}"#
1076 );
1077 }
1078 }
1079
1080 #[test]
1081 fn test_agent_value_deserialization() {
1082 {
1084 let deserialized: AgentValue = serde_json::from_str("null").unwrap();
1085 assert_eq!(deserialized, AgentValue::Unit);
1086 }
1087
1088 {
1090 let deserialized: AgentValue = serde_json::from_str("false").unwrap();
1091 assert_eq!(deserialized, AgentValue::boolean(false));
1092
1093 let deserialized: AgentValue = serde_json::from_str("true").unwrap();
1094 assert_eq!(deserialized, AgentValue::boolean(true));
1095 }
1096
1097 {
1099 let deserialized: AgentValue = serde_json::from_str("123").unwrap();
1100 assert_eq!(deserialized, AgentValue::integer(123));
1101 }
1102
1103 {
1105 let deserialized: AgentValue = serde_json::from_str("3.14").unwrap();
1106 assert_eq!(deserialized, AgentValue::number(3.14));
1107
1108 let deserialized: AgentValue = serde_json::from_str("3.0").unwrap();
1109 assert_eq!(deserialized, AgentValue::number(3.0));
1110 }
1111
1112 {
1114 let deserialized: AgentValue = serde_json::from_str("\"Hello, world!\"").unwrap();
1115 assert_eq!(deserialized, AgentValue::string("Hello, world!"));
1116
1117 let deserialized: AgentValue = serde_json::from_str(r#""hello\nworld\n\n""#).unwrap();
1118 assert_eq!(deserialized, AgentValue::string("hello\nworld\n\n"));
1119 }
1120
1121 #[cfg(feature = "image")]
1123 {
1124 let deserialized: AgentValue = serde_json::from_str(
1125 r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#,
1126 )
1127 .unwrap();
1128 assert!(matches!(deserialized, AgentValue::Image(_)));
1129 }
1130
1131 {
1133 let deserialized: AgentValue =
1134 serde_json::from_str(r#"[1,"test",{"key1":"test","key2":2}]"#).unwrap();
1135 assert!(matches!(deserialized, AgentValue::Array(_)));
1136 if let AgentValue::Array(arr) = deserialized {
1137 assert_eq!(arr.len(), 3, "Array length mismatch after serialization");
1138 assert_eq!(arr[0], AgentValue::integer(1));
1139 assert_eq!(arr[1], AgentValue::string("test"));
1140 assert_eq!(
1141 arr[2],
1142 AgentValue::object(
1143 [
1144 ("key1".to_string(), AgentValue::string("test")),
1145 ("key2".to_string(), AgentValue::integer(2)),
1146 ]
1147 .into()
1148 )
1149 );
1150 }
1151 }
1152
1153 {
1155 let deserialized: AgentValue =
1156 serde_json::from_str(r#"{"key1":"test","key2":3}"#).unwrap();
1157 assert_eq!(
1158 deserialized,
1159 AgentValue::object(
1160 [
1161 ("key1".to_string(), AgentValue::string("test")),
1162 ("key2".to_string(), AgentValue::integer(3)),
1163 ]
1164 .into()
1165 )
1166 );
1167 }
1168 }
1169
1170 #[test]
1171 fn test_agent_value_into() {
1172 let from_unit: AgentValue = ().into();
1174 assert_eq!(from_unit, AgentValue::Unit);
1175
1176 let from_bool: AgentValue = true.into();
1177 assert_eq!(from_bool, AgentValue::Boolean(true));
1178
1179 let from_i32: AgentValue = 42i32.into();
1180 assert_eq!(from_i32, AgentValue::Integer(42));
1181
1182 let from_i64: AgentValue = 100i64.into();
1183 assert_eq!(from_i64, AgentValue::Integer(100));
1184
1185 let from_f64: AgentValue = 3.14f64.into();
1186 assert_eq!(from_f64, AgentValue::Number(3.14));
1187
1188 let from_string: AgentValue = "hello".to_string().into();
1189 assert_eq!(
1190 from_string,
1191 AgentValue::String(Arc::new("hello".to_string()))
1192 );
1193
1194 let from_str: AgentValue = "world".into();
1195 assert_eq!(from_str, AgentValue::String(Arc::new("world".to_string())));
1196 }
1197
1198 #[test]
1199 fn test_serialize_deserialize_roundtrip() {
1200 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1201 struct TestStruct {
1202 name: String,
1203 age: i64,
1204 active: bool,
1205 }
1206
1207 let test_data = TestStruct {
1208 name: "Alice".to_string(),
1209 age: 30,
1210 active: true,
1211 };
1212
1213 let agent_data = AgentValue::from_serialize(&test_data).unwrap();
1215 assert_eq!(agent_data.get_str("name"), Some("Alice"));
1216 assert_eq!(agent_data.get_i64("age"), Some(30));
1217 assert_eq!(agent_data.get_bool("active"), Some(true));
1218
1219 let restored: TestStruct = agent_data.to_deserialize().unwrap();
1220 assert_eq!(restored, test_data);
1221 }
1222
1223 #[test]
1224 fn test_serialize_deserialize_nested() {
1225 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1226 struct Address {
1227 street: String,
1228 city: String,
1229 zip: String,
1230 }
1231
1232 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1233 struct Person {
1234 name: String,
1235 age: i64,
1236 address: Address,
1237 tags: Vec<String>,
1238 }
1239
1240 let person = Person {
1241 name: "Bob".to_string(),
1242 age: 25,
1243 address: Address {
1244 street: "123 Main St".to_string(),
1245 city: "Springfield".to_string(),
1246 zip: "12345".to_string(),
1247 },
1248 tags: vec!["developer".to_string(), "rust".to_string()],
1249 };
1250
1251 let agent_data = AgentValue::from_serialize(&person).unwrap();
1253 assert_eq!(agent_data.get_str("name"), Some("Bob"));
1254
1255 let address = agent_data.get_object("address").unwrap();
1256 assert_eq!(
1257 address.get("city").and_then(|v| v.as_str()),
1258 Some("Springfield")
1259 );
1260
1261 let tags = agent_data.get_array("tags").unwrap();
1262 assert_eq!(tags.len(), 2);
1263 assert_eq!(tags[0].as_str(), Some("developer"));
1264
1265 let restored: Person = agent_data.to_deserialize().unwrap();
1266 assert_eq!(restored, person);
1267 }
1268}