fluidattacks-blends-domain 0.6.1

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

use alloc::string::String;

use crate::ast::AstGraph;
use crate::query::{adj_ast, label_text};
use crate::NodeId;

#[must_use]
pub fn node_to_str(ast_graph: &AstGraph, n_id: NodeId) -> String {
    let mut out = String::new();
    lazy_childs_text(ast_graph, n_id, &mut out);
    out
}

fn lazy_childs_text(ast_graph: &AstGraph, n_id: NodeId, out: &mut String) {
    for c_id in adj_ast(ast_graph, n_id, None, &[]) {
        lazy_childs_text(ast_graph, c_id, out);
    }
    if let Some(text) = label_text(ast_graph, n_id) {
        out.push_str(text);
    }
}

#[cfg(test)]
mod tests {
    use super::node_to_str;
    use crate::ast::{AstGraph, AstNode};
    use crate::NodeId;
    use alloc::borrow::ToOwned;

    #[test]
    fn concatenates_descendant_text_children_first() {
        let mut ast = AstGraph::new();
        ast.add_node(
            NodeId(1),
            AstNode::new(1, 1, "block_mapping_pair".to_owned()),
        );
        let mut key = AstNode::new(1, 1, "string_scalar".to_owned());
        key.text = Some("empty-key".to_owned());
        ast.add_node(NodeId(2), key);
        let mut colon = AstNode::new(1, 10, ":".to_owned());
        colon.text = Some(":".to_owned());
        ast.add_node(NodeId(3), colon);
        ast.add_edge(NodeId(1), NodeId(2), 0);
        ast.add_edge(NodeId(1), NodeId(3), 1);

        assert_eq!(node_to_str(&ast, NodeId(1)), "empty-key:");
        assert_eq!(node_to_str(&ast, NodeId(2)), "empty-key");
    }
}