1use crate::cow_rc_str::CowRcStr;
6use crate::tokenizer::{SourceLocation, SourcePosition, Token, Tokenizer};
7use smallvec::SmallVec;
8use std::fmt;
9use std::ops::BitOr;
10use std::ops::Range;
11
12#[derive(Debug, Clone, Default)]
18pub struct ParserState {
19 pub(crate) position: usize,
20 pub(crate) current_line_start_position: usize,
21 pub(crate) current_line_number: u32,
22 pub(crate) at_start_of: Option<BlockType>,
23}
24
25impl ParserState {
26 #[inline]
28 pub fn position(&self) -> SourcePosition {
29 SourcePosition(self.position)
30 }
31
32 #[inline]
34 pub fn source_location(&self) -> SourceLocation {
35 SourceLocation {
36 line: self.current_line_number,
37 column: (self.position - self.current_line_start_position + 1) as u32,
38 }
39 }
40}
41
42#[derive(Clone, Copy, Debug, Eq, PartialEq)]
57pub enum ParseUntilErrorBehavior {
58 Consume,
60 Stop,
62}
63
64#[derive(Clone, Debug, PartialEq)]
66pub enum BasicParseErrorKind {
67 UnexpectedToken,
75 EndOfInput,
77 AtRuleInvalid,
80 AtRuleBodyInvalid,
82 QualifiedRuleInvalid,
84 TooManyNestedBlocks,
86}
87
88impl fmt::Display for BasicParseErrorKind {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 match self {
91 BasicParseErrorKind::TooManyNestedBlocks => {
92 write!(f, "nesting block limit reached")
93 }
94 BasicParseErrorKind::UnexpectedToken => write!(f, "unexpected token"),
95 BasicParseErrorKind::EndOfInput => write!(f, "unexpected end of input"),
96 BasicParseErrorKind::AtRuleInvalid => write!(f, "invalid @ rule encountered"),
97 BasicParseErrorKind::AtRuleBodyInvalid => write!(f, "invalid @ rule body encountered"),
98 BasicParseErrorKind::QualifiedRuleInvalid => {
99 write!(f, "invalid qualified rule encountered")
100 }
101 }
102 }
103}
104
105#[derive(Clone, Debug, PartialEq)]
107pub struct BasicParseError {
108 pub kind: BasicParseErrorKind,
110}
111
112impl BasicParseError {
113 #[inline]
115 pub fn new(kind: BasicParseErrorKind) -> Self {
116 Self { kind }
117 }
118
119 #[inline]
121 pub fn unexpected_token() -> Self {
122 Self::new(BasicParseErrorKind::UnexpectedToken)
123 }
124}
125
126impl<T> From<BasicParseError> for ParseError<T> {
127 #[inline]
128 fn from(this: BasicParseError) -> ParseError<T> {
129 ParseError {
130 kind: ParseErrorKind::Basic(this.kind),
131 }
132 }
133}
134
135#[derive(Clone, Debug, PartialEq)]
137pub enum ParseErrorKind<T> {
138 Basic(BasicParseErrorKind),
140 Custom(T),
142}
143
144impl<T> ParseErrorKind<T> {
145 pub fn into<U>(self) -> ParseErrorKind<U>
147 where
148 T: Into<U>,
149 {
150 match self {
151 ParseErrorKind::Basic(basic) => ParseErrorKind::Basic(basic),
152 ParseErrorKind::Custom(custom) => ParseErrorKind::Custom(custom.into()),
153 }
154 }
155}
156
157impl<E: fmt::Display> fmt::Display for ParseErrorKind<E> {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 match self {
160 ParseErrorKind::Basic(basic) => basic.fmt(f),
161 ParseErrorKind::Custom(custom) => custom.fmt(f),
162 }
163 }
164}
165
166#[derive(Clone, Debug, PartialEq)]
168pub struct ParseError<E> {
169 pub kind: ParseErrorKind<E>,
171}
172
173impl<T> ParseError<T> {
174 #[inline]
176 pub fn from_basic_kind(kind: BasicParseErrorKind) -> Self {
177 Self {
178 kind: ParseErrorKind::Basic(kind),
179 }
180 }
181
182 #[inline]
184 pub fn unexpected_token() -> Self {
185 Self::from_basic_kind(BasicParseErrorKind::UnexpectedToken)
186 }
187
188 #[inline]
190 pub fn custom<E: Into<T>>(error: E) -> Self {
191 Self {
192 kind: ParseErrorKind::Custom(error.into()),
193 }
194 }
195
196 pub fn basic(self) -> BasicParseError {
198 match self.kind {
199 ParseErrorKind::Basic(kind) => BasicParseError { kind },
200 ParseErrorKind::Custom(_) => panic!("Not a basic parse error"),
201 }
202 }
203
204 pub fn into<U>(self) -> ParseError<U>
206 where
207 T: Into<U>,
208 {
209 ParseError {
210 kind: self.kind.into(),
211 }
212 }
213}
214
215impl<E: fmt::Display> fmt::Display for ParseError<E> {
216 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
217 self.kind.fmt(f)
218 }
219}
220
221impl<E: fmt::Display + fmt::Debug> std::error::Error for ParseError<E> {}
222
223pub struct Parser<'i> {
226 tokenizer: Tokenizer<'i>,
227 cached_token: CachedToken<'i>,
228 current_block_depth: u8,
229 nested_block_limit: u8,
230 at_start_of: Option<BlockType>,
232 stop_before: Delimiters,
234}
235
236struct CachedToken<'i> {
237 token: Token<'i>,
238 start_position: SourcePosition,
239 end_state: ParserState,
240}
241
242#[derive(Copy, Clone, PartialEq, Eq, Debug)]
243pub(crate) enum BlockType {
244 Parenthesis,
245 SquareBracket,
246 CurlyBracket,
247}
248
249impl BlockType {
250 fn opening(token: &Token) -> Option<BlockType> {
251 match *token {
252 Token::Function(_) | Token::ParenthesisBlock => Some(BlockType::Parenthesis),
253 Token::SquareBracketBlock => Some(BlockType::SquareBracket),
254 Token::CurlyBracketBlock => Some(BlockType::CurlyBracket),
255 _ => None,
256 }
257 }
258
259 fn closing(token: &Token) -> Option<BlockType> {
260 match *token {
261 Token::CloseParenthesis => Some(BlockType::Parenthesis),
262 Token::CloseSquareBracket => Some(BlockType::SquareBracket),
263 Token::CloseCurlyBracket => Some(BlockType::CurlyBracket),
264 _ => None,
265 }
266 }
267}
268
269#[derive(Copy, Clone, PartialEq, Eq, Debug)]
277pub struct Delimiters {
278 bits: u8,
279}
280
281#[allow(non_upper_case_globals, non_snake_case)]
283pub mod Delimiter {
284 use super::Delimiters;
285
286 pub const None: Delimiters = Delimiters { bits: 0 };
288 pub const CurlyBracketBlock: Delimiters = Delimiters { bits: 1 << 1 };
290 pub const Semicolon: Delimiters = Delimiters { bits: 1 << 2 };
292 pub const Bang: Delimiters = Delimiters { bits: 1 << 3 };
294 pub const Comma: Delimiters = Delimiters { bits: 1 << 4 };
296}
297
298#[allow(non_upper_case_globals, non_snake_case)]
299mod ClosingDelimiter {
300 use super::Delimiters;
301
302 pub const CloseCurlyBracket: Delimiters = Delimiters { bits: 1 << 5 };
303 pub const CloseSquareBracket: Delimiters = Delimiters { bits: 1 << 6 };
304 pub const CloseParenthesis: Delimiters = Delimiters { bits: 1 << 7 };
305}
306
307impl BitOr<Delimiters> for Delimiters {
308 type Output = Delimiters;
309
310 #[inline]
311 fn bitor(self, other: Delimiters) -> Delimiters {
312 Delimiters {
313 bits: self.bits | other.bits,
314 }
315 }
316}
317
318impl Delimiters {
319 #[inline]
320 fn contains(self, other: Delimiters) -> bool {
321 (self.bits & other.bits) != 0
322 }
323
324 #[inline]
325 pub(crate) fn from_byte(byte: u8) -> Delimiters {
326 const TABLE: [Delimiters; 256] = {
327 let mut table = [Delimiter::None; 256];
328 table[b';' as usize] = Delimiter::Semicolon;
329 table[b'!' as usize] = Delimiter::Bang;
330 table[b',' as usize] = Delimiter::Comma;
331 table[b'{' as usize] = Delimiter::CurlyBracketBlock;
332 table[b'}' as usize] = ClosingDelimiter::CloseCurlyBracket;
333 table[b']' as usize] = ClosingDelimiter::CloseSquareBracket;
334 table[b')' as usize] = ClosingDelimiter::CloseParenthesis;
335 table
336 };
337
338 TABLE[byte as usize]
339 }
340}
341
342macro_rules! expect {
344 ($parser: ident, $($branches: tt)+) => {
345 {
346 match *$parser.next()? {
347 $($branches)+
348 _ => {
349 return Err(BasicParseError::unexpected_token())
350 }
351 }
352 }
353 }
354}
355
356pub type ArbitrarySubstitutionFunctions<'a> = &'a [&'static str];
359
360impl<'i> Parser<'i> {
361 const REASONABLE_NESTED_BLOCK_LIMIT: u8 = 75;
363
364 #[inline]
366 pub fn new(input: &'i str) -> Self {
367 Self {
368 tokenizer: Tokenizer::new(input),
369 at_start_of: None,
370 stop_before: Delimiter::None,
371 nested_block_limit: Self::REASONABLE_NESTED_BLOCK_LIMIT,
372 current_block_depth: 0,
373 cached_token: CachedToken {
374 token: Token::Semicolon, start_position: SourcePosition(usize::MAX), end_state: ParserState::default(),
377 },
378 }
379 }
380
381 pub fn set_nested_block_limit(&mut self, limit: u8) {
385 self.nested_block_limit = limit;
386 }
387
388 pub fn current_line(&self) -> &'i str {
390 self.tokenizer.current_source_line()
391 }
392
393 #[inline]
397 pub fn is_exhausted(&mut self) -> bool {
398 self.expect_exhausted().is_ok()
399 }
400
401 #[inline]
406 pub fn expect_exhausted(&mut self) -> Result<(), BasicParseError> {
407 let start = self.state();
408 let result = match self.next() {
409 Err(BasicParseError {
410 kind: BasicParseErrorKind::EndOfInput,
411 ..
412 }) => Ok(()),
413 Err(e) => unreachable!("Unexpected error encountered: {:?}", e),
414 Ok(_) => Err(BasicParseError::unexpected_token()),
415 };
416 self.reset(&start);
417 result
418 }
419
420 #[inline]
424 pub fn position(&self) -> SourcePosition {
425 self.tokenizer.position()
426 }
427
428 #[inline]
430 pub fn current_source_location(&self) -> SourceLocation {
431 self.tokenizer.current_source_location()
432 }
433
434 pub fn current_source_map_url(&self) -> Option<&str> {
440 self.tokenizer.current_source_map_url()
441 }
442
443 pub fn current_source_url(&self) -> Option<&str> {
449 self.tokenizer.current_source_url()
450 }
451
452 #[inline]
454 pub fn new_error_for_next_token<E>(&mut self) -> ParseError<E> {
455 match self.next() {
456 Ok(_) => ParseError::unexpected_token(),
457 Err(e) => e.into(),
458 }
459 }
460
461 #[inline]
465 pub fn state(&self) -> ParserState {
466 ParserState {
467 at_start_of: self.at_start_of,
468 ..self.tokenizer.state()
469 }
470 }
471
472 #[inline]
474 pub fn skip_whitespace(&mut self) {
475 if let Some(block_type) = self.at_start_of.take() {
476 consume_until_end_of_block(block_type, &mut self.tokenizer);
477 }
478
479 self.tokenizer.skip_whitespace()
480 }
481
482 #[inline]
483 pub(crate) fn skip_cdc_and_cdo(&mut self) {
484 if let Some(block_type) = self.at_start_of.take() {
485 consume_until_end_of_block(block_type, &mut self.tokenizer);
486 }
487
488 self.tokenizer.skip_cdc_and_cdo()
489 }
490
491 #[inline]
492 pub(crate) fn next_byte(&self) -> Option<u8> {
493 let byte = self.tokenizer.next_byte()?;
494 if self.stop_before.contains(Delimiters::from_byte(byte)) {
495 return None;
496 }
497 Some(byte)
498 }
499
500 #[inline]
505 pub fn reset(&mut self, state: &ParserState) {
506 self.tokenizer.reset(state);
507 self.at_start_of = state.at_start_of;
508 }
509
510 #[inline]
513 pub fn look_for_arbitrary_substitution_functions(
514 &mut self,
515 fns: ArbitrarySubstitutionFunctions<'i>,
516 ) {
517 self.tokenizer
518 .look_for_arbitrary_substitution_functions(fns)
519 }
520
521 #[inline]
524 pub fn seen_arbitrary_substitution_functions(&mut self) -> bool {
525 self.tokenizer.seen_arbitrary_substitution_functions()
526 }
527
528 #[inline]
530 pub fn r#try<F, T, E>(&mut self, thing: F) -> Result<T, E>
531 where
532 F: FnOnce(&mut Parser<'i>) -> Result<T, E>,
533 {
534 self.try_parse(thing)
535 }
536
537 #[inline]
542 pub fn try_parse<F, T, E>(&mut self, thing: F) -> Result<T, E>
543 where
544 F: FnOnce(&mut Parser<'i>) -> Result<T, E>,
545 {
546 let start = self.state();
547 let result = thing(self);
548 if result.is_err() {
549 self.reset(&start)
550 }
551 result
552 }
553
554 #[inline]
556 pub fn slice(&self, range: Range<SourcePosition>) -> &'i str {
557 self.tokenizer.slice(range)
558 }
559
560 #[inline]
562 pub fn slice_from(&self, start_position: SourcePosition) -> &'i str {
563 self.tokenizer.slice_from(start_position)
564 }
565
566 #[allow(clippy::should_implement_trait)]
578 pub fn next(&mut self) -> Result<&Token<'i>, BasicParseError> {
579 self.skip_whitespace();
580 self.next_including_whitespace_and_comments()
581 }
582
583 pub fn next_including_whitespace(&mut self) -> Result<&Token<'i>, BasicParseError> {
585 while let Token::Comment(..) = self.next_including_whitespace_and_comments()? {
586 }
588 Ok(&self.cached_token.token)
589 }
590
591 pub fn next_including_whitespace_and_comments(
598 &mut self,
599 ) -> Result<&Token<'i>, BasicParseError> {
600 if let Some(block_type) = self.at_start_of.take() {
601 consume_until_end_of_block(block_type, &mut self.tokenizer);
602 }
603
604 let Some(byte) = self.tokenizer.next_byte() else {
605 return Err(BasicParseError::new(BasicParseErrorKind::EndOfInput));
606 };
607
608 if self.stop_before.contains(Delimiters::from_byte(byte)) {
609 return Err(BasicParseError::new(BasicParseErrorKind::EndOfInput));
610 }
611
612 let token_start_position = self.tokenizer.position();
613 let using_cached_token = self.cached_token.start_position == token_start_position;
614 let token = if using_cached_token {
615 let cached_token = &self.cached_token;
616 self.tokenizer.reset(&cached_token.end_state);
617 if let Token::Function(ref name) = cached_token.token {
618 self.tokenizer.see_function(name)
619 }
620 &cached_token.token
621 } else {
622 let new_token = self.tokenizer.next_unchecked();
623 self.cached_token = CachedToken {
624 token: new_token,
625 start_position: token_start_position,
626 end_state: self.tokenizer.state(),
627 };
628 &self.cached_token.token
629 };
630
631 if let Some(block_type) = BlockType::opening(token) {
632 self.at_start_of = Some(block_type);
633 }
634 Ok(token)
635 }
636
637 #[inline]
642 pub fn parse_entirely<F, T, E>(&mut self, parse: F) -> Result<T, ParseError<E>>
643 where
644 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
645 {
646 let result = parse(self)?;
647 self.expect_exhausted()?;
648 Ok(result)
649 }
650
651 #[inline]
663 pub fn parse_comma_separated<F, T, E>(&mut self, parse_one: F) -> Result<Vec<T>, ParseError<E>>
664 where
665 F: FnMut(&mut Parser<'i>) -> Result<T, ParseError<E>>,
666 {
667 self.parse_comma_separated_internal(parse_one, false)
668 }
669
670 #[inline]
676 pub fn parse_comma_separated_ignoring_errors<F, T, E>(&mut self, parse_one: F) -> Vec<T>
677 where
678 F: FnMut(&mut Parser<'i>) -> Result<T, ParseError<E>>,
679 {
680 match self.parse_comma_separated_internal(parse_one, true) {
681 Ok(values) => values,
682 Err(..) => unreachable!(),
683 }
684 }
685
686 #[inline]
687 fn parse_comma_separated_internal<F, T, E>(
688 &mut self,
689 mut parse_one: F,
690 ignore_errors: bool,
691 ) -> Result<Vec<T>, ParseError<E>>
692 where
693 F: FnMut(&mut Parser<'i>) -> Result<T, ParseError<E>>,
694 {
695 let mut values = Vec::with_capacity(1);
700 loop {
701 self.skip_whitespace(); match self.parse_until_before(Delimiter::Comma, &mut parse_one) {
703 Ok(v) => values.push(v),
704 Err(e) if !ignore_errors => return Err(e),
705 Err(_) => {}
706 }
707 match self.next() {
708 Err(_) => return Ok(values),
709 Ok(&Token::Comma) => continue,
710 Ok(_) => unreachable!(),
711 }
712 }
713 }
714
715 #[inline]
727 pub fn parse_nested_block<F, T, E>(&mut self, parse: F) -> Result<T, ParseError<E>>
728 where
729 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
730 {
731 parse_nested_block(self, parse)
732 }
733
734 #[inline]
743 pub fn parse_until_before<F, T, E>(
744 &mut self,
745 delimiters: Delimiters,
746 parse: F,
747 ) -> Result<T, ParseError<E>>
748 where
749 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
750 {
751 parse_until_before(self, delimiters, ParseUntilErrorBehavior::Consume, parse)
752 }
753
754 #[inline]
760 pub fn parse_until_after<F, T, E>(
761 &mut self,
762 delimiters: Delimiters,
763 parse: F,
764 ) -> Result<T, ParseError<E>>
765 where
766 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
767 {
768 parse_until_after(self, delimiters, ParseUntilErrorBehavior::Consume, parse)
769 }
770
771 #[inline]
773 pub fn expect_whitespace(&mut self) -> Result<&'i str, BasicParseError> {
774 match *self.next_including_whitespace()? {
775 Token::WhiteSpace(value) => Ok(value),
776 _ => Err(BasicParseError::unexpected_token()),
777 }
778 }
779
780 #[inline]
782 pub fn expect_ident(&mut self) -> Result<&CowRcStr<'i>, BasicParseError> {
783 expect! {self,
784 Token::Ident(ref value) => Ok(value),
785 }
786 }
787
788 #[inline]
790 pub fn expect_ident_cloned(&mut self) -> Result<CowRcStr<'i>, BasicParseError> {
791 self.expect_ident().cloned()
792 }
793
794 #[inline]
796 pub fn expect_ident_matching(&mut self, expected_value: &str) -> Result<(), BasicParseError> {
797 expect! {self,
798 Token::Ident(ref value) if value.eq_ignore_ascii_case(expected_value) => Ok(()),
799 }
800 }
801
802 #[inline]
804 pub fn expect_string(&mut self) -> Result<&CowRcStr<'i>, BasicParseError> {
805 expect! {self,
806 Token::QuotedString(ref value) => Ok(value),
807 }
808 }
809
810 #[inline]
812 pub fn expect_string_cloned(&mut self) -> Result<CowRcStr<'i>, BasicParseError> {
813 self.expect_string().cloned()
814 }
815
816 #[inline]
818 pub fn expect_ident_or_string(&mut self) -> Result<&CowRcStr<'i>, BasicParseError> {
819 expect! {self,
820 Token::Ident(ref value) => Ok(value),
821 Token::QuotedString(ref value) => Ok(value),
822 }
823 }
824
825 #[inline]
827 pub fn expect_url(&mut self) -> Result<CowRcStr<'i>, BasicParseError> {
828 expect! {self,
829 Token::UnquotedUrl(ref value) => Ok(value.clone()),
830 Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
831 self.parse_nested_block(|input| {
832 input.expect_string().map_err(Into::into).cloned()
833 })
834 .map_err(ParseError::<()>::basic)
835 }
836 }
837 }
838
839 #[inline]
841 pub fn expect_url_or_string(&mut self) -> Result<CowRcStr<'i>, BasicParseError> {
842 expect! {self,
843 Token::UnquotedUrl(ref value) => Ok(value.clone()),
844 Token::QuotedString(ref value) => Ok(value.clone()),
845 Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
846 self.parse_nested_block(|input| {
847 input.expect_string().map_err(Into::into).cloned()
848 })
849 .map_err(ParseError::<()>::basic)
850 }
851 }
852 }
853
854 #[inline]
856 pub fn expect_number(&mut self) -> Result<f32, BasicParseError> {
857 expect! {self,
858 Token::Number { value, .. } => Ok(value),
859 }
860 }
861
862 #[inline]
864 pub fn expect_integer(&mut self) -> Result<i32, BasicParseError> {
865 expect! {self,
866 Token::Number { int_value: Some(int_value), .. } => Ok(int_value),
867 }
868 }
869
870 #[inline]
873 pub fn expect_percentage(&mut self) -> Result<f32, BasicParseError> {
874 expect! {self,
875 Token::Percentage { unit_value, .. } => Ok(unit_value),
876 }
877 }
878
879 #[inline]
881 pub fn expect_colon(&mut self) -> Result<(), BasicParseError> {
882 expect! {self,
883 Token::Colon => Ok(()),
884 }
885 }
886
887 #[inline]
889 pub fn expect_semicolon(&mut self) -> Result<(), BasicParseError> {
890 expect! {self,
891 Token::Semicolon => Ok(()),
892 }
893 }
894
895 #[inline]
897 pub fn expect_comma(&mut self) -> Result<(), BasicParseError> {
898 expect! {self,
899 Token::Comma => Ok(()),
900 }
901 }
902
903 #[inline]
905 pub fn expect_delim(&mut self, expected_value: char) -> Result<(), BasicParseError> {
906 expect! {self,
907 Token::Delim(value) if value == expected_value => Ok(()),
908 }
909 }
910
911 #[inline]
915 pub fn expect_curly_bracket_block(&mut self) -> Result<(), BasicParseError> {
916 expect! {self,
917 Token::CurlyBracketBlock => Ok(()),
918 }
919 }
920
921 #[inline]
925 pub fn expect_square_bracket_block(&mut self) -> Result<(), BasicParseError> {
926 expect! {self,
927 Token::SquareBracketBlock => Ok(()),
928 }
929 }
930
931 #[inline]
935 pub fn expect_parenthesis_block(&mut self) -> Result<(), BasicParseError> {
936 expect! {self,
937 Token::ParenthesisBlock => Ok(()),
938 }
939 }
940
941 #[inline]
945 pub fn expect_function(&mut self) -> Result<&CowRcStr<'i>, BasicParseError> {
946 expect! {self,
947 Token::Function(ref name) => Ok(name),
948 }
949 }
950
951 #[inline]
955 pub fn expect_function_matching(&mut self, expected_name: &str) -> Result<(), BasicParseError> {
956 expect! {self,
957 Token::Function(ref name) if name.eq_ignore_ascii_case(expected_name) => Ok(()),
958 }
959 }
960
961 #[inline]
965 pub fn expect_no_error_token(&mut self) -> Result<(), BasicParseError> {
966 loop {
967 match self.next_including_whitespace_and_comments() {
968 Ok(&Token::Function(_))
969 | Ok(&Token::ParenthesisBlock)
970 | Ok(&Token::SquareBracketBlock)
971 | Ok(&Token::CurlyBracketBlock) => self
972 .parse_nested_block(|input| input.expect_no_error_token().map_err(Into::into))
973 .map_err(ParseError::<()>::basic)?,
974 Ok(t) => {
975 if t.is_parse_error() {
978 return Err(BasicParseError::unexpected_token());
979 }
980 }
981 Err(_) => return Ok(()),
982 }
983 }
984 }
985}
986
987pub fn parse_until_before<'i, F, T, E>(
988 parser: &mut Parser<'i>,
989 delimiters: Delimiters,
990 error_behavior: ParseUntilErrorBehavior,
991 parse: F,
992) -> Result<T, ParseError<E>>
993where
994 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
995{
996 let old_stop_before = parser.stop_before;
997 let delimiters = parser.stop_before | delimiters;
998 parser.stop_before = delimiters;
999 let result = parser.parse_entirely(parse);
1000 parser.stop_before = old_stop_before;
1001 if error_behavior == ParseUntilErrorBehavior::Stop && result.is_err() {
1002 return result;
1003 }
1004 if let Some(block_type) = parser.at_start_of.take() {
1005 consume_until_end_of_block(block_type, &mut parser.tokenizer);
1006 }
1007 while let Some(next_byte) = parser.tokenizer.next_byte() {
1009 if delimiters.contains(Delimiters::from_byte(next_byte)) {
1010 break;
1011 }
1012 let token = parser.tokenizer.next_unchecked();
1013 if let Some(block_type) = BlockType::opening(&token) {
1014 consume_until_end_of_block(block_type, &mut parser.tokenizer);
1015 }
1016 }
1017 result
1018}
1019
1020pub fn parse_until_after<'i, F, T, E>(
1021 parser: &mut Parser<'i>,
1022 delimiters: Delimiters,
1023 error_behavior: ParseUntilErrorBehavior,
1024 parse: F,
1025) -> Result<T, ParseError<E>>
1026where
1027 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
1028{
1029 let result = parse_until_before(parser, delimiters, error_behavior, parse);
1030 if error_behavior == ParseUntilErrorBehavior::Stop && result.is_err() {
1031 return result;
1032 }
1033 if let Some(next_byte) = parser.tokenizer.next_byte() {
1034 let delimiter = Delimiters::from_byte(next_byte);
1035 if !parser.stop_before.contains(delimiter) {
1036 debug_assert!(delimiters.contains(delimiter));
1037 parser.tokenizer.advance(1);
1039 if next_byte == b'{' {
1040 consume_until_end_of_block(BlockType::CurlyBracket, &mut parser.tokenizer);
1041 }
1042 }
1043 }
1044 result
1045}
1046
1047pub fn parse_nested_block<'i, F, T, E>(
1048 parser: &mut Parser<'i>,
1049 parse: F,
1050) -> Result<T, ParseError<E>>
1051where
1052 F: FnOnce(&mut Parser<'i>) -> Result<T, ParseError<E>>,
1053{
1054 let block_type = parser.at_start_of.take().expect(
1055 "\
1056 A nested parser can only be created when a Function, \
1057 ParenthesisBlock, SquareBracketBlock, or CurlyBracketBlock \
1058 token was just consumed.\
1059 ",
1060 );
1061 if parser.current_block_depth >= parser.nested_block_limit && parser.nested_block_limit != 0 {
1062 return Err(ParseError::from_basic_kind(
1063 BasicParseErrorKind::TooManyNestedBlocks,
1064 ));
1065 }
1066 parser.current_block_depth = parser.current_block_depth.wrapping_add(1);
1068
1069 let old_stop_before = parser.stop_before;
1070 parser.stop_before = match block_type {
1071 BlockType::CurlyBracket => ClosingDelimiter::CloseCurlyBracket,
1072 BlockType::SquareBracket => ClosingDelimiter::CloseSquareBracket,
1073 BlockType::Parenthesis => ClosingDelimiter::CloseParenthesis,
1074 };
1075 let result = parser.parse_entirely(parse);
1076 if let Some(nested_block_type) = parser.at_start_of.take() {
1077 consume_until_end_of_block(nested_block_type, &mut parser.tokenizer);
1078 }
1079 consume_until_end_of_block(block_type, &mut parser.tokenizer);
1080 parser.stop_before = old_stop_before;
1081 parser.current_block_depth = parser.current_block_depth.wrapping_sub(1);
1082 result
1083}
1084
1085#[inline(never)]
1086#[cold]
1087fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer) {
1088 let mut stack = SmallVec::<[BlockType; 16]>::new();
1089 stack.push(block_type);
1090
1091 while let Ok(ref token) = tokenizer.next() {
1093 if let Some(b) = BlockType::closing(token) {
1094 if *stack.last().unwrap() == b {
1095 stack.pop();
1096 if stack.is_empty() {
1097 return;
1098 }
1099 }
1100 }
1101
1102 if let Some(block_type) = BlockType::opening(token) {
1103 stack.push(block_type);
1104 }
1105 }
1106}