use crate::parsing::{parse_boolean, ParseWarning, ParseWarningKind, Parser};
use crate::tree::AttributeMap;
use std::borrow::Cow;
use std::collections::HashMap;
use std::str::FromStr;
use unicase::UniCase;
macro_rules! make_warn {
($parser:expr) => {
$parser.make_warn(ParseWarningKind::BlockMalformedArguments)
};
}
#[derive(Debug, Clone, Default)]
pub struct Arguments<'t> {
inner: HashMap<UniCase<&'t str>, Cow<'t, str>>,
}
impl<'t> Arguments<'t> {
#[inline]
pub fn new() -> Self {
Arguments::default()
}
pub fn insert(&mut self, key: &'t str, value: Cow<'t, str>) {
let key = UniCase::ascii(key);
self.inner.insert(key, value);
}
pub fn get(&mut self, key: &'t str) -> Option<Cow<'t, str>> {
let key = UniCase::ascii(key);
self.inner.remove(&key)
}
pub fn get_bool(
&mut self,
parser: &Parser<'_, 't>,
key: &'t str,
) -> Result<Option<bool>, ParseWarning> {
match self.get(key) {
Some(argument) => match parse_boolean(argument) {
Ok(value) => Ok(Some(value)),
Err(_) => Err(make_warn!(parser)),
},
None => Ok(None),
}
}
pub fn get_value<T: FromStr>(
&mut self,
parser: &Parser<'_, 't>,
key: &'t str,
) -> Result<Option<T>, ParseWarning> {
match self.get(key) {
Some(argument) => match argument.parse() {
Ok(value) => Ok(Some(value)),
Err(_) => Err(make_warn!(parser)),
},
None => Ok(None),
}
}
pub fn to_hash_map(&self) -> AttributeMap<'t> {
self.inner
.iter()
.map(|(key, value)| (cow!(key.into_inner()), Cow::clone(value)))
.collect()
}
}