fluidattacks-blends-domain 0.6.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
//! Counterpart of `blends/syntax/readers/yaml/block_mapping_pair.py`.

use crate::query::{adj_ast, pred_ast};
use crate::syntax::builders::pair::build_pair_node;
use crate::syntax::builders::symbol_lookup::build_symbol_lookup_node;
use crate::syntax::fields::yaml::{block_mapping_pair, flow_pair};
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};

fn inline_comment_id<G: CodeGraph>(graph: &G, pair_id: NodeId) -> Option<NodeId> {
    let parent = *pred_ast(graph, pair_id, None).first()?;
    adj_ast(graph, parent, None, &[])
        .into_iter()
        .skip_while(|&s_id| s_id != pair_id)
        .nth(1)
        .filter(|&s_id| graph.label_type(s_id) == Some("comment"))
}

pub fn reader(
    args: &mut SyntaxGraphArgs<'_>,
    n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
    let graph = args.ast_graph;
    let (key_id, value_id) = match graph.label_type(n_id) {
        Some("block_mapping_pair") => (
            args.optional_field_alt(n_id, block_mapping_pair::KEY),
            args.optional_field_alt(n_id, block_mapping_pair::VALUE),
        ),
        Some("flow_pair") => (
            args.optional_field_alt(n_id, flow_pair::KEY),
            args.optional_field_alt(n_id, flow_pair::VALUE),
        ),
        _ => return Err(SyntaxGraphError::UnexpectedAstShape),
    };

    if let (Some(key_id), Some(mut value_id)) = (key_id, value_id) {
        if graph.label_type(value_id) == Some("block_node") {
            value_id = adj_ast(graph, value_id, None, &[])
                .into_iter()
                .next_back()
                .ok_or(SyntaxGraphError::UnexpectedAstShape)?;
        }
        return build_pair_node(args, n_id, key_id, value_id).map(Some);
    }

    if let (Some(key_id), None) = (key_id, value_id) {
        if let Some(comment_id) = inline_comment_id(graph, n_id) {
            return build_pair_node(args, n_id, key_id, comment_id).map(Some);
        }
    }

    let symbol = node_to_str(graph, n_id);
    Ok(Some(build_symbol_lookup_node(args, n_id, symbol)))
}