id3_cli/
text_format.rs

1use crate::error::Error;
2use clap::ValueEnum;
3use serde::Serialize;
4
5/// Format of input/output text values.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
7#[clap(about = "")]
8pub enum TextFormat {
9    Json,
10    Yaml,
11}
12
13impl TextFormat {
14    /// Convert a [serializable](Serialize) value to a string according to the specified [format](TextFormat).
15    pub fn serialize(self, value: &impl Serialize) -> Result<String, Error> {
16        match self {
17            TextFormat::Json => serde_json::to_string_pretty(value).map_err(Error::from),
18            TextFormat::Yaml => serde_yaml::to_string(value).map_err(Error::from),
19        }
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::TextFormat;
26    use pretty_assertions::assert_eq;
27    use serde::Serialize;
28    use text_block_macros::text_block;
29
30    #[derive(Debug, Serialize)]
31    struct TestSubject {
32        number: i32,
33        string: &'static str,
34        array: &'static [TestSubject],
35    }
36
37    const TEST_SUBJECT: TestSubject = TestSubject {
38        number: 123,
39        string: "text",
40        array: &[
41            TestSubject {
42                number: 0,
43                string: "a",
44                array: &[],
45            },
46            TestSubject {
47                number: 1,
48                string: "a",
49                array: &[TestSubject {
50                    number: 0,
51                    string: "b",
52                    array: &[],
53                }],
54            },
55        ],
56    };
57
58    #[test]
59    fn json() {
60        let received = TextFormat::Json
61            .serialize(&TEST_SUBJECT)
62            .expect("serialize test subject");
63        let expected = text_block! {
64            r#"{"#
65            r#"  "number": 123,"#
66            r#"  "string": "text","#
67            r#"  "array": ["#
68            r#"    {"#
69            r#"      "number": 0,"#
70            r#"      "string": "a","#
71            r#"      "array": []"#
72            r#"    },"#
73            r#"    {"#
74            r#"      "number": 1,"#
75            r#"      "string": "a","#
76            r#"      "array": ["#
77            r#"        {"#
78            r#"          "number": 0,"#
79            r#"          "string": "b","#
80            r#"          "array": []"#
81            r#"        }"#
82            r#"      ]"#
83            r#"    }"#
84            r#"  ]"#
85            r#"}"#
86        };
87        eprintln!("RECEIVED:\n{received}");
88        assert_eq!(received, expected);
89    }
90
91    #[test]
92    fn yaml() {
93        let received = TextFormat::Yaml
94            .serialize(&TEST_SUBJECT)
95            .expect("serialize test subject");
96        let expected = text_block! {
97            "number: 123"
98            "string: text"
99            "array:"
100            "- number: 0"
101            "  string: a"
102            "  array: []"
103            "- number: 1"
104            "  string: a"
105            "  array:"
106            "  - number: 0"
107            "    string: b"
108            "    array: []"
109            ""
110        };
111        eprintln!("RECEIVED:\n{received}");
112        assert_eq!(received, expected);
113    }
114}