blob: 025e98a9aec4f3d54c5267fa8068ea42d4cdd295 [file] [log] [blame]
// If no features are used, there is an "unused mut" warning in `ALL_EXTENSIONS`
// BUG: ? For some reason this doesn't do anything if I try and function scope this
#![allow(unused_mut)]
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::error::Error;
use crate::map::Map;
use crate::{file::FileStoredFormat, value::Value, Format};
#[cfg(feature = "toml")]
mod toml;
#[cfg(feature = "json")]
mod json;
#[cfg(feature = "yaml")]
mod yaml;
#[cfg(feature = "ini")]
mod ini;
#[cfg(feature = "ron")]
mod ron;
#[cfg(feature = "json5")]
mod json5;
/// File formats provided by the library.
///
/// Although it is possible to define custom formats using [`Format`] trait it is recommended to use FileFormat if possible.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FileFormat {
/// TOML (parsed with toml)
#[cfg(feature = "toml")]
Toml,
/// JSON (parsed with serde_json)
#[cfg(feature = "json")]
Json,
/// YAML (parsed with yaml_rust)
#[cfg(feature = "yaml")]
Yaml,
/// INI (parsed with rust_ini)
#[cfg(feature = "ini")]
Ini,
/// RON (parsed with ron)
#[cfg(feature = "ron")]
Ron,
/// JSON5 (parsed with json5)
#[cfg(feature = "json5")]
Json5,
}
lazy_static! {
#[doc(hidden)]
// #[allow(unused_mut)] ?
pub static ref ALL_EXTENSIONS: HashMap<FileFormat, Vec<&'static str>> = {
let mut formats: HashMap<FileFormat, Vec<_>> = HashMap::new();
#[cfg(feature = "toml")]
formats.insert(FileFormat::Toml, vec!["toml"]);
#[cfg(feature = "json")]
formats.insert(FileFormat::Json, vec!["json"]);
#[cfg(feature = "yaml")]
formats.insert(FileFormat::Yaml, vec!["yaml", "yml"]);
#[cfg(feature = "ini")]
formats.insert(FileFormat::Ini, vec!["ini"]);
#[cfg(feature = "ron")]
formats.insert(FileFormat::Ron, vec!["ron"]);
#[cfg(feature = "json5")]
formats.insert(FileFormat::Json5, vec!["json5"]);
formats
};
}
impl FileFormat {
pub(crate) fn extensions(&self) -> &'static [&'static str] {
// It should not be possible for this to fail
// A FileFormat would need to be declared without being added to the
// ALL_EXTENSIONS map.
ALL_EXTENSIONS.get(self).unwrap()
}
pub(crate) fn parse(
&self,
uri: Option<&String>,
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
match self {
#[cfg(feature = "toml")]
FileFormat::Toml => toml::parse(uri, text),
#[cfg(feature = "json")]
FileFormat::Json => json::parse(uri, text),
#[cfg(feature = "yaml")]
FileFormat::Yaml => yaml::parse(uri, text),
#[cfg(feature = "ini")]
FileFormat::Ini => ini::parse(uri, text),
#[cfg(feature = "ron")]
FileFormat::Ron => ron::parse(uri, text),
#[cfg(feature = "json5")]
FileFormat::Json5 => json5::parse(uri, text),
#[cfg(all(
not(feature = "toml"),
not(feature = "json"),
not(feature = "yaml"),
not(feature = "ini"),
not(feature = "ron"),
not(feature = "json5"),
))]
_ => unreachable!("No features are enabled, this library won't work without features"),
}
}
}
impl Format for FileFormat {
fn parse(
&self,
uri: Option<&String>,
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
self.parse(uri, text)
}
}
impl FileStoredFormat for FileFormat {
fn file_extensions(&self) -> &'static [&'static str] {
self.extensions()
}
}