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()
);
}
}