1use std::collections::BTreeMap;
2use crate::availability::Availability;
3use crate::ast::config::Config;
4use crate::ast::config_declaration::ConfigDeclaration;
5use crate::ast::data_set::DataSet;
6use crate::ast::decorator_declaration::DecoratorDeclaration;
7use crate::ast::handler::{HandlerDeclaration, HandlerGroupDeclaration};
8use crate::ast::handler_template_declaration::HandlerTemplateDeclaration;
9use crate::ast::interface::InterfaceDeclaration;
10use crate::ast::middleware::MiddlewareDeclaration;
11use crate::ast::model::Model;
12use crate::ast::namespace::Namespace;
13use crate::ast::node::Node;
14use crate::ast::pipeline_item_declaration::PipelineItemDeclaration;
15use crate::ast::r#enum::Enum;
16use crate::ast::source::Source;
17use crate::ast::struct_declaration::StructDeclaration;
18use crate::ast::synthesized_shape_declaration::SynthesizedShapeDeclaration;
19use crate::traits::identifiable::Identifiable;
20
21#[derive(Debug)]
22pub struct Schema {
23 pub sources: BTreeMap<usize, Source>,
24 pub references: SchemaReferences,
25}
26
27impl Schema {
28
29 pub fn main_source(&self) -> &Source {
30 self.source(self.references.main_source.unwrap()).unwrap()
31 }
32
33 pub fn source(&self, id: usize) -> Option<&Source> {
34 self.sources.get(&id)
35 }
36
37 pub fn source_at_path(&self, path: &str) -> Option<&Source> {
38 self.sources().iter().find_map(|s| if s.file_path.as_str() == path { Some(*s) } else { None })
39 }
40
41 pub fn builtin_sources(&self) -> Vec<&Source> {
42 self.references.builtin_sources.iter().map(|id| self.source(*id).unwrap()).collect()
43 }
44
45 pub fn user_sources(&self) -> Vec<&Source> {
46 self.references.user_sources.iter().map(|id| self.source(*id).unwrap()).collect()
47 }
48
49 pub fn std_source(&self) -> &Source {
50 if self.builtin_sources().is_empty() {
51 self.sources().first().unwrap()
52 } else {
53 self.builtin_sources().first().unwrap()
54 }
55 }
56
57 pub fn find_config_declaration_by_name(&self, name: &str, availability: Availability) -> Option<&ConfigDeclaration> {
58 for config_declaration in self.config_declarations() {
59 if config_declaration.identifier().name() == name && config_declaration.define_availability.contains(availability) {
60 return Some(config_declaration)
61 }
62 }
63 None
64 }
65
66 pub fn find_top_by_path(&self, path: &Vec<usize>) -> Option<&Node> {
67 if path.len() < 2 {
68 return None;
69 }
70 if let Some(source) = self.source(*path.get(0).unwrap()) {
71 source.find_top_by_path(path)
72 } else {
73 None
74 }
75 }
76
77 pub fn sources(&self) -> Vec<&Source> {
80 self.sources.values().collect()
81 }
82
83 pub fn configs(&self) -> Vec<&Config> {
84 self.references.config_declarations.iter().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap()).collect()
85 }
86
87 pub fn server(&self) -> Option<&Config> {
88 self.references.server.as_ref().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap())
89 }
90
91 pub fn debug(&self) -> Option<&Config> {
92 self.references.debug.as_ref().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap())
93 }
94
95 pub fn admin(&self) -> Option<&Config> {
96 self.references.admin.as_ref().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap())
97 }
98
99 pub fn connectors(&self) -> Vec<&Config> {
100 self.references.connectors.iter().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap()).collect()
101 }
102
103 pub fn entities(&self) -> Vec<&Config> {
104 self.references.entities.iter().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap()).collect()
105 }
106
107 pub fn clients(&self) -> Vec<&Config> {
108 self.references.clients.iter().map(|path| self.find_top_by_path(path).unwrap().as_config().unwrap()).collect()
109 }
110
111 pub fn enums(&self) -> Vec<&Enum> {
112 self.references.enums.iter().map(|path| self.find_top_by_path(path).unwrap().as_enum().unwrap()).collect()
113 }
114
115 pub fn models(&self) -> Vec<&Model> {
116 self.references.models.iter().map(|path| self.find_top_by_path(path).unwrap().as_model().unwrap()).collect()
117 }
118
119 pub fn data_sets(&self) -> Vec<&DataSet> {
120 self.references.data_sets.iter().map(|path| self.find_top_by_path(path).unwrap().as_data_set().unwrap()).collect()
121 }
122
123 pub fn interfaces(&self) -> Vec<&InterfaceDeclaration> {
124 self.references.interfaces.iter().map(|path| self.find_top_by_path(path).unwrap().as_interface_declaration().unwrap()).collect()
125 }
126
127 pub fn namespaces(&self) -> Vec<&Namespace> {
128 self.references.namespaces.iter().map(|path| self.find_top_by_path(path).unwrap().as_namespace().unwrap()).collect()
129 }
130
131 pub fn config_declarations(&self) -> Vec<&ConfigDeclaration> {
132 self.references.config_declarations.iter().map(|path| self.find_top_by_path(path).unwrap().as_config_declaration().unwrap()).collect()
133 }
134
135 pub fn decorator_declarations(&self) -> Vec<&DecoratorDeclaration> {
136 self.references.decorator_declarations.iter().map(|path| self.find_top_by_path(path).unwrap().as_decorator_declaration().unwrap()).collect()
137 }
138
139 pub fn pipeline_item_declarations(&self) -> Vec<&PipelineItemDeclaration> {
140 self.references.pipeline_item_declarations.iter().map(|path| self.find_top_by_path(path).unwrap().as_pipeline_item_declaration().unwrap()).collect()
141 }
142
143 pub fn middleware_declarations(&self) -> Vec<&MiddlewareDeclaration> {
144 self.references.middlewares.iter().map(|path| self.find_top_by_path(path).unwrap().as_middleware_declaration().unwrap()).collect()
145 }
146
147 pub fn handler_declarations(&self) -> Vec<&HandlerDeclaration> {
148 self.references.handlers.iter().map(|path| self.find_top_by_path(path).unwrap().as_handler_declaration().unwrap()).collect()
149 }
150
151 pub fn handler_template_declarations(&self) -> Vec<&HandlerTemplateDeclaration> {
152 self.references.handler_templates.iter().map(|path| self.find_top_by_path(path).unwrap().as_handler_template_declaration().unwrap()).collect()
153 }
154
155 pub fn handler_group_declarations(&self) -> Vec<&HandlerGroupDeclaration> {
156 self.references.handler_groups.iter().map(|path| self.find_top_by_path(path).unwrap().as_handler_group_declaration().unwrap()).collect()
157 }
158
159 pub fn struct_declarations(&self) -> Vec<&StructDeclaration> {
160 self.references.struct_declarations.iter().map(|path| self.find_top_by_path(path).unwrap().as_struct_declaration().unwrap()).collect()
161 }
162
163 pub fn declared_shapes(&self) -> Vec<&SynthesizedShapeDeclaration> {
164 self.references.declared_shapes.iter().map(|path| self.find_top_by_path(path).unwrap().as_synthesized_shape_declaration().unwrap()).collect()
165 }
166}
167
168#[derive(Debug, Clone)]
169pub struct SchemaReferences {
170 pub builtin_sources: Vec<usize>,
171 pub user_sources: Vec<usize>,
172 pub main_source: Option<usize>,
173 pub configs: Vec<Vec<usize>>,
174 pub server: Option<Vec<usize>>,
175 pub debug: Option<Vec<usize>>,
176 pub connectors: Vec<Vec<usize>>,
177 pub entities: Vec<Vec<usize>>,
178 pub clients: Vec<Vec<usize>>,
179 pub admin: Option<Vec<usize>>,
180 pub enums: Vec<Vec<usize>>,
181 pub models: Vec<Vec<usize>>,
182 pub data_sets: Vec<Vec<usize>>,
183 pub interfaces: Vec<Vec<usize>>,
184 pub namespaces: Vec<Vec<usize>>,
185 pub config_declarations: Vec<Vec<usize>>,
186 pub decorator_declarations: Vec<Vec<usize>>,
187 pub pipeline_item_declarations: Vec<Vec<usize>>,
188 pub middlewares: Vec<Vec<usize>>,
189 pub handlers: Vec<Vec<usize>>,
190 pub handler_templates: Vec<Vec<usize>>,
191 pub handler_groups: Vec<Vec<usize>>,
192 pub struct_declarations: Vec<Vec<usize>>,
193 pub declared_shapes: Vec<Vec<usize>>,
194 pub use_middlewares_blocks: Vec<Vec<usize>>,
195}
196
197impl SchemaReferences {
198
199 pub fn new() -> Self {
200 Self {
201 builtin_sources: vec![],
202 user_sources: vec![],
203 main_source: None,
204 connectors: vec![],
205 configs: vec![],
206 server: None,
207 entities: vec![],
208 clients: vec![],
209 admin: None,
210 enums: vec![],
211 models: vec![],
212 data_sets: vec![],
213 debug: None,
214 interfaces: vec![],
215 namespaces: vec![],
216 config_declarations: vec![],
217 decorator_declarations: vec![],
218 pipeline_item_declarations: vec![],
219 middlewares: vec![],
220 handlers: vec![],
221 handler_templates: vec![],
222 handler_groups: vec![],
223 struct_declarations: vec![],
224 declared_shapes: vec![],
225 use_middlewares_blocks: vec![],
226 }
227 }
228
229 pub fn add_config(&mut self, config: &Config) {
230 self.configs.push(config.path().clone());
231 if config.keyword().is_client() {
232 self.clients.push(config.path().clone());
233 } else if config.keyword().is_connector() {
234 self.connectors.push(config.path().clone());
235 } else if config.keyword().is_server() {
236 self.server = Some(config.path().clone());
237 } else if config.keyword().is_entity() {
238 self.entities.push(config.path().clone());
239 } else if config.keyword().is_debug() {
240 self.debug = Some(config.path().clone());
241 } else if config.keyword().is_admin() {
242 self.admin = Some(config.path().clone());
243 }
244 }
245}