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
58impl OutputFormat {
59 #[must_use]
61 pub const fn all() -> &'static [Self] {
62 &[Self::Json, Self::Dot, Self::D2, Self::Mermaid]
63 }
64
65 #[must_use]
67 pub const fn as_str(self) -> &'static str {
68 match self {
69 Self::Json => "json",
70 Self::Dot => "dot",
71 Self::D2 => "d2",
72 Self::Mermaid => "mermaid",
73 }
74 }
75
76 #[must_use]
78 pub const fn file_extension(self) -> &'static str {
79 match self {
80 Self::Json => "json",
81 Self::Dot => "dot",
82 Self::D2 => "d2",
83 Self::Mermaid => "mmd",
84 }
85 }
86
87 #[must_use]
92 pub fn parse(s: &str) -> Option<Self> {
93 match s.to_lowercase().as_str() {
94 "json" => Some(Self::Json),
95 "dot" | "graphviz" => Some(Self::Dot),
96 "d2" => Some(Self::D2),
97 "mermaid" | "mmd" => Some(Self::Mermaid),
98 _ => None,
99 }
100 }
101
102 #[must_use]
107 pub const fn is_text_format(self) -> bool {
108 true
109 }
110
111 #[must_use]
113 pub const fn is_diagram_format(self) -> bool {
114 matches!(self, Self::Dot | Self::D2 | Self::Mermaid)
115 }
116}
117
118impl fmt::Display for OutputFormat {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 f.write_str(self.as_str())
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_as_str() {
130 assert_eq!(OutputFormat::Json.as_str(), "json");
131 assert_eq!(OutputFormat::Dot.as_str(), "dot");
132 assert_eq!(OutputFormat::D2.as_str(), "d2");
133 assert_eq!(OutputFormat::Mermaid.as_str(), "mermaid");
134 }
135
136 #[test]
137 fn test_file_extension() {
138 assert_eq!(OutputFormat::Json.file_extension(), "json");
139 assert_eq!(OutputFormat::Dot.file_extension(), "dot");
140 assert_eq!(OutputFormat::D2.file_extension(), "d2");
141 assert_eq!(OutputFormat::Mermaid.file_extension(), "mmd");
142 }
143
144 #[test]
145 fn test_parse() {
146 assert_eq!(OutputFormat::parse("json"), Some(OutputFormat::Json));
147 assert_eq!(OutputFormat::parse("DOT"), Some(OutputFormat::Dot));
148 assert_eq!(OutputFormat::parse("graphviz"), Some(OutputFormat::Dot));
149 assert_eq!(OutputFormat::parse("mermaid"), Some(OutputFormat::Mermaid));
150 assert_eq!(OutputFormat::parse("mmd"), Some(OutputFormat::Mermaid));
151 assert_eq!(OutputFormat::parse("unknown"), None);
152 }
153
154 #[test]
155 fn test_display() {
156 assert_eq!(format!("{}", OutputFormat::Json), "json");
157 assert_eq!(format!("{}", OutputFormat::Mermaid), "mermaid");
158 }
159
160 #[test]
161 fn test_serde_roundtrip() {
162 for fmt in OutputFormat::all() {
163 let json = serde_json::to_string(fmt).unwrap();
164 let deserialized: OutputFormat = serde_json::from_str(&json).unwrap();
165 assert_eq!(*fmt, deserialized);
166 }
167 }
168
169 #[test]
170 fn test_classification() {
171 assert!(OutputFormat::Json.is_text_format());
172 assert!(!OutputFormat::Json.is_diagram_format());
173 assert!(OutputFormat::Dot.is_diagram_format());
174 assert!(OutputFormat::Mermaid.is_diagram_format());
175 }
176
177 #[test]
178 fn test_default() {
179 assert_eq!(OutputFormat::default(), OutputFormat::Json);
180 }
181}