use super::schema::ArgumentSchema;
use super::value::ArgumentValue;
use std::collections::HashMap;
use unicase::UniCase;
pub type ArgumentKey<'a> = UniCase<&'a str>;
pub type PageArgumentsMap<'a> = HashMap<ArgumentKey<'a>, (ArgumentValue<'a>, &'a str)>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PageArguments<'a>(pub PageArgumentsMap<'a>);
impl<'a> PageArguments<'a> {
pub fn parse(mut path: &'a str, schema: ArgumentSchema) -> Self {
if path.starts_with('/') {
path = &path[1..];
}
let mut arguments = HashMap::new();
let mut parts = path.split('/');
fn process_argument<'a>(
arguments: &mut PageArgumentsMap<'a>,
key: &'a str,
parts: &mut dyn Iterator<Item = &'a str>,
schema: ArgumentSchema,
) {
let value = parts.next();
if schema.solo_keys.contains(&key) {
if let Some(value) = value {
if schema.valid_keys.contains(&value) {
let key = ArgumentKey::unicode(key);
arguments.insert(key, (ArgumentValue::Null, value));
process_argument(arguments, value, parts, schema);
return;
}
}
}
let key = ArgumentKey::unicode(key);
arguments.insert(key, (ArgumentValue::from(value), value.unwrap_or("")));
}
while let Some(key) = parts.next() {
if !key.is_empty() {
process_argument(&mut arguments, key, &mut parts, schema);
}
}
PageArguments(arguments)
}
}