agent_stream_kit/
value.rs

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    // Primitive types stored directly
20    Unit,
21    Boolean(bool),
22    Integer(i64),
23    Number(f64),
24
25    // Larger data structures use reference counting
26    String(Arc<String>),
27
28    #[cfg(feature = "image")]
29    Image(Arc<PhotonImage>),
30
31    // Recursive data structures
32    Array(Arc<Vec<AgentValue>>),
33    Object(Arc<AgentValueMap<String, AgentValue>>),
34
35    // Error
36    // special type to represent errors
37    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, // Errors are not serializable
175        }
176    }
177
178    /// Create AgentValue from Serialize
179    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    /// Convert AgentValue to a Deserialize
186    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(), // Errors are not serializable
403        }
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        // Test PartialEq implementation
469        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        // Test AgentValue constructors
534        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        // Test converting from JSON value to AgentValue
584        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        // Test test methods on AgentValue
634        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        // Test accessor methods on AgentValue
734        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)); // truncated
757        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        // Test get methods on AgentValue
841        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        // Test set method on AgentValue
907        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        // Test to_json
951        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        // Test Null serialization
993        {
994            let null = AgentValue::Unit;
995            assert_eq!(serde_json::to_string(&null).unwrap(), "null");
996        }
997
998        // Test Boolean serialization
999        {
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        // Test Integer serialization
1008        {
1009            let integer = AgentValue::integer(42);
1010            assert_eq!(serde_json::to_string(&integer).unwrap(), "42");
1011        }
1012
1013        // Test Number serialization
1014        {
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        // Test String serialization
1023        {
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        // Test Image serialization
1032        #[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        // Test Arc Image serialization
1042        #[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        // Test Array serialization
1052        {
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        // Test Object serialization
1071        {
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        // Test Null deserialization
1089        {
1090            let deserialized: AgentValue = serde_json::from_str("null").unwrap();
1091            assert_eq!(deserialized, AgentValue::Unit);
1092        }
1093
1094        // Test Boolean deserialization
1095        {
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        // Test Integer deserialization
1104        {
1105            let deserialized: AgentValue = serde_json::from_str("123").unwrap();
1106            assert_eq!(deserialized, AgentValue::integer(123));
1107        }
1108
1109        // Test Number deserialization
1110        {
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        // Test String deserialization
1119        {
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        // Test Image deserialization
1128        #[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        // Test Array deserialization
1138        {
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        // Test Object deserialization
1160        {
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        // Test From implementations for AgentValue
1179        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        // Test AgentData roundtrip
1220        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        // Test AgentData roundtrip with nested structures
1258        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}