teo_runtime/schema/load/
load_interface.rs

1use indexmap::indexmap;
2use teo_parser::ast::schema::Schema;
3use teo_parser::diagnostics::diagnostics::Diagnostics;
4use teo_parser::traits::has_availability::HasAvailability;
5use teo_parser::traits::identifiable::Identifiable;
6use teo_parser::traits::info_provider::InfoProvider;
7use teo_parser::traits::named_identifiable::NamedIdentifiable;
8use teo_parser::traits::resolved::Resolve;
9use teo_result::Result;
10use crate::{interface, namespace};
11use crate::model::field::is_optional::{IsOptional};
12use crate::model::field::set_optional::SetOptional;
13use crate::schema::fetch::fetch_decorator_arguments::fetch_decorator_arguments;
14use crate::schema::load::load_comment::load_comment;
15
16pub fn load_interface(main_namespace_builder: &namespace::Builder, schema: &Schema, interface_declaration: &teo_parser::ast::interface::InterfaceDeclaration, diagnostics: &mut Diagnostics) -> Result<()> {
17    let mut fields = indexmap! {};
18    let mut generic_names = vec![];
19    let mut extends = vec![];
20    if let Some(generics_declaration) = interface_declaration.generics_declaration() {
21        for gen in generics_declaration.identifiers() {
22            generic_names.push(gen.name().to_owned().clone());
23        }
24    }
25    for t in interface_declaration.extends() {
26        extends.push(t.resolved().clone());
27    }
28    for field_declaration in interface_declaration.fields() {
29        if field_declaration.is_available() {
30            fields.insert(
31                field_declaration.identifier().name().to_owned(),
32                load_interface_field(main_namespace_builder, field_declaration, schema, diagnostics)?,
33            );
34        }
35    }
36    let interface_builder = interface::Builder::new(
37        interface_declaration.string_path().clone(),
38        interface_declaration.path().clone(),
39        load_comment(interface_declaration.comment()),
40        fields,
41        generic_names,
42        extends,
43        interface_declaration.resolved().shape().clone(),
44    );
45    for decorator in interface_declaration.decorators() {
46        if let Some(decorator_declaration) = schema.find_top_by_path(decorator.resolved()).unwrap().as_decorator_declaration() {
47            if let Some(decorator_implementation) = main_namespace_builder.interface_decorator_at_path(&decorator_declaration.str_path()) {
48                let args = fetch_decorator_arguments(decorator, schema, interface_declaration, main_namespace_builder, diagnostics)?;
49                decorator_implementation.call.call(args, &interface_builder)?;
50            }
51        }
52    }
53    let dest_namespace = main_namespace_builder.descendant_namespace_or_create_at_path(&interface_declaration.namespace_string_path());
54    dest_namespace.insert_interface(interface_declaration.identifier().name().to_owned(), interface_builder.build());
55    Ok(())
56}
57
58fn load_interface_field(main_namespace_builder: &namespace::Builder, field_declaration: &teo_parser::ast::field::Field, schema: &Schema, diagnostics: &mut Diagnostics) -> Result<interface::Field> {
59    let field_builder = interface::field::Builder::new(
60        field_declaration.identifier().name().to_owned(),
61        load_comment(field_declaration.comment()),
62        field_declaration.type_expr().resolved().clone(),
63    );
64    if field_declaration.type_expr().resolved().is_optional() {
65        field_builder.set_optional();
66    } else {
67        field_builder.set_required();
68    }
69    Ok(field_builder.build())
70}