teo_parser/ast/
schema.rs

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    // Public APIs
78
79    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}