use crate::{Cursor, CursorSink, SourceCursor, SourceCursorSink, Token};
use core::fmt::{Result, Write};
pub struct CursorWriteSink<'a, T: Write> {
source_text: &'a str,
writer: T,
last_token: Option<Token>,
err: Result,
}
impl<'a, T: Write> CursorWriteSink<'a, T> {
pub fn new(source_text: &'a str, writer: T) -> Self {
Self { source_text, writer, last_token: None, err: Ok(()) }
}
fn write(&mut self, c: Cursor, source: &'a str) -> Result {
self.err?;
if let Some(last) = self.last_token
&& last.needs_separator_for(c.token())
{
self.writer.write_char(' ')?;
}
self.last_token = Some(c.token());
self.writer.write_str(c.str_slice(source))?;
Ok(())
}
}
impl<'a, T: Write> CursorSink for CursorWriteSink<'a, T> {
fn append(&mut self, c: Cursor) {
self.err = self.write(c, self.source_text);
}
}
impl<'a, T: Write> SourceCursorSink<'a> for CursorWriteSink<'a, T> {
fn append(&mut self, c: SourceCursor<'a>) {
self.err = self.write(c.cursor(), c.source());
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{ComponentValues, EmptyAtomSet, Parser, ToCursors};
use bumpalo::Bump;
use css_lexer::Lexer;
#[test]
fn test() {
let source_text = "foo{bar:baz();}";
let bump = Bump::default();
let mut str = String::new();
let mut stream = CursorWriteSink::new(source_text, &mut str);
let lexer = Lexer::new(&EmptyAtomSet::ATOMS, source_text);
let mut parser = Parser::new(&bump, source_text, lexer);
parser.parse_entirely::<ComponentValues>().output.unwrap().to_cursors(&mut stream);
assert_eq!(str, "foo{bar:baz();}");
}
}