teo_parser/ast/
namespace.rs1use std::collections::{BTreeSet};
2use std::fmt::{Debug};
3use std::sync::Arc;
4use maplit::btreeset;
5use crate::ast::handler::HandlerGroupDeclaration;
6use crate::availability::Availability;
7use crate::ast::config::Config;
8use crate::ast::data_set::DataSet;
9use crate::ast::model::Model;
10use crate::ast::r#enum::Enum;
11use crate::ast::identifier::Identifier;
12use crate::ast::doc_comment::DocComment;
13use crate::{declare_container_node, impl_container_node_defaults, node_child_fn, node_optional_child_fn};
14use crate::ast::decorator::Decorator;
15use crate::ast::empty_decorator::EmptyDecorator;
16use crate::ast::node::Node;
17use crate::format::Writer;
18use crate::traits::node_trait::NodeTrait;
19use crate::traits::write::Write;
20
21declare_container_node!(Namespace, named,
22 pub(crate) comment: Option<usize>,
23 pub(crate) identifier: usize,
24 pub(crate) references: NamespaceReferences,
25);
26
27impl_container_node_defaults!(Namespace, named);
28
29impl Namespace {
30
31 node_child_fn!(identifier, Identifier);
32
33 node_optional_child_fn!(comment, DocComment);
34
35 pub fn parent_str_path(&self) -> Vec<&str> {
36 self.string_path.iter().rev().skip(1).rev().map(AsRef::as_ref).collect()
37 }
38
39 pub fn get_connector(&self) -> Option<&Config> {
40 self.references.connector.map(|id| self.children.get(&id).unwrap().as_config().unwrap())
41 }
42
43 fn get_enum(&self, id: usize) -> Option<&Enum> {
44 self.children.get(&id).unwrap().as_enum()
45 }
46
47 fn get_model(&self, id: usize) -> Option<&Model> {
48 self.children.get(&id).unwrap().as_model()
49 }
50
51 pub fn get_namespace(&self, id: usize) -> Option<&Namespace> {
52 self.children.get(&id).unwrap().as_namespace()
53 }
54
55 fn get_data_set(&self, id: usize) -> Option<&DataSet> {
56 self.children.get(&id).unwrap().as_data_set()
57 }
58
59 fn get_handler_group(&self, id: usize) -> Option<&HandlerGroupDeclaration> {
60 self.children.get(&id).unwrap().as_handler_group_declaration()
61 }
62
63 pub fn models(&self) -> Vec<&Model> {
64 self.references.models.iter().map(|m| self.get_model(*m).unwrap()).collect()
65 }
66
67 pub fn enums(&self) -> Vec<&Enum> {
68 self.references.enums.iter().map(|m| self.get_enum(*m).unwrap()).collect()
69 }
70
71 pub fn handler_groups(&self) -> Vec<&HandlerGroupDeclaration> {
72 self.references.namespaces.iter().map(|m| self.get_handler_group(*m).unwrap()).collect()
73 }
74
75 pub fn namespaces(&self) -> Vec<&Namespace> {
76 self.references.namespaces.iter().map(|m| self.get_namespace(*m).unwrap()).collect()
77 }
78
79 pub fn data_sets(&self) -> Vec<&DataSet> {
80 self.references.data_sets.iter().map(|m| self.get_data_set(*m).unwrap()).collect()
81 }
82
83 pub fn empty_decorators(&self) -> Vec<&EmptyDecorator> {
84 self.references.empty_decorators.iter().map(|m| self.children.get(m).unwrap().as_empty_decorator().unwrap()).collect()
85 }
86
87 pub fn unattached_decorators(&self) -> Vec<&Decorator> {
88 self.references.unattached_decorators.iter().map(|m| self.children.get(m).unwrap().as_decorator().unwrap()).collect()
89 }
90
91 pub fn find_top_by_name(&self, name: &str, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
92 self.children.values().find(|t| {
93 if let Some(n) = t.name() {
94 (n == name) && filter(*t) && t.available_test(availability)
95 } else {
96 false
97 }
98 }).map(|t| t)
99 }
100
101 pub fn find_top_by_id(&self, id: usize) -> Option<&Node> {
102 self.children.get(&id)
103 }
104
105 pub fn find_node_by_string_path(&self, path: &Vec<&str>, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
106 if path.len() == 0 {
107 return None;
108 } else if path.len() == 1 {
109 self.find_top_by_name(path.get(0).unwrap(), filter, availability)
110 } else {
111 let mut path_for_ns = path.clone();
112 path_for_ns.remove(path_for_ns.len() - 1);
113 let child_ns = self.find_child_namespace_by_string_path(&path_for_ns);
114 return if let Some(child_ns) = child_ns {
115 child_ns.find_top_by_name(path.last().unwrap(), filter, availability)
116 } else {
117 None
118 }
119 }
120 }
121
122 pub fn find_child_namespace_by_string_path(&self, path: &Vec<&str>) -> Option<&Namespace> {
123 let mut retval = self;
124 for name in path {
125 if let Some(child) = retval.namespaces().iter().find(|n| n.identifier().name() == *name) {
126 retval = child
127 } else {
128 return None
129 }
130 }
131 Some(retval)
132 }
133}
134
135#[derive(Debug)]
136pub struct NamespaceReferences {
137 pub constants: BTreeSet<usize>,
138 pub connector: Option<usize>,
139 pub configs: BTreeSet<usize>,
140 pub enums: BTreeSet<usize>,
141 pub models: BTreeSet<usize>,
142 pub data_sets: BTreeSet<usize>,
143 pub interfaces: BTreeSet<usize>,
144 pub namespaces: BTreeSet<usize>,
145 pub config_declarations: BTreeSet<usize>,
146 pub decorator_declarations: BTreeSet<usize>,
147 pub pipeline_item_declarations: BTreeSet<usize>,
148 pub middlewares: BTreeSet<usize>,
149 pub handlers: BTreeSet<usize>,
150 pub handler_groups: BTreeSet<usize>,
151 pub struct_declarations: BTreeSet<usize>,
152 pub use_middlewares_block: Option<usize>,
153 pub empty_decorators: BTreeSet<usize>,
154 pub unattached_decorators: BTreeSet<usize>,
155 pub synthesized_shape_declarations: BTreeSet<usize>,
156 pub handler_template_declarations: BTreeSet<usize>,
157}
158
159impl NamespaceReferences {
160
161 pub fn new() -> Self {
162 Self {
163 constants: btreeset!{},
164 connector: None,
165 configs: btreeset!{},
166 enums: btreeset!{},
167 models: btreeset!{},
168 data_sets: btreeset!{},
169 interfaces: btreeset!{},
170 namespaces: btreeset!{},
171 config_declarations: btreeset!{},
172 decorator_declarations: btreeset!{},
173 pipeline_item_declarations: btreeset!{},
174 middlewares: btreeset!{},
175 handlers: btreeset!{},
176 handler_groups: btreeset!{},
177 struct_declarations: btreeset!{},
178 use_middlewares_block: None,
179 empty_decorators: btreeset! {},
180 unattached_decorators: btreeset! {},
181 synthesized_shape_declarations: btreeset! {},
182 handler_template_declarations: btreeset! {},
183 }
184 }
185}
186
187impl Write for Namespace {
188 fn write<'a>(&'a self, writer: &mut Writer<'a>) {
189 writer.write_children(self, self.children.values());
190 }
191 fn is_block_level_element(&self) -> bool {
192 true
193 }
194}