use crate::alloc::borrow::ToOwned;
use crate::ast::node_utils::{children, AstNodeAndId};
use crate::ast::{AstGraph, AstNode};
use crate::syntax::_node_builders::core::SyntaxNodeBuildError;
use crate::syntax::core_nodes::{ArrayExpression, CoreSyntaxNode, CoreSyntaxNodeWithId};
use alloc::vec::Vec;
fn filter_comments(items: Vec<CoreSyntaxNodeWithId>) -> Vec<CoreSyntaxNodeWithId> {
items
.into_iter()
.filter(|(n, _)| !matches!(n, CoreSyntaxNode::Comment(_)))
.collect()
}
fn ensure_one_expression(
element_group: &[CoreSyntaxNodeWithId],
) -> Result<CoreSyntaxNodeWithId, SyntaxNodeBuildError> {
match element_group {
[unique] => Ok(unique.clone()),
[_, ..] => Err(SyntaxNodeBuildError::Error(
"There is more than one expression/node for an element of an ArrayExpression"
.to_owned(),
)),
[] => Err(SyntaxNodeBuildError::Error(
"An element group of an ArrayExpression is empty".to_owned(),
)),
}
}
pub fn build_array_expression(
graph: &AstGraph,
node: &AstNode,
build_syntax_node: impl Fn(AstNodeAndId) -> Result<CoreSyntaxNodeWithId, SyntaxNodeBuildError>,
) -> Result<ArrayExpression, SyntaxNodeBuildError> {
let all_children = children(graph, node).map_err(SyntaxNodeBuildError::ResolutionError)?;
let removed_delimiters = all_children
.iter()
.filter(|(child, _)| !matches!(child.kind.as_str(), "[" | "]"))
.collect::<Vec<_>>();
let element_groups = removed_delimiters
.split(|(child, _)| child.kind == ",")
.collect::<Vec<_>>();
let trimmed_groups = match element_groups.as_slice() {
[rest @ .., []] => rest, all => all,
};
let transformed_groups = trimmed_groups.iter().map(|group| {
group
.iter()
.map(|i| build_syntax_node(**i))
.collect::<Result<Vec<_>, _>>()
});
let elements = transformed_groups
.map(|r| {
r.map(filter_comments)
.and_then(|g| ensure_one_expression(g.as_slice()))
})
.collect::<Result<Vec<_>, _>>();
elements.map(|e| ArrayExpression { elements: e })
}
#[cfg(test)]
mod tests;