1use std::rc::Rc;
2use crate::{option, arg};
3use std::collections::HashMap;
4
5type ParserResultConsumer = Box<dyn Fn(&Vec<arg::Value>, &HashMap<&str, option::Value>)>;
7
8pub struct Group {
18    options: Option<HashMap<Rc<String>, Rc<option::Descriptor>>>,
20
21    arguments: Vec<arg::Descriptor>,
23
24    children: HashMap<Rc<String>, Rc<Group>>,
26
27    children_lookup: HashMap<Rc<String>, Rc<Group>>,
29
30    alias_lookup: HashMap<Rc<String>, Vec<Rc<String>>>,
32
33    consumer: ParserResultConsumer,
35
36    description: String,
38}
39
40impl Group {
41    pub fn new(consumer: ParserResultConsumer, description: &str) -> Self {
43        Group {
44            options: Some(HashMap::new()),
45            arguments: Vec::new(),
46            children: HashMap::new(),
47            children_lookup: HashMap::new(),
48            alias_lookup: HashMap::new(),
49            consumer,
50            description: String::from(description),
51        }
52    }
53
54    pub fn add_argument(mut self, argument: arg::Descriptor) -> Self {
56        self.arguments.push(argument);
57
58        self
59    }
60
61    pub fn get_arguments(&self) -> &Vec<arg::Descriptor> {
63        &self.arguments
64    }
65
66    pub fn add_option(mut self, option: option::Descriptor) -> Self {
68        assert!(!&self.options.as_ref().unwrap().contains_key(option.name()));
69
70        self.options.as_mut().unwrap().insert(option.take_name(), Rc::new(option));
71
72        self
73    }
74
75    pub fn get_options(&self) -> &HashMap<Rc<String>, Rc<option::Descriptor>> {
77        self.options.as_ref().unwrap()
78    }
79
80    pub fn add_child(mut self, name: &str, aliases: Option<Vec<&str>>, group: Group) -> Self {
82        let name = Rc::new(String::from(name));
83        let group = Rc::new(group);
84
85        assert!(!self.children.contains_key(&name));
86        self.children.insert(Rc::clone(&name), Rc::clone(&group));
87
88        assert!(!self.children_lookup.contains_key(&name));
90        self.children_lookup.insert(Rc::clone(&name), Rc::clone(&group));
91
92        if aliases.is_some() {
93            let aliases = aliases.unwrap();
94            let mut alias_vec = Vec::with_capacity(aliases.len());
95            for alias in aliases {
96                let alias = Rc::new(String::from(alias));
97                alias_vec.push(Rc::clone(&alias));
98
99                assert!(!self.children_lookup.contains_key(&alias));
100                self.children_lookup.insert(Rc::clone(&alias), Rc::clone(&group));
101            }
102
103            self.alias_lookup.insert(Rc::clone(&name), alias_vec);
104        }
105
106        self
107    }
108
109    pub fn get_aliases_for_group_name(&self, group_name: &String) -> Option<&Vec<Rc<String>>> {
111        self.alias_lookup.get(group_name)
112    }
113
114    pub fn get_children(&self) -> &HashMap<Rc<String>, Rc<Group>> {
116        &self.children
117    }
118
119    pub fn get_child_known_for(&self, alias: &str) -> Option<Rc<Group>> {
121        match self.children_lookup.get(&String::from(alias)) {
122            Some(v) => Some(Rc::clone(v)),
123            None => None
124        }
125    }
126
127    pub fn get_consumer(&self) -> &ParserResultConsumer {
129        &self.consumer
130    }
131
132    pub fn description(&self) -> &String {
134        &self.description
135    }
136}