teo_parser/parser/
parse_model.rs

1use std::cell::RefCell;
2use crate::ast::model::Model;
3use crate::{parse_append, parse_container_node_variables, parse_container_node_variables_cleanup, parse_insert, parse_insert_keyword, parse_insert_punctuation, parse_set_identifier_and_string_path, parse_set_optional};
4use crate::parser::parse_availability_end::parse_availability_end;
5use crate::parser::parse_availability_flag::parse_availability_flag;
6use crate::parser::parse_code_comment::parse_code_comment;
7use crate::parser::parse_doc_comment::parse_doc_comment;
8use crate::parser::parse_decorator::parse_decorator;
9use crate::parser::parse_field::parse_field;
10use crate::parser::parse_handler_group::parse_handler_declaration;
11use crate::parser::parse_include_handler_from_template::parse_include_handler_from_template;
12use crate::parser::parse_partial_field::parse_partial_field;
13use crate::parser::parse_span::parse_span;
14use crate::parser::parser_context::ParserContext;
15use crate::parser::pest_parser::{Pair, Rule};
16
17pub(super) fn parse_model_declaration(pair: Pair<'_>, context: &ParserContext) -> Model {
18    let (
19        span,
20        path,
21        mut string_path,
22        mut children,
23        define_availability,
24        actual_availability
25    ) = parse_container_node_variables!(pair, context, named, availability);
26    let mut inside_block = false;
27    let mut comment = None;
28    let mut decorators = vec![];
29    let mut empty_decorator_spans = vec![];
30    let mut empty_field_decorator_spans = vec![];
31    let mut unattached_field_decorators = vec![];
32    let mut identifier = 0;
33    let mut fields = vec![];
34    let mut partial_fields = vec![];
35    let mut handlers = vec![];
36    let mut handler_inclusions = vec![];
37    for current in pair.into_inner() {
38        match current.as_rule() {
39            Rule::MODEL_KEYWORD => parse_insert_keyword!(context, current, children, "model"),
40            Rule::BLOCK_CLOSE => parse_insert_punctuation!(context, current, children, "}"),
41            Rule::BLOCK_OPEN => {
42                parse_insert_punctuation!(context, current, children, "{");
43                inside_block = true;
44            },
45            Rule::triple_comment_block => if !inside_block {
46                parse_set_optional!(parse_doc_comment(current, context), children, comment)
47            } else {
48                context.insert_unattached_doc_comment(parse_span(&current));
49                parse_append!(parse_doc_comment(current, context), children);
50            },
51            Rule::double_comment_block => parse_append!(parse_code_comment(current, context), children),
52            Rule::decorator => if inside_block {
53                unattached_field_decorators.push(parse_decorator(current, context));
54            } else {
55                parse_insert!(parse_decorator(current, context), children, decorators);
56            },
57            Rule::empty_decorator => if inside_block {
58                empty_field_decorator_spans.push(parse_span(&current));
59            } else {
60                empty_decorator_spans.push(parse_span(&current));
61            },
62            Rule::identifier => parse_set_identifier_and_string_path!(context, current, children, identifier, string_path),
63            Rule::field_declaration => parse_insert!(parse_field(current, context), children, fields),
64            Rule::partial_field => parse_insert!(parse_partial_field(current, context), children, partial_fields),
65            Rule::handler_declaration => parse_insert!(parse_handler_declaration(current, context, true), children, handlers),
66            Rule::availability_start => parse_append!(parse_availability_flag(current, context), children),
67            Rule::availability_end => parse_append!(parse_availability_end(current, context), children),
68            Rule::include_handler_from_template => parse_insert!(parse_include_handler_from_template(current, context), children, handler_inclusions),
69            _ => context.insert_unparsed(parse_span(&current)),
70        }
71    }
72    parse_container_node_variables_cleanup!(context, named);
73    Model {
74        span,
75        path,
76        string_path,
77        children,
78        define_availability,
79        actual_availability,
80        comment,
81        identifier,
82        fields,
83        partial_fields,
84        decorators,
85        empty_decorator_spans,        
86        empty_field_decorator_spans,
87        unattached_field_decorators,
88        handlers,
89        handler_inclusions,
90        resolved: RefCell::new(None),
91    }
92}