teo_runtime/schema/load/
load_interface.rs1use 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}