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) {
if let Some(text) = label_text(ast_graph, n_id) {
out.push_str(text);
return;
}
for c_id in adj_ast(ast_graph, n_id, None, &[]) {
lazy_childs_text(ast_graph, c_id, out);
}
}
#[cfg(test)]
mod tests {
use super::node_to_str;
use crate::ast::{AstGraph, AstNode};
use crate::NodeId;
use alloc::borrow::ToOwned;
#[test]
fn joins_the_text_of_the_leaves_in_order() {
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");
}
#[test]
fn a_node_with_text_is_not_joined_with_its_children() {
let mut ast = AstGraph::new();
let mut literal = AstNode::new(1, 1, "interpreted_string_literal".to_owned());
literal.text = Some("\"/a\"".to_owned());
ast.add_node(NodeId(1), literal);
for (index, text) in [(0_u32, "\""), (1, "/a"), (2, "\"")] {
let id = NodeId(u64::from(index) + 2);
let mut child = AstNode::new(1, 1, "token".to_owned());
child.text = Some(text.to_owned());
ast.add_node(id, child);
ast.add_edge(NodeId(1), id, index);
}
assert_eq!(node_to_str(&ast, NodeId(1)), "\"/a\"");
}
}