css_parse/traits/
cursor_sink.rs1use crate::{Cursor, SourceCursor, Token};
2use bumpalo::collections::Vec;
3
4pub trait CursorSink {
8 fn append(&mut self, c: Cursor);
9}
10
11pub trait SourceCursorSink<'a> {
12 fn append(&mut self, c: SourceCursor<'a>);
13}
14
15const SEPARATOR: Cursor = Cursor::dummy(Token::SPACE);
16
17impl<'a> CursorSink for Vec<'a, Cursor> {
18 fn append(&mut self, c: Cursor) {
19 if let Some(last) = self.last()
22 && last.token().needs_separator_for(c.into())
23 {
24 self.push(SEPARATOR);
25 }
26 self.push(c);
27 }
28}
29
30impl<'a> SourceCursorSink<'a> for Vec<'a, SourceCursor<'a>> {
31 fn append(&mut self, c: SourceCursor<'a>) {
32 if let Some(last) = self.last()
35 && last.token().needs_separator_for(c.token())
36 {
37 self.push(SourceCursor::from(SEPARATOR, " "));
38 }
39 self.push(c)
40 }
41}
42
43#[cfg(test)]
44mod test {
45 use super::*;
46 use crate::{ComponentValues, EmptyAtomSet, Parser, ToCursors};
47 use bumpalo::Bump;
48 use css_lexer::Lexer;
49
50 #[test]
51 fn test_cursor_sink_for_vec() {
52 use std::fmt::Write;
53 let source_text = "black white";
54 let bump = Bump::default();
55 let mut stream = Vec::new_in(&bump);
56 let lexer = Lexer::new(&EmptyAtomSet::ATOMS, source_text);
57 let mut parser = Parser::new(&bump, source_text, lexer);
58 parser.parse_entirely::<ComponentValues>().output.unwrap().to_cursors(&mut stream);
59 let mut str = String::new();
60 for c in stream {
61 write!(&mut str, "{}", SourceCursor::from(c, c.str_slice(source_text))).unwrap();
62 }
63 assert_eq!(str, "black white");
64 }
65}