use std::{borrow::Cow, collections::HashMap};
#[allow(clippy::type_complexity)]
#[must_use]
pub struct Parser<'a, Config: 'a> {
config: Config,
arguments: HashMap<Cow<'a, str>, Box<dyn Fn(&mut Config) + 'a>>,
unknown: Box<dyn Fn(&mut Config, &'a str) + 'a>,
}
impl<'a, Config: 'a> Parser<'a, Config> {
pub fn new(config: Config, unknown: impl Fn(&mut Config, &'a str) + 'a) -> Self {
Self {
config,
arguments: HashMap::new(),
unknown: Box::new(unknown),
}
}
#[allow(clippy::type_complexity)]
pub fn with_arguments(
config: Config,
arguments: HashMap<Cow<'a, str>, Box<dyn Fn(&mut Config) + 'a>>,
unknown: impl Fn(&mut Config, &'a str) + 'a,
) -> Self {
Self {
config,
arguments,
unknown: Box::new(unknown),
}
}
pub fn arg(
mut self,
argument: impl Into<Cow<'a, str>>,
callback: impl Fn(&mut Config) + 'a,
) -> Self {
self.arguments.insert(argument.into(), Box::new(callback));
self
}
pub fn parse(mut self, input: impl IntoIterator<Item = &'a str>) -> Config {
for arg in input {
if let Some(callback) = self.arguments.get(arg) {
callback(&mut self.config);
} else {
(self.unknown)(&mut self.config, arg);
};
}
self.config
}
}
impl<'a, Config: Default> Default for Parser<'a, Config> {
fn default() -> Self {
Self::new(Config::default(), |_, _| {})
}
}