wp_model_core/model/
fmt_def.rs

1use std::fmt::Display;
2
3use serde_derive::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
6pub enum OutFmt {
7    #[serde(rename = "fmt")]
8    Fmt(TextFmt),
9}
10impl Default for OutFmt {
11    fn default() -> Self {
12        OutFmt::Fmt(TextFmt::default())
13    }
14}
15#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Default, Copy)]
16pub enum TextFmt {
17    #[serde(rename = "json")]
18    Json,
19    #[serde(rename = "csv")]
20    Csv,
21    #[serde(rename = "show")]
22    Show,
23    #[serde(rename = "kv")]
24    Kv,
25    #[serde(rename = "raw")]
26    #[default]
27    Raw,
28    #[serde(rename = "proto")]
29    Proto,
30    #[serde(rename = "proto-text")]
31    ProtoText,
32}
33
34impl From<&str> for TextFmt {
35    fn from(value: &str) -> Self {
36        if value == "json" {
37            TextFmt::Json
38        } else if value == "csv" {
39            TextFmt::Csv
40        } else if value == "show" {
41            TextFmt::Show
42        } else if value == "kv" {
43            TextFmt::Kv
44        } else if value == "proto" {
45            TextFmt::Proto
46        } else if value == "proto-text" {
47            TextFmt::ProtoText
48        } else {
49            TextFmt::Raw
50        }
51    }
52}
53
54impl Display for TextFmt {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        match self {
57            TextFmt::Json => write!(f, "json"),
58            TextFmt::Csv => write!(f, "csv"),
59            TextFmt::Show => write!(f, "show"),
60            TextFmt::Kv => write!(f, "kv"),
61            TextFmt::Raw => write!(f, "raw"),
62            TextFmt::Proto => write!(f, "proto"),
63            TextFmt::ProtoText => write!(f, "proto-text"),
64        }
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    // ========== TextFmt tests ==========
73
74    #[test]
75    fn test_text_fmt_default() {
76        assert_eq!(TextFmt::default(), TextFmt::Raw);
77    }
78
79    #[test]
80    fn test_text_fmt_from_str() {
81        assert_eq!(TextFmt::from("json"), TextFmt::Json);
82        assert_eq!(TextFmt::from("csv"), TextFmt::Csv);
83        assert_eq!(TextFmt::from("show"), TextFmt::Show);
84        assert_eq!(TextFmt::from("kv"), TextFmt::Kv);
85        assert_eq!(TextFmt::from("proto"), TextFmt::Proto);
86        assert_eq!(TextFmt::from("proto-text"), TextFmt::ProtoText);
87    }
88
89    #[test]
90    fn test_text_fmt_from_str_unknown() {
91        // Unknown values should default to Raw
92        assert_eq!(TextFmt::from("unknown"), TextFmt::Raw);
93        assert_eq!(TextFmt::from(""), TextFmt::Raw);
94        assert_eq!(TextFmt::from("JSON"), TextFmt::Raw); // case sensitive
95    }
96
97    #[test]
98    fn test_text_fmt_display() {
99        assert_eq!(format!("{}", TextFmt::Json), "json");
100        assert_eq!(format!("{}", TextFmt::Csv), "csv");
101        assert_eq!(format!("{}", TextFmt::Show), "show");
102        assert_eq!(format!("{}", TextFmt::Kv), "kv");
103        assert_eq!(format!("{}", TextFmt::Raw), "raw");
104        assert_eq!(format!("{}", TextFmt::Proto), "proto");
105        assert_eq!(format!("{}", TextFmt::ProtoText), "proto-text");
106    }
107
108    #[test]
109    fn test_text_fmt_roundtrip() {
110        // from -> display should be consistent
111        let formats = ["json", "csv", "show", "kv", "proto", "proto-text"];
112        for fmt_str in formats {
113            let fmt = TextFmt::from(fmt_str);
114            assert_eq!(format!("{}", fmt), fmt_str);
115        }
116    }
117
118    // ========== OutFmt tests ==========
119
120    #[test]
121    fn test_out_fmt_default() {
122        let out = OutFmt::default();
123        assert_eq!(out, OutFmt::Fmt(TextFmt::Raw));
124    }
125
126    #[test]
127    fn test_out_fmt_with_text_fmt() {
128        let out = OutFmt::Fmt(TextFmt::Json);
129        assert_eq!(out, OutFmt::Fmt(TextFmt::Json));
130    }
131
132    // ========== Serde tests ==========
133
134    #[test]
135    fn test_text_fmt_serde() {
136        let fmt = TextFmt::Json;
137        let json = serde_json::to_string(&fmt).unwrap();
138        assert_eq!(json, "\"json\"");
139
140        let parsed: TextFmt = serde_json::from_str(&json).unwrap();
141        assert_eq!(parsed, TextFmt::Json);
142    }
143
144    #[test]
145    fn test_text_fmt_serde_all_variants() {
146        let variants = vec![
147            (TextFmt::Json, "\"json\""),
148            (TextFmt::Csv, "\"csv\""),
149            (TextFmt::Show, "\"show\""),
150            (TextFmt::Kv, "\"kv\""),
151            (TextFmt::Raw, "\"raw\""),
152            (TextFmt::Proto, "\"proto\""),
153            (TextFmt::ProtoText, "\"proto-text\""),
154        ];
155
156        for (fmt, expected_json) in variants {
157            let json = serde_json::to_string(&fmt).unwrap();
158            assert_eq!(json, expected_json);
159
160            let parsed: TextFmt = serde_json::from_str(&json).unwrap();
161            assert_eq!(parsed, fmt);
162        }
163    }
164
165    #[test]
166    fn test_out_fmt_serde() {
167        let out = OutFmt::Fmt(TextFmt::Csv);
168        let json = serde_json::to_string(&out).unwrap();
169        let parsed: OutFmt = serde_json::from_str(&json).unwrap();
170        assert_eq!(parsed, out);
171    }
172
173    // ========== Clone and PartialEq tests ==========
174
175    #[test]
176    fn test_text_fmt_clone() {
177        let fmt = TextFmt::Json;
178        let cloned = fmt;
179        assert_eq!(fmt, cloned);
180    }
181
182    #[test]
183    fn test_out_fmt_clone() {
184        let out = OutFmt::Fmt(TextFmt::Kv);
185        let cloned = out.clone();
186        assert_eq!(out, cloned);
187    }
188}