arc_isle/parser/
mod.rs

1mod hosts;
2mod imports;
3mod interfaces;
4mod types;
5pub(crate) mod utils;
6mod versioning;
7
8use std::collections::HashMap;
9use std::error::Error;
10use std::fmt::Display;
11
12use crate::parser::hosts::HostsParser;
13use crate::parser::imports::detect;
14use crate::parser::types::TypesParser;
15use crate::parser::{utils::read_yaml, versioning::VersioningParser};
16use crate::schema::{ImportError, Schema, TypeUsageMeta, UnknownType};
17
18use self::interfaces::InterfacesParser;
19
20#[derive(Debug)]
21pub struct MissingTypeDeclError {
22    pub list: Vec<UnknownType>
23}
24
25impl Error for MissingTypeDeclError {
26}
27
28impl Display for MissingTypeDeclError {
29   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30       f.write_str(&format!("{:?}", self.list))
31   } 
32}
33
34pub fn parse(parent_path: &str) -> Result<Schema, Box<dyn std::error::Error>> {
35    let file_path = &(parent_path.to_string() + "/main.yaml");
36    let yaml = read_yaml(file_path)?;
37    let main = &yaml[0];
38    let hosts_parser = HostsParser { main };
39    let hosts = hosts_parser.parse()?;
40    let versioning_parser = VersioningParser { main };
41    let versioning = versioning_parser.parse()?;
42    let mut types_usage: HashMap<String, TypeUsageMeta> = HashMap::new();
43    let main_types_hash = main["types"]
44        .as_hash()
45        .ok_or(ImportError::InvalidInputSource)?;
46    let types_imports = detect(&main_types_hash, parent_path);
47    let mut types_parser = TypesParser {
48        parent_path,
49        types_usage: &mut types_usage,
50    };
51    let mut types: Vec<_> = vec![];
52    for import in types_imports {
53        types.extend(types_parser.parse(import?)?);
54    }
55    let main_interfaces_hash = main["interfaces"]
56        .as_hash()
57        .ok_or(ImportError::InvalidInputSource)?;
58    let interfaces_imports = detect(&main_interfaces_hash, parent_path);
59    let mut interfaces_parser = InterfacesParser {
60        parent_path,
61        types_usage: &mut types_usage,
62        types: &types,
63    };
64    let mut interfaces: Vec<_> = vec![];
65    for import in interfaces_imports {
66        interfaces.extend(interfaces_parser.parse(import?)?);
67    }
68    let mut missing_declations: Vec<UnknownType> = Vec::new();
69    for (type_name, unknown) in &types_usage {
70        if let Some(unknown) = unknown {
71            for e in unknown {
72                missing_declations.push(e.clone());
73                match e {
74                    UnknownType::InTypeDeclaration(ti, pi) => {
75                        println!("Unknown type {} at {} in property at {}", type_name, ti, pi);
76                    }
77                    UnknownType::InPayload(ii, pi) => {
78                        println!("Unknown type {} in interface (#{}) input {}", type_name, ii, pi);
79                    }
80                    UnknownType::InResponse(ii, code, pi) => {
81                        println!(
82                        "Unknown type {} in interface (#{}) output status code {} in property at {}",
83                        type_name, ii, code, pi
84                    );
85                    }
86                }
87            }
88        }
89    }
90    if !missing_declations.is_empty() {
91        let err = MissingTypeDeclError{list: missing_declations};
92        return Err(Box::new(err));
93    }
94    let schema = Schema {
95        hosts,
96        versioning,
97        types,
98        interfaces,
99    };
100    Ok(schema)
101}