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