sqry_core/schema/
format.rs1use serde::{Deserialize, Serialize};
6use std::fmt;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
29#[serde(rename_all = "lowercase")]
30#[derive(Default)]
31pub enum OutputFormat {
32 #[default]
37 Json,
38
39 Dot,
44
45 D2,
50
51 Mermaid,
56
57 Archify,
67}
68
69impl OutputFormat {
70 #[must_use]
72 pub const fn all() -> &'static [Self] {
73 &[
74 Self::Json,
75 Self::Dot,
76 Self::D2,
77 Self::Mermaid,
78 Self::Archify,
79 ]
80 }
81
82 #[must_use]
84 pub const fn as_str(self) -> &'static str {
85 match self {
86 Self::Json => "json",
87 Self::Dot => "dot",
88 Self::D2 => "d2",
89 Self::Mermaid => "mermaid",
90 Self::Archify => "archify",
91 }
92 }
93
94 #[must_use]
100 pub const fn file_extension(self) -> &'static str {
101 match self {
102 Self::Json => "json",
103 Self::Dot => "dot",
104 Self::D2 => "d2",
105 Self::Mermaid => "mmd",
106 Self::Archify => "archify.json",
107 }
108 }
109
110 #[must_use]
115 pub fn parse(s: &str) -> Option<Self> {
116 match s.to_lowercase().as_str() {
117 "json" => Some(Self::Json),
118 "dot" | "graphviz" => Some(Self::Dot),
119 "d2" => Some(Self::D2),
120 "mermaid" | "mmd" => Some(Self::Mermaid),
121 "archify" => Some(Self::Archify),
122 _ => None,
123 }
124 }
125
126 #[must_use]
131 pub const fn is_text_format(self) -> bool {
132 true
133 }
134
135 #[must_use]
137 pub const fn is_diagram_format(self) -> bool {
138 matches!(self, Self::Dot | Self::D2 | Self::Mermaid | Self::Archify)
139 }
140}
141
142impl fmt::Display for OutputFormat {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.write_str(self.as_str())
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151
152 #[test]
153 fn test_as_str() {
154 assert_eq!(OutputFormat::Json.as_str(), "json");
155 assert_eq!(OutputFormat::Dot.as_str(), "dot");
156 assert_eq!(OutputFormat::D2.as_str(), "d2");
157 assert_eq!(OutputFormat::Mermaid.as_str(), "mermaid");
158 assert_eq!(OutputFormat::Archify.as_str(), "archify");
159 }
160
161 #[test]
162 fn test_file_extension() {
163 assert_eq!(OutputFormat::Json.file_extension(), "json");
164 assert_eq!(OutputFormat::Dot.file_extension(), "dot");
165 assert_eq!(OutputFormat::D2.file_extension(), "d2");
166 assert_eq!(OutputFormat::Mermaid.file_extension(), "mmd");
167 assert_eq!(OutputFormat::Archify.file_extension(), "archify.json");
168 }
169
170 #[test]
171 fn test_parse() {
172 assert_eq!(OutputFormat::parse("json"), Some(OutputFormat::Json));
173 assert_eq!(OutputFormat::parse("DOT"), Some(OutputFormat::Dot));
174 assert_eq!(OutputFormat::parse("graphviz"), Some(OutputFormat::Dot));
175 assert_eq!(OutputFormat::parse("mermaid"), Some(OutputFormat::Mermaid));
176 assert_eq!(OutputFormat::parse("mmd"), Some(OutputFormat::Mermaid));
177 assert_eq!(OutputFormat::parse("archify"), Some(OutputFormat::Archify));
178 assert_eq!(OutputFormat::parse("ARCHIFY"), Some(OutputFormat::Archify));
179 assert_eq!(OutputFormat::parse("unknown"), None);
180 }
181
182 #[test]
183 fn test_display() {
184 assert_eq!(format!("{}", OutputFormat::Json), "json");
185 assert_eq!(format!("{}", OutputFormat::Mermaid), "mermaid");
186 }
187
188 #[test]
189 fn test_serde_roundtrip() {
190 for fmt in OutputFormat::all() {
191 let json = serde_json::to_string(fmt).unwrap();
192 let deserialized: OutputFormat = serde_json::from_str(&json).unwrap();
193 assert_eq!(*fmt, deserialized);
194 }
195 }
196
197 #[test]
198 fn test_classification() {
199 assert!(OutputFormat::Json.is_text_format());
200 assert!(!OutputFormat::Json.is_diagram_format());
201 assert!(OutputFormat::Dot.is_diagram_format());
202 assert!(OutputFormat::Mermaid.is_diagram_format());
203 assert!(OutputFormat::Archify.is_diagram_format());
204 }
205
206 #[test]
207 fn test_default() {
208 assert_eq!(OutputFormat::default(), OutputFormat::Json);
209 }
210}