1use std::fmt;
2use std::path::Path;
3
4use crate::error::X2YError;
5#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
6pub enum Format {
7 Yaml,
8 Json,
9 Toml,
10}
11
12impl TryFrom<&Path> for Format {
13 type Error = X2YError;
14
15 fn try_from(s: &Path) -> Result<Self, Self::Error> {
16 if let Some(extension) = s.extension() {
17 if let Some(format) = extension.to_str() {
18 match format.trim() {
19 "yaml" => Ok(Self::Yaml),
20 "yml" => Ok(Self::Yaml),
21 "json" => Ok(Self::Json),
22 "toml" => Ok(Self::Toml),
23 other => Err(X2YError::InvalidInput(format!(
24 "{} is not a supported file format.",
25 other
26 ))),
27 }
28 } else {
29 Err(X2YError::InvalidInput(format!(
30 "{} contains invalid unicode.",
31 s.display()
32 )))
33 }
34 } else if let Some(s) = s.to_str() {
35 match s.trim() {
36 "yaml" => Ok(Self::Yaml),
37 "yml" => Ok(Self::Yaml),
38 "json" => Ok(Self::Json),
39 "toml" => Ok(Self::Toml),
40 other => Err(X2YError::InvalidInput(format!(
41 "{} is not a supported file format.",
42 other
43 ))),
44 }
45 } else {
46 Err(X2YError::InvalidInput(format!(
47 "{:?} has no retrievable extension.",
48 s
49 )))
50 }
51 }
52}
53
54impl fmt::Display for Format {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 match self {
57 Format::Yaml => write!(f, "yaml"),
58 Format::Json => write!(f, "json"),
59 Format::Toml => write!(f, "toml"),
60 }
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use std::path::PathBuf;
68
69 use claims::*;
70
71 #[test]
72 fn a_format_is_extracted_from_a_path() {
73 let input = PathBuf::from("directory/test.yaml");
74 let path = input.as_path();
75 let format = Format::try_from(path).unwrap();
76 assert_eq!(Format::Yaml, format);
77 }
78
79 #[test]
80 fn a_path_containing_an_unsupported_file_format_is_not_extracted() {
81 let input = PathBuf::from("directory/test.cpp");
82 let path = input.as_path();
83 let format = Format::try_from(path);
84 assert_err!(format);
85 }
86
87 #[test]
88 fn a_path_of_just_a_file_format_is_extracted() {
89 let input = PathBuf::from("yaml");
90 let path = input.as_path();
91 let format = Format::try_from(path).unwrap();
92 assert_eq!(Format::Yaml, format);
93 }
94 #[test]
95 fn a_path_containing_format_names_is_ok() {
96 let input = PathBuf::from("json_yaml.yaml");
97 let path = input.as_path();
98 let format = Format::try_from(path).unwrap();
99 assert_eq!(Format::Yaml, format);
100 }
101}