Skip to main content

synwire_core/output_parsers/
json.rs

1//! JSON output parser that deserialises text to `serde_json::Value`.
2
3use crate::error::{ParseError, SynwireError};
4use crate::output_parsers::OutputParser;
5
6/// Parser that deserialises JSON text to `serde_json::Value`.
7///
8/// Useful when you need structured data from a model but do not have
9/// a specific Rust type to deserialise into.
10///
11/// # Examples
12///
13/// ```
14/// use synwire_core::output_parsers::{OutputParser, JsonOutputParser};
15///
16/// let parser = JsonOutputParser;
17/// let result = parser.parse(r#"{"key": "value"}"#).unwrap();
18/// assert_eq!(result["key"], "value");
19/// ```
20pub struct JsonOutputParser;
21
22impl OutputParser for JsonOutputParser {
23    type Output = serde_json::Value;
24
25    fn parse(&self, text: &str) -> Result<serde_json::Value, SynwireError> {
26        serde_json::from_str(text).map_err(|e| {
27            SynwireError::from(ParseError::ParseFailed {
28                message: format!("Failed to parse JSON: {e}"),
29            })
30        })
31    }
32
33    fn get_format_instructions(&self) -> String {
34        "Respond with valid JSON.".to_string()
35    }
36}
37
38#[cfg(test)]
39#[allow(clippy::unwrap_used)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn test_json_parser_valid() {
45        let parser = JsonOutputParser;
46        let result = parser.parse(r#"{"name": "Alice", "age": 30}"#).unwrap();
47        assert_eq!(result["name"], "Alice");
48        assert_eq!(result["age"], 30);
49    }
50
51    #[test]
52    fn test_json_parser_invalid() {
53        let parser = JsonOutputParser;
54        let result = parser.parse("not valid json");
55        assert!(result.is_err());
56    }
57
58    #[test]
59    fn test_json_parser_array() {
60        let parser = JsonOutputParser;
61        let result = parser.parse(r"[1, 2, 3]").unwrap();
62        assert_eq!(result.as_array().unwrap().len(), 3);
63    }
64
65    #[test]
66    fn test_json_parser_format_instructions() {
67        let parser = JsonOutputParser;
68        assert_eq!(parser.get_format_instructions(), "Respond with valid JSON.");
69    }
70}