agent_chain_core/load/
dump.rs

1//! Dump objects to JSON.
2//!
3//! This module provides functions for serializing LangChain objects to JSON,
4//! mirroring `langchain_core.load.dump`.
5
6use serde::Serialize;
7use serde_json::Value;
8
9use super::serializable::{Serializable, Serialized, to_json_not_implemented};
10
11/// Return a default serialized value for an object.
12///
13/// If the object is serializable, returns its JSON representation.
14/// Otherwise, returns a SerializedNotImplemented.
15///
16/// # Arguments
17///
18/// * `obj` - The object to serialize.
19pub fn default_serializer<T: Serialize>(obj: &T) -> Value {
20    match serde_json::to_value(obj) {
21        Ok(v) => v,
22        Err(_) => serde_json::to_value(to_json_not_implemented(&Value::Null)).unwrap_or_default(),
23    }
24}
25
26/// Serialize a Serializable object to a JSON string.
27///
28/// # Arguments
29///
30/// * `obj` - The object to serialize.
31/// * `pretty` - Whether to pretty print the JSON. If `true`, the JSON will be
32///   indented with 2 spaces.
33///
34/// # Returns
35///
36/// A JSON string representation of the object.
37///
38/// # Errors
39///
40/// Returns an error if serialization fails.
41pub fn dumps<T: Serializable + Serialize>(obj: &T, pretty: bool) -> crate::Result<String> {
42    let serialized = obj.to_json();
43    if pretty {
44        serde_json::to_string_pretty(&serialized).map_err(crate::Error::from)
45    } else {
46        serde_json::to_string(&serialized).map_err(crate::Error::from)
47    }
48}
49
50/// Serialize any serde-serializable object to a JSON string.
51///
52/// This is a fallback for objects that don't implement Serializable.
53///
54/// # Arguments
55///
56/// * `obj` - The object to serialize.
57/// * `pretty` - Whether to pretty print the JSON.
58///
59/// # Returns
60///
61/// A JSON string representation of the object.
62///
63/// # Errors
64///
65/// Returns an error if serialization fails.
66pub fn dumps_value<T: Serialize>(obj: &T, pretty: bool) -> crate::Result<String> {
67    if pretty {
68        serde_json::to_string_pretty(obj).map_err(crate::Error::from)
69    } else {
70        serde_json::to_string(obj).map_err(crate::Error::from)
71    }
72}
73
74/// Serialize a Serialized enum to a JSON string.
75///
76/// # Arguments
77///
78/// * `serialized` - The Serialized enum to convert to string.
79/// * `pretty` - Whether to pretty print the JSON.
80///
81/// # Returns
82///
83/// A JSON string representation.
84///
85/// # Errors
86///
87/// Returns an error if serialization fails.
88pub fn dumps_serialized(serialized: &Serialized, pretty: bool) -> crate::Result<String> {
89    if pretty {
90        serde_json::to_string_pretty(serialized).map_err(crate::Error::from)
91    } else {
92        serde_json::to_string(serialized).map_err(crate::Error::from)
93    }
94}
95
96/// Serialize a Serializable object to a Value (dict-like structure).
97///
98/// # Arguments
99///
100/// * `obj` - The object to serialize.
101///
102/// # Returns
103///
104/// A serde_json::Value representation of the object.
105///
106/// # Errors
107///
108/// Returns an error if serialization fails.
109pub fn dumpd<T: Serializable + Serialize>(obj: &T) -> crate::Result<Value> {
110    let json_string = dumps(obj, false)?;
111    serde_json::from_str(&json_string).map_err(crate::Error::from)
112}
113
114/// Serialize any serde-serializable object to a Value.
115///
116/// This is a fallback for objects that don't implement Serializable.
117///
118/// # Arguments
119///
120/// * `obj` - The object to serialize.
121///
122/// # Returns
123///
124/// A serde_json::Value representation of the object.
125///
126/// # Errors
127///
128/// Returns an error if serialization fails.
129pub fn dumpd_value<T: Serialize>(obj: &T) -> crate::Result<Value> {
130    serde_json::to_value(obj).map_err(crate::Error::from)
131}
132
133/// Serialize a Serialized enum to a Value.
134///
135/// # Arguments
136///
137/// * `serialized` - The Serialized enum to convert.
138///
139/// # Returns
140///
141/// A serde_json::Value representation.
142///
143/// # Errors
144///
145/// Returns an error if serialization fails.
146pub fn dumpd_serialized(serialized: &Serialized) -> crate::Result<Value> {
147    serde_json::to_value(serialized).map_err(crate::Error::from)
148}
149
150#[cfg(test)]
151mod tests {
152    use super::*;
153    use serde::{Deserialize, Serialize};
154    use std::collections::HashMap;
155
156    #[derive(Debug, Serialize, Deserialize)]
157    struct TestModel {
158        name: String,
159        value: i32,
160    }
161
162    impl Serializable for TestModel {
163        fn is_lc_serializable() -> bool {
164            true
165        }
166
167        fn get_lc_namespace() -> Vec<String> {
168            vec!["test".to_string(), "models".to_string()]
169        }
170    }
171
172    #[test]
173    fn test_dumps_serializable() {
174        let model = TestModel {
175            name: "test".to_string(),
176            value: 42,
177        };
178
179        let json = dumps(&model, false).unwrap();
180        assert!(json.contains("constructor"));
181        assert!(json.contains("test"));
182    }
183
184    #[test]
185    fn test_dumps_pretty() {
186        let model = TestModel {
187            name: "test".to_string(),
188            value: 42,
189        };
190
191        let json = dumps(&model, true).unwrap();
192        assert!(json.contains('\n'));
193    }
194
195    #[test]
196    fn test_dumpd() {
197        let model = TestModel {
198            name: "test".to_string(),
199            value: 42,
200        };
201
202        let value = dumpd(&model).unwrap();
203        assert!(value.is_object());
204        assert_eq!(
205            value.get("type").and_then(|v| v.as_str()),
206            Some("constructor")
207        );
208    }
209
210    #[test]
211    fn test_dumps_value() {
212        let data = HashMap::from([("key", "value")]);
213        let json = dumps_value(&data, false).unwrap();
214        assert!(json.contains("key"));
215        assert!(json.contains("value"));
216    }
217}