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