1#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Default)]
3#[non_exhaustive]
4pub enum DataFormat {
5 Error,
7 Binary,
9 #[default]
10 Text,
11 #[cfg(feature = "json")]
12 Json,
13 #[cfg(feature = "json")]
15 JsonLines,
16 #[cfg(feature = "term-svg")]
19 TermSvg,
20}
21
22impl DataFormat {
23 pub fn ext(self) -> &'static str {
25 match self {
26 Self::Error => "txt",
27 Self::Binary => "bin",
28 Self::Text => "txt",
29 #[cfg(feature = "json")]
30 Self::Json => "json",
31 #[cfg(feature = "json")]
32 Self::JsonLines => "jsonl",
33 #[cfg(feature = "term-svg")]
34 Self::TermSvg => "term.svg",
35 }
36 }
37}
38
39impl From<&std::path::Path> for DataFormat {
40 fn from(path: &std::path::Path) -> Self {
41 let file_name = path
42 .file_name()
43 .and_then(|e| e.to_str())
44 .unwrap_or_default();
45 let mut ext = file_name.strip_prefix('.').unwrap_or(file_name);
46 while let Some((_, new_ext)) = ext.split_once('.') {
47 ext = new_ext;
48 match ext {
49 #[cfg(feature = "json")]
50 "json" => {
51 return DataFormat::Json;
52 }
53 #[cfg(feature = "json")]
54 "jsonl" => {
55 return DataFormat::JsonLines;
56 }
57 #[cfg(feature = "term-svg")]
58 "term.svg" => {
59 return Self::TermSvg;
60 }
61 _ => {}
62 }
63 }
64 DataFormat::Text
65 }
66}
67
68#[cfg(test)]
69mod test {
70 use super::*;
71
72 #[test]
73 fn combos() {
74 #[cfg(feature = "json")]
75 let json = DataFormat::Json;
76 #[cfg(not(feature = "json"))]
77 let json = DataFormat::Text;
78 #[cfg(feature = "json")]
79 let jsonl = DataFormat::JsonLines;
80 #[cfg(not(feature = "json"))]
81 let jsonl = DataFormat::Text;
82 #[cfg(feature = "term-svg")]
83 let term_svg = DataFormat::TermSvg;
84 #[cfg(not(feature = "term-svg"))]
85 let term_svg = DataFormat::Text;
86 let cases = [
87 ("foo", DataFormat::Text),
88 (".foo", DataFormat::Text),
89 ("foo.txt", DataFormat::Text),
90 (".foo.txt", DataFormat::Text),
91 ("foo.stdout.txt", DataFormat::Text),
92 ("foo.json", json),
93 ("foo.stdout.json", json),
94 (".foo.json", json),
95 ("foo.jsonl", jsonl),
96 ("foo.stdout.jsonl", jsonl),
97 (".foo.jsonl", jsonl),
98 ("foo.term.svg", term_svg),
99 ("foo.stdout.term.svg", term_svg),
100 (".foo.term.svg", term_svg),
101 ];
102 for (input, output) in cases {
103 let input = std::path::Path::new(input);
104 assert_eq!(DataFormat::from(input), output, "for `{}`", input.display());
105 }
106 }
107}