use {
super::*,
std::sync::Arc,
};
#[derive(Clone, Debug, PartialEq)]
pub struct TokenStream<Token> {
pub stream: Arc<[chumsky::prelude::Spanned<Token>]>,
pub source_key: SourceKey,
}
impl<Token> TokenStream<Token> {
pub fn new(
source_key: SourceKey,
tokens: Vec<chumsky::prelude::Spanned<Token>>,
) -> Self {
Self {
stream: Arc::from(tokens.into_boxed_slice()),
source_key,
}
}
pub fn as_slice(&self) -> &[chumsky::prelude::Spanned<Token>] {
self.stream.as_ref()
}
pub fn source_key(&self) -> SourceKey {
self.source_key
}
}
pub struct TokenStreamPrinterState<'a> {
pub source: &'a str,
pub span_cache: &'a SpanCache,
}
impl<'a> TokenStreamPrinterState<'a> {
pub fn new(source: &'a str, span_cache: &'a SpanCache) -> Self {
Self { source, span_cache }
}
pub fn span_text(&self, span: &Span) -> &str {
span.text(self.span_cache, self.source).unwrap_or("")
}
}
impl<Token: bluegum::Bluegum> bluegum::Bluegum for TokenStream<Token> {
fn node(&self, b: &mut bluegum::Builder) {
b.name("Lexer::TokenStream");
b.add_nodes_of_builders(
"Tokens",
self
.stream
.iter()
.map(|s| bluegum::Builder::render(&s.inner))
.collect::<Vec<bluegum::Builder>>(),
);
}
}
impl<'a, Token: bluegum::BluegumWithState<TokenStreamPrinterState<'a>>>
bluegum::BluegumWithState<TokenStreamPrinterState<'a>>
for TokenStream<Token>
{
fn node_with_state(
&self,
b: &mut bluegum::Builder,
state: &TokenStreamPrinterState<'a>,
) {
b.name("Lexer::TokenStream");
b.add_nodes_of_builders(
"Tokens",
self
.stream
.iter()
.map(|s| bluegum::Builder::render_with_state(&s.inner, state))
.collect::<Vec<bluegum::Builder>>(),
);
}
}
impl<Token: std::fmt::Debug> TokenStream<Token> {
pub fn pretty_print(&self) -> String {
self.pretty_print_with_prefix("")
}
pub fn pretty_print_with_prefix(&self, line_prefix: &str) -> String {
self
.stream
.iter()
.map(|s| format!("{line_prefix}({:?}) → {:?}", s.span, s.inner))
.collect::<Vec<String>>()
.join("\n")
}
}