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 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    // 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
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    /// Create AgentValue from Serialize
174    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    /// Convert AgentValue to a Deserialize
181    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        // Test PartialEq implementation
463        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        // Test AgentValue constructors
528        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        // Test converting from JSON value to AgentValue
578        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        // Test test methods on AgentValue
628        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        // Test accessor methods on AgentValue
728        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)); // truncated
751        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        // Test get methods on AgentValue
835        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        // Test set method on AgentValue
901        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        // Test to_json
945        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        // Test Null serialization
987        {
988            let null = AgentValue::Unit;
989            assert_eq!(serde_json::to_string(&null).unwrap(), "null");
990        }
991
992        // Test Boolean serialization
993        {
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        // Test Integer serialization
1002        {
1003            let integer = AgentValue::integer(42);
1004            assert_eq!(serde_json::to_string(&integer).unwrap(), "42");
1005        }
1006
1007        // Test Number serialization
1008        {
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        // Test String serialization
1017        {
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        // Test Image serialization
1026        #[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        // Test Arc Image serialization
1036        #[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        // Test Array serialization
1046        {
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        // Test Object serialization
1065        {
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        // Test Null deserialization
1083        {
1084            let deserialized: AgentValue = serde_json::from_str("null").unwrap();
1085            assert_eq!(deserialized, AgentValue::Unit);
1086        }
1087
1088        // Test Boolean deserialization
1089        {
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        // Test Integer deserialization
1098        {
1099            let deserialized: AgentValue = serde_json::from_str("123").unwrap();
1100            assert_eq!(deserialized, AgentValue::integer(123));
1101        }
1102
1103        // Test Number deserialization
1104        {
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        // Test String deserialization
1113        {
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        // Test Image deserialization
1122        #[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        // Test Array deserialization
1132        {
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        // Test Object deserialization
1154        {
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        // Test From implementations for AgentValue
1173        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        // Test AgentData roundtrip
1214        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        // Test AgentData roundtrip with nested structures
1252        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}