use crate::error::HierConfError;
use facet::Facet;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AttrKey {
AppName,
#[cfg(feature = "mangen")]
Synopsis,
#[cfg(feature = "mangen")]
Date,
}
#[cfg(not(feature = "mangen"))]
facet::define_attr_grammar! {
ns "hierconf";
crate_path ::hierconf_core::attrs;
pub enum Attr {
AppName(&'static str),
}
}
#[cfg(feature = "mangen")]
facet::define_attr_grammar! {
ns "hierconf";
crate_path ::hierconf_core::attrs;
pub enum Attr {
AppName(&'static str),
Synopsis(&'static str),
Date(&'static str),
}
}
impl AttrKey {
fn key_str(&self) -> &'static str {
match self {
AttrKey::AppName => "app_name",
#[cfg(feature = "mangen")]
AttrKey::Synopsis => "synopsis",
#[cfg(feature = "mangen")]
AttrKey::Date => "date",
}
}
fn attr_name(&self) -> &'static str {
match self {
AttrKey::AppName => "hierconf::app_name",
#[cfg(feature = "mangen")]
AttrKey::Synopsis => "hierconf::synopsis",
#[cfg(feature = "mangen")]
AttrKey::Date => "hierconf::date",
}
}
}
pub fn extract_attr<T>(key: AttrKey) -> Result<String, HierConfError>
where
T: Facet<'static>,
{
let key_str = key.key_str();
let attr_name = key.attr_name();
for attr in T::SHAPE.attributes {
if attr.ns == Some("hierconf") && attr.key == key_str {
if let Some(value) = attr.get_as::<&'static str>() {
return Ok((*value).to_string());
}
return Err(HierConfError::AttributeShapeMismatch {
shape: attr.data.shape(),
namespace: attr.ns,
key: attr.key,
attr: attr_name,
});
}
}
Err(HierConfError::MissingAttribute(format!(
"{} must be specified via #[facet({}(\"...\"))] attribute on the struct",
key_str, attr_name
)))
}
pub fn extract_optional_attr<T>(key: AttrKey) -> Result<Option<String>, HierConfError>
where
T: Facet<'static>,
{
match extract_attr::<T>(key) {
Ok(value) => Ok(Some(value)),
Err(HierConfError::MissingAttribute(_)) => Ok(None),
Err(e) => Err(e),
}
}