fluidattacks-blends-domain 0.14.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
use alloc::collections::BTreeMap;
use alloc::string::String;

use crate::syntax::builders::variable_declaration::build_variable_declaration_node;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError, SyntaxNode};
use crate::NodeId;

pub struct VarNameEntry {
    pub name_id: NodeId,
    pub name: String,
    pub type_name: Option<String>,
    pub value_id: Option<NodeId>,
}

pub fn build_expression_statement_node(
    args: &mut SyntaxGraphArgs<'_>,
    n_id: NodeId,
    c_ids: &[NodeId],
) -> Result<NodeId, SyntaxGraphError> {
    args.syntax_graph
        .add_node(n_id, SyntaxNode::ExpressionStatement);

    for c_id in c_ids {
        let built = args.generic(*c_id)?;
        args.syntax_graph.add_ast_edge(n_id, built);
    }

    Ok(n_id)
}

pub fn build_variable_declaration_group_node(
    args: &mut SyntaxGraphArgs<'_>,
    n_id: NodeId,
    entries: &[VarNameEntry],
) -> Result<NodeId, SyntaxGraphError> {
    if let [entry] = entries {
        return build_variable_declaration_node(
            args,
            n_id,
            entry.name.clone(),
            entry.type_name.clone(),
            entry.value_id,
            None,
            None,
        );
    }

    args.syntax_graph
        .add_node(n_id, SyntaxNode::ExpressionStatement);
    let mut built_values: BTreeMap<NodeId, NodeId> = BTreeMap::new();
    for entry in entries {
        let shared = entry
            .value_id
            .and_then(|value_id| built_values.get(&value_id).copied());
        let child_id = build_variable_declaration_node(
            args,
            entry.name_id,
            entry.name.clone(),
            entry.type_name.clone(),
            if shared.is_some() {
                None
            } else {
                entry.value_id
            },
            None,
            None,
        )?;
        if let Some(built) = shared {
            if let Some(SyntaxNode::VariableDeclaration { value_id, .. }) =
                args.syntax_graph.nodes.get_mut(&child_id)
            {
                *value_id = Some(built);
            }
        } else if let Some(ast_value_id) = entry.value_id {
            if let Some(built) = args
                .syntax_graph
                .nodes
                .get(&child_id)
                .and_then(SyntaxNode::value_id)
            {
                built_values.insert(ast_value_id, built);
            }
        }
        args.syntax_graph.add_ast_edge(n_id, child_id);
    }

    Ok(n_id)
}