config/file/format/
mod.rs

1use std::error::Error;
2
3use crate::map::Map;
4use crate::{file::FileStoredFormat, value::Value, Format};
5
6#[cfg(feature = "toml")]
7mod toml;
8
9#[cfg(feature = "json")]
10mod json;
11
12#[cfg(feature = "yaml")]
13mod yaml;
14
15#[cfg(feature = "ini")]
16mod ini;
17
18#[cfg(feature = "ron")]
19mod ron;
20
21#[cfg(feature = "json5")]
22mod json5;
23
24#[cfg(feature = "corn")]
25mod corn;
26
27/// File formats provided by the library.
28///
29/// Although it is possible to define custom formats using [`Format`] trait it is recommended to use `FileFormat` if possible.
30#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
31#[non_exhaustive]
32pub enum FileFormat {
33    /// TOML (parsed with toml)
34    #[cfg(feature = "toml")]
35    Toml,
36
37    /// JSON (parsed with `serde_json`)
38    #[cfg(feature = "json")]
39    Json,
40
41    /// YAML (parsed with `yaml_rust2`)
42    #[cfg(feature = "yaml")]
43    Yaml,
44
45    /// INI (parsed with `rust_ini`)
46    #[cfg(feature = "ini")]
47    Ini,
48
49    /// RON (parsed with ron)
50    #[cfg(feature = "ron")]
51    Ron,
52
53    /// JSON5 (parsed with json5)
54    #[cfg(feature = "json5")]
55    Json5,
56
57    /// Corn (parsed with `libcorn`)
58    #[cfg(feature = "corn")]
59    Corn,
60}
61
62impl FileFormat {
63    pub(crate) fn all() -> &'static [FileFormat] {
64        &[
65            #[cfg(feature = "toml")]
66            FileFormat::Toml,
67            #[cfg(feature = "json")]
68            FileFormat::Json,
69            #[cfg(feature = "yaml")]
70            FileFormat::Yaml,
71            #[cfg(feature = "ini")]
72            FileFormat::Ini,
73            #[cfg(feature = "ron")]
74            FileFormat::Ron,
75            #[cfg(feature = "json5")]
76            FileFormat::Json5,
77            #[cfg(feature = "corn")]
78            FileFormat::Corn,
79        ]
80    }
81
82    pub(crate) fn extensions(&self) -> &'static [&'static str] {
83        match self {
84            #[cfg(feature = "toml")]
85            FileFormat::Toml => &["toml"],
86
87            #[cfg(feature = "json")]
88            FileFormat::Json => &["json"],
89
90            #[cfg(feature = "yaml")]
91            FileFormat::Yaml => &["yaml", "yml"],
92
93            #[cfg(feature = "ini")]
94            FileFormat::Ini => &["ini"],
95
96            #[cfg(feature = "ron")]
97            FileFormat::Ron => &["ron"],
98
99            #[cfg(feature = "json5")]
100            FileFormat::Json5 => &["json5"],
101
102            #[cfg(feature = "corn")]
103            FileFormat::Corn => &["corn"],
104
105            #[cfg(all(
106                not(feature = "toml"),
107                not(feature = "json"),
108                not(feature = "yaml"),
109                not(feature = "ini"),
110                not(feature = "ron"),
111                not(feature = "json5"),
112            ))]
113            _ => unreachable!("No features are enabled, this library won't work without features"),
114        }
115    }
116
117    pub(crate) fn parse(
118        &self,
119        uri: Option<&String>,
120        text: &str,
121    ) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
122        match self {
123            #[cfg(feature = "toml")]
124            FileFormat::Toml => toml::parse(uri, text),
125
126            #[cfg(feature = "json")]
127            FileFormat::Json => json::parse(uri, text),
128
129            #[cfg(feature = "yaml")]
130            FileFormat::Yaml => yaml::parse(uri, text),
131
132            #[cfg(feature = "ini")]
133            FileFormat::Ini => ini::parse(uri, text),
134
135            #[cfg(feature = "ron")]
136            FileFormat::Ron => ron::parse(uri, text),
137
138            #[cfg(feature = "json5")]
139            FileFormat::Json5 => json5::parse(uri, text),
140
141            #[cfg(feature = "corn")]
142            FileFormat::Corn => corn::parse(uri, text),
143
144            #[cfg(all(
145                not(feature = "toml"),
146                not(feature = "json"),
147                not(feature = "yaml"),
148                not(feature = "ini"),
149                not(feature = "ron"),
150                not(feature = "json5"),
151            ))]
152            _ => unreachable!("No features are enabled, this library won't work without features"),
153        }
154    }
155}
156
157impl Format for FileFormat {
158    fn parse(
159        &self,
160        uri: Option<&String>,
161        text: &str,
162    ) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
163        self.parse(uri, text)
164    }
165}
166
167impl FileStoredFormat for FileFormat {
168    fn file_extensions(&self) -> &'static [&'static str] {
169        self.extensions()
170    }
171}