use std::collections::BTreeMap;
use crate::error::Error;
use crate::value::Value;
pub(crate) fn origin_of(provider: &(dyn figment::Provider + Send + Sync)) -> crate::Origin {
match provider.metadata().source {
Some(figment::Source::File(path)) => crate::Origin::File(path),
Some(figment::Source::Code(_)) => crate::Origin::Inline,
Some(figment::Source::Custom(what)) => crate::Origin::Remote(what),
Some(_) | None => crate::Origin::Unknown,
}
}
fn into_tree(dict: &figment::value::Dict) -> BTreeMap<String, Value> {
dict.iter()
.map(|(key, value)| (key.clone(), super::from_figment(value)))
.collect()
}
pub(crate) fn section_of(
provider: &(dyn figment::Provider + Send + Sync),
key: &str,
) -> Result<Option<BTreeMap<String, Value>>, Error> {
let data = provider
.data()
.map_err(|error| super::error::translate(&error))?;
let mut found: Option<crate::Value> = None;
for candidate in [
figment::Profile::Default,
figment::Profile::from(key),
figment::Profile::from("global"),
] {
let Some(dict) = data.get(&candidate) else {
continue;
};
let values = crate::Value::Table(into_tree(dict));
match &mut found {
Some(into) => into.merge(values),
None => found = Some(values),
}
}
match found {
Some(crate::Value::Table(table)) => Ok(Some(table)),
_ => Ok(None),
}
}