#![allow(dead_code)]
use syntax_lang::{Builder, Node, Span, Token, TokenKind};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Kind {
Group,
Word,
Space,
}
impl TokenKind for Kind {
fn is_trivia(&self) -> bool {
matches!(self, Kind::Space)
}
}
#[derive(Clone, Debug)]
pub enum Shape {
Leaf(Kind, u32),
Branch(Vec<Shape>),
}
#[must_use]
pub fn build(shape: &Shape) -> (Node<Kind>, u32) {
let mut builder = Builder::new();
let mut cursor = 0u32;
emit(shape, &mut builder, &mut cursor);
let root = builder.finish().expect("shape produces a balanced tree");
(root, cursor)
}
fn emit(shape: &Shape, builder: &mut Builder<Kind>, cursor: &mut u32) {
match shape {
Shape::Leaf(kind, len) => {
let start = *cursor;
*cursor += *len;
builder.token(Token::new(*kind, Span::new(start, *cursor)));
}
Shape::Branch(children) => {
builder.start_node(Kind::Group);
for child in children {
emit(child, builder, cursor);
}
builder.finish_node();
}
}
}
#[must_use]
pub fn leaf_count(shape: &Shape) -> usize {
match shape {
Shape::Leaf(..) => 1,
Shape::Branch(children) => children.iter().map(leaf_count).sum(),
}
}