use crate::parsing::{ParseError, ParseErrorKind, Parser, parse_boolean};
use crate::settings::WikitextSettings;
use crate::tree::AttributeMap;
use std::borrow::Cow;
use std::collections::HashMap;
use std::str::FromStr;
use unicase::UniCase;
macro_rules! make_err {
($parser:expr) => {
$parser.make_err(ParseErrorKind::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>, ParseError> {
match self.get(key) {
Some(argument) => match parse_boolean(argument) {
Ok(value) => Ok(Some(value)),
Err(_) => Err(make_err!(parser)),
},
None => Ok(None),
}
}
pub fn get_value<T: FromStr>(
&mut self,
parser: &Parser<'_, 't>,
key: &'t str,
) -> Result<Option<T>, ParseError> {
match self.get(key) {
Some(argument) => match argument.parse() {
Ok(value) => Ok(Some(value)),
Err(_) => Err(make_err!(parser)),
},
None => Ok(None),
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn to_hash_map(&self) -> HashMap<Cow<'t, str>, Cow<'t, str>> {
self.inner
.iter()
.map(|(key, value)| {
let key = cow!(key.into_inner());
let value = value.clone();
(key, value)
})
.collect()
}
#[inline]
pub fn to_attribute_map(&self, settings: &WikitextSettings) -> AttributeMap<'t> {
let mut map = AttributeMap::from_arguments(&self.inner);
map.isolate_id(settings);
map
}
}