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}