teo-parser 0.3.0

Parser for Teo schema language
Documentation
use crate::ast::data_set::DataSet;
use crate::ast::literals::EnumVariantLiteral;
use crate::ast::reference_space::ReferenceSpace;
use crate::ast::schema::Schema;
use crate::ast::source::Source;
use crate::availability::Availability;
use crate::completion::collect_argument_list_names::collect_argument_list_names_from_argument_list_declaration;
use crate::completion::completion_item::CompletionItem;
use crate::completion::completion_item_from_top::documentation_from_comment;
use crate::completion::find_completion_in_argument_list::find_completion_in_argument_list;
use crate::r#type::synthesized_enum::SynthesizedEnum;
use crate::r#type::Type;
use crate::search::search_identifier_path::search_identifier_path_names_with_filter_to_top_multiple;
use crate::traits::info_provider::InfoProvider;
use crate::traits::named_identifiable::NamedIdentifiable;
use crate::traits::resolved::Resolve;
use crate::utils::top_filter::top_filter_for_reference_type;

pub(super) fn find_completion_in_enum_variant_literal(schema: &Schema, source: &Source, enum_variant_literal: &EnumVariantLiteral, line_col: (usize, usize), namespace_path: &Vec<&str>, expect: &Type, availability: Availability) -> Vec<CompletionItem> {
    if enum_variant_literal.identifier().span.contains_line_col(line_col) {
        find_completion_in_empty_enum_variant_literal(schema, source, namespace_path, expect, availability)
    } else if let Some(argument_list) = enum_variant_literal.argument_list() {
        if argument_list.span.contains_line_col(line_col) {
            match expect {
                Type::EnumVariant(reference) => {
                    let enum_definition = schema.find_top_by_path(reference.path()).unwrap().as_enum().unwrap();
                    if let Some(member) = enum_definition.members().find(|m| m.identifier().name() == enum_variant_literal.identifier().name()) {
                        if let Some(argument_list_declaration) = member.argument_list_declaration() {
                            find_completion_in_argument_list(schema, source, argument_list, line_col, namespace_path, availability, vec![collect_argument_list_names_from_argument_list_declaration(
                                argument_list_declaration
                            )])
                        } else {
                            find_completion_in_argument_list(schema, source, argument_list, line_col, namespace_path, availability, vec![])
                        }
                    } else {
                        find_completion_in_argument_list(schema, source, argument_list, line_col, namespace_path, availability, vec![])
                    }
                },
                _ => {
                    find_completion_in_argument_list(schema, source, argument_list, line_col, namespace_path, availability, vec![])
                }
            }
        } else {
            vec![]
        }
    } else {
        vec![]
    }
}

fn completion_item_from_synthesized_enum(synthesized_enum: &SynthesizedEnum) -> Vec<CompletionItem> {
    synthesized_enum.members.values().map(|member| CompletionItem {
        label: member.name.clone(),
        namespace_path: None,
        documentation: documentation_from_comment(member.comment.as_ref()),
        detail: None,
    }).collect()
}

pub(super) fn find_completion_in_empty_enum_variant_literal(schema: &Schema, source: &Source, namespace_path: &Vec<&str>, expect: &Type, availability: Availability) -> Vec<CompletionItem> {
    match expect {
        Type::EnumVariant(reference) => {
            let enum_definition = schema.find_top_by_path(reference.path()).unwrap().as_enum().unwrap();
            enum_definition.members().map(|member| CompletionItem {
                label: member.name().to_owned(),
                namespace_path: Some(enum_definition.str_path().join(".")),
                documentation: documentation_from_comment(member.comment()),
                detail: None,
            }).collect()
        },
        Type::SynthesizedEnum(synthesized_enum) => {
            completion_item_from_synthesized_enum(synthesized_enum)
        },
        Type::SynthesizedEnumReference(synthesized_enum_reference) => {
            if let Some(synthesized_enum) = synthesized_enum_reference.fetch_synthesized_definition(schema) {
                completion_item_from_synthesized_enum(synthesized_enum)
            } else {
                vec![]
            }
        }
        Type::DataSetRecord(dataset_object, model_object) => {
            let dataset_string_path = dataset_object.as_data_set_object().unwrap();
            let model_reference = model_object.as_model_object().unwrap();
            let data_sets_found: Vec<&DataSet> = search_identifier_path_names_with_filter_to_top_multiple(
                &dataset_string_path.iter().map(AsRef::as_ref).collect(),
                schema,
                source,
                namespace_path,
                &top_filter_for_reference_type(ReferenceSpace::Default),
                availability,
            ).iter().map(|node| node.as_data_set().unwrap()).collect();
            let mut records = vec![];
            for data_set in data_sets_found {
                if let Some(group) = data_set.groups().find(|g| g.resolved() == model_reference) {
                    for record in group.records() {
                        records.push(CompletionItem {
                            label: record.identifier().name().to_owned(),
                            namespace_path: Some(data_set.namespace_str_path().join(".")),
                            documentation: None,
                            detail: None,
                        });
                    }
                }
            }
            records
        }
        _ => vec![]
    }
}