use std::rc::Rc;
use crate::{option, arg};
use std::collections::HashMap;
type ParserResultConsumer = Box<dyn Fn(&Vec<arg::Value>, &HashMap<&str, option::Value>)>;
pub struct Group {
options: Option<HashMap<Rc<String>, Rc<option::Descriptor>>>,
arguments: Vec<arg::Descriptor>,
children: HashMap<Rc<String>, Rc<Group>>,
children_lookup: HashMap<Rc<String>, Rc<Group>>,
alias_lookup: HashMap<Rc<String>, Vec<Rc<String>>>,
consumer: ParserResultConsumer,
description: String,
}
impl Group {
pub fn new(consumer: ParserResultConsumer, description: &str) -> Self {
Group {
options: Some(HashMap::new()),
arguments: Vec::new(),
children: HashMap::new(),
children_lookup: HashMap::new(),
alias_lookup: HashMap::new(),
consumer,
description: String::from(description),
}
}
pub fn add_argument(mut self, argument: arg::Descriptor) -> Self {
self.arguments.push(argument);
self
}
pub fn get_arguments(&self) -> &Vec<arg::Descriptor> {
&self.arguments
}
pub fn add_option(mut self, option: option::Descriptor) -> Self {
assert!(!&self.options.as_ref().unwrap().contains_key(option.name()));
self.options.as_mut().unwrap().insert(option.take_name(), Rc::new(option));
self
}
pub fn get_options(&self) -> &HashMap<Rc<String>, Rc<option::Descriptor>> {
self.options.as_ref().unwrap()
}
pub fn add_child(mut self, name: &str, aliases: Option<Vec<&str>>, group: Group) -> Self {
let name = Rc::new(String::from(name));
let group = Rc::new(group);
assert!(!self.children.contains_key(&name));
self.children.insert(Rc::clone(&name), Rc::clone(&group));
assert!(!self.children_lookup.contains_key(&name));
self.children_lookup.insert(Rc::clone(&name), Rc::clone(&group));
if aliases.is_some() {
let aliases = aliases.unwrap();
let mut alias_vec = Vec::with_capacity(aliases.len());
for alias in aliases {
let alias = Rc::new(String::from(alias));
alias_vec.push(Rc::clone(&alias));
assert!(!self.children_lookup.contains_key(&alias));
self.children_lookup.insert(Rc::clone(&alias), Rc::clone(&group));
}
self.alias_lookup.insert(Rc::clone(&name), alias_vec);
}
self
}
pub fn get_aliases_for_group_name(&self, group_name: &String) -> Option<&Vec<Rc<String>>> {
self.alias_lookup.get(group_name)
}
pub fn get_children(&self) -> &HashMap<Rc<String>, Rc<Group>> {
&self.children
}
pub fn get_child_known_for(&self, alias: &str) -> Option<Rc<Group>> {
match self.children_lookup.get(&String::from(alias)) {
Some(v) => Some(Rc::clone(v)),
None => None
}
}
pub fn get_consumer(&self) -> &ParserResultConsumer {
&self.consumer
}
pub fn description(&self) -> &String {
&self.description
}
}