1use rskit_errors::{AppError, AppResult};
2use serde_json::Value;
3
4use crate::codec::Codec;
5
6#[derive(Debug, Clone, Copy, Default)]
12pub struct TomlCodec;
13
14impl Codec for TomlCodec {
15 fn name(&self) -> &'static str {
16 "toml"
17 }
18
19 fn encode_value(&self, value: &Value) -> AppResult<String> {
20 toml::to_string(value).map_err(|err| {
21 AppError::invalid_input("codec", "failed to serialize value as TOML").with_cause(err)
22 })
23 }
24
25 fn decode_value(&self, contents: &str) -> AppResult<Value> {
26 toml::from_str::<Value>(contents)
27 .map_err(|err| AppError::invalid_input("codec", "failed to parse TOML").with_cause(err))
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn round_trips_table() {
37 let codec = TomlCodec;
38 let value: Value = serde_json::json!({
39 "name": "svc",
40 "retries": 3,
41 "nested": { "enabled": true }
42 });
43
44 let encoded = codec.encode_value(&value).unwrap();
45 let decoded = codec.decode_value(&encoded).unwrap();
46
47 assert_eq!(decoded, value);
48 assert_eq!(codec.name(), "toml");
49 }
50
51 #[test]
52 fn rejects_malformed_input() {
53 let err = TomlCodec.decode_value("= not valid").unwrap_err();
54 assert!(err.to_string().contains("parse"));
55 }
56
57 #[test]
58 fn rejects_unrepresentable_values() {
59 let err = TomlCodec.encode_value(&Value::Null).unwrap_err();
62 assert!(err.to_string().contains("serialize"));
63 }
64}