fluidattacks-blends-domain 0.6.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
//! Typed accessors over node attributes and label types.

use alloc::vec::Vec;

use crate::ast::AstGraph;
use crate::syntax::{SyntaxGraph, SyntaxKind};
use crate::NodeId;

#[must_use]
pub fn label_text(ast_graph: &AstGraph, n_id: NodeId) -> Option<&str> {
    ast_graph
        .nodes
        .get(&n_id)
        .and_then(|node| node.text.as_deref())
}

#[must_use]
pub fn matching_nodes(graph: &SyntaxGraph, label_type: SyntaxKind) -> Vec<NodeId> {
    graph
        .nodes_by_type
        .get(&label_type)
        .cloned()
        .unwrap_or_default()
}

#[cfg(test)]
mod tests {
    use super::{label_text, matching_nodes};
    use crate::ast::{AstGraph, AstNode};
    use crate::syntax::{SyntaxGraph, SyntaxKind, SyntaxNode};
    use crate::NodeId;
    use alloc::borrow::ToOwned;
    use alloc::vec::Vec;

    fn sample() -> SyntaxGraph {
        let mut graph = SyntaxGraph::new();
        graph.add_node(NodeId(9), SyntaxNode::Break);
        graph.add_node(NodeId(1), SyntaxNode::File);
        graph.add_node(NodeId(5), SyntaxNode::Break);
        graph.add_node(NodeId(2), SyntaxNode::Break);
        graph
    }

    #[test]
    fn labels_read_the_node_or_default() {
        let mut ast = AstGraph::new();
        let mut scalar = AstNode::new(2, 5, "string_scalar".to_owned());
        scalar.text = Some("doe".to_owned());
        ast.add_node(NodeId(1), AstNode::new(1, 1, "stream".to_owned()));
        ast.add_node(NodeId(4), scalar);

        assert_eq!(label_text(&ast, NodeId(4)), Some("doe"));
        assert_eq!(label_text(&ast, NodeId(1)), None);
    }

    #[test]
    fn matching_nodes_reads_the_index_in_insertion_order() {
        assert_eq!(
            matching_nodes(&sample(), SyntaxKind::Break),
            [NodeId(9), NodeId(5), NodeId(2)]
        );
        assert_eq!(matching_nodes(&sample(), SyntaxKind::File), [NodeId(1)]);
    }

    #[test]
    fn matching_nodes_is_empty_for_an_absent_syntax_type() {
        assert_eq!(matching_nodes(&sample(), SyntaxKind::If), Vec::new());
        assert_eq!(
            matching_nodes(&SyntaxGraph::new(), SyntaxKind::Break),
            Vec::new()
        );
    }
}