aldrin_parser/
parser.rs

1use crate::error::DuplicateServiceUuid;
2use crate::issues::Issues;
3use crate::validate::Validate;
4use crate::{Error, Resolver, Schema, Warning};
5use std::collections::hash_map::{Entry, HashMap};
6use std::iter;
7
8#[derive(Debug)]
9pub struct Parser {
10    main_schema: String,
11    schemas: HashMap<String, Schema>,
12    issues: Issues,
13}
14
15impl Parser {
16    pub fn parse<T: Resolver>(mut resolver: T) -> Self {
17        let mut issues = Issues::default();
18        let main_schema = Schema::parse(&resolver.main_schema(), &mut issues);
19
20        let mut this = Self {
21            main_schema: main_schema.name().to_owned(),
22            schemas: HashMap::from_iter(iter::once((main_schema.name().to_owned(), main_schema))),
23            issues,
24        };
25
26        let mut imports = this
27            .main_schema()
28            .imports()
29            .iter()
30            .map(|i| i.schema_name().value().to_owned())
31            .collect::<Vec<_>>();
32
33        while let Some(import) = imports.pop() {
34            let Entry::Vacant(entry) = this.schemas.entry(import) else {
35                continue;
36            };
37
38            let Some(schema_file) = resolver.resolve(entry.key()) else {
39                continue;
40            };
41
42            let schema = Schema::parse(&schema_file, &mut this.issues);
43
44            imports.extend(
45                schema
46                    .imports()
47                    .iter()
48                    .map(|i| i.schema_name().value().to_owned()),
49            );
50
51            entry.insert(schema);
52        }
53
54        this.validate();
55        this
56    }
57
58    fn validate(&mut self) {
59        DuplicateServiceUuid::validate(self.schemas.values(), &mut self.issues);
60
61        for (schema_name, schema) in &self.schemas {
62            let is_main_schema = *schema_name == self.main_schema;
63
64            let mut validate =
65                Validate::new(schema_name, &mut self.issues, &self.schemas, is_main_schema);
66
67            schema.validate(&mut validate);
68        }
69    }
70
71    pub fn main_schema(&self) -> &Schema {
72        self.get_schema(&self.main_schema).unwrap()
73    }
74
75    pub fn get_schema(&self, schema_name: &str) -> Option<&Schema> {
76        self.schemas.get(schema_name)
77    }
78
79    pub fn errors(&self) -> &[Error] {
80        self.issues.errors()
81    }
82
83    pub fn warnings(&self) -> &[Warning] {
84        self.issues.warnings()
85    }
86
87    pub fn other_warnings(&self) -> &[Warning] {
88        self.issues.other_warnings()
89    }
90
91    pub(crate) fn schemas(&self) -> &HashMap<String, Schema> {
92        &self.schemas
93    }
94}