use crate::error::{Error, ErrorKind};
use crate::reader::Reader;
use crate::source::Format;
use crate::value::Value;
#[derive(Debug)]
pub(crate) struct Figment;
impl Reader for Figment {
fn name(&self) -> &str {
"figment"
}
fn reads(&self, format: Format) -> bool {
match format {
Format::Json => cfg!(feature = "json"),
Format::Toml => cfg!(feature = "toml"),
Format::Yaml => cfg!(feature = "yaml"),
Format::Ini | Format::Properties | Format::Ron | Format::Json5 => false,
}
}
#[allow(unused_variables)]
fn parse(&self, text: &str, format: Format) -> Result<Value, Error> {
#[allow(unused_imports)]
use figment::{providers::Format as _, Provider as _};
let provider: Option<Box<dyn figment::Provider>> = match format {
#[cfg(feature = "json")]
Format::Json => Some(Box::new(figment::providers::Json::string(text))),
#[cfg(feature = "toml")]
Format::Toml => Some(Box::new(figment::providers::Toml::string(text))),
#[cfg(feature = "yaml")]
Format::Yaml => Some(Box::new(figment::providers::Yaml::string(text))),
_ => None,
};
let Some(provider) = provider else {
return Err(crate::reader::unread(format));
};
let data = provider.data().map_err(|error| refused(&error))?;
let dict = data.into_values().next().unwrap_or_default();
let parsed = Value::Table(
dict.iter()
.map(|(key, value)| (key.clone(), super::from_figment(value)))
.collect(),
);
#[cfg(feature = "toml")]
let parsed = if format == Format::Toml {
crate::document::dates(parsed)
} else {
parsed
};
Ok(parsed)
}
}
fn refused(error: &figment::Error) -> Error {
let rendered = error.to_string();
let first = rendered.lines().next().unwrap_or_default();
Error::new(ErrorKind::Parse, crate::loader::redacted(first))
}