1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use super::Parser;
use crate::{
tokenizer::{token::Comment, Tokenizer},
ParserOptions, Syntax,
};
/// Parser builder is for building a parser while allowing us
/// to control advanced behaviors.
///
/// Unlike [`Parser`], syntax isn't required when creating a parser builder,
/// and the default syntax will be CSS. If you need to parse with another syntax,
/// use the [`syntax`](ParserBuilder::syntax) to modify it.
pub struct ParserBuilder<'cmt, 's: 'cmt> {
source: &'s str,
syntax: Syntax,
options: Option<ParserOptions>,
comments: Option<&'cmt mut Vec<Comment<'s>>>,
}
impl<'cmt, 's: 'cmt> ParserBuilder<'cmt, 's> {
/// Create a parser builder from given source code.
pub fn new(source: &'s str) -> Self {
ParserBuilder {
source,
options: None,
syntax: Syntax::default(),
comments: None,
}
}
/// Specify the syntax for parsing.
pub fn syntax(mut self, syntax: Syntax) -> Self {
self.syntax = syntax;
self
}
/// Customize parser options.
pub fn options(mut self, options: ParserOptions) -> Self {
self.options = Some(options);
self
}
/// Collect comments and put them into the given collection.
pub fn comments(mut self, comments: &'cmt mut Vec<Comment<'s>>) -> Self {
self.comments = Some(comments);
self
}
/// Disable collecting comments.
///
/// Collecting comments is disabled by default,
/// so you don't need to use this if you never call the [`comments`](ParserBuilder::comments) method.
pub fn ignore_comments(mut self) -> Self {
self.comments = None;
self
}
/// Build a parser.
pub fn build(self) -> Parser<'cmt, 's> {
let source = self.source.strip_prefix('\u{feff}').unwrap_or(self.source);
Parser {
source,
syntax: self.syntax,
options: self.options.unwrap_or_default(),
tokenizer: Tokenizer::new(self.source, self.syntax, self.comments),
state: Default::default(),
recoverable_errors: vec![],
cached_token: None,
}
}
}