Skip to main content

rskit_codec/
json.rs

1use rskit_errors::{AppError, AppResult};
2use serde_json::Value;
3
4use crate::codec::Codec;
5
6/// Built-in JSON codec.
7///
8/// Always available because [`serde_json`] backs the crate's value model.
9/// Encodes as pretty-printed JSON.
10#[derive(Debug, Clone, Copy, Default)]
11pub struct JsonCodec;
12
13impl Codec for JsonCodec {
14    fn name(&self) -> &'static str {
15        "json"
16    }
17
18    fn encode_value(&self, value: &Value) -> AppResult<String> {
19        serde_json::to_string_pretty(value).map_err(|err| {
20            AppError::invalid_input("codec", "failed to serialize value as JSON").with_cause(err)
21        })
22    }
23
24    fn decode_value(&self, contents: &str) -> AppResult<Value> {
25        serde_json::from_str(contents)
26            .map_err(|err| AppError::invalid_input("codec", "failed to parse JSON").with_cause(err))
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn round_trips_value() {
36        let codec = JsonCodec;
37        let value: Value = serde_json::json!({ "a": 1, "nested": { "b": true } });
38
39        let encoded = codec.encode_value(&value).unwrap();
40        let decoded = codec.decode_value(&encoded).unwrap();
41
42        assert_eq!(decoded, value);
43        assert_eq!(codec.name(), "json");
44    }
45
46    #[test]
47    fn rejects_malformed_input() {
48        let err = JsonCodec.decode_value("{ not json").unwrap_err();
49        assert!(err.to_string().contains("parse"));
50    }
51}