MCPcopy Create free account
hub / github.com/csskit/csskit / parse

Method parse

crates/css_lexer/src/source_cursor.rs:566–651  ·  view source on GitHub ↗

Parse the cursor's content using any allocator that implements the Allocator trait.

(&self, allocator: A)

Source from the content-addressed store, hash-verified

564
565 /// Parse the cursor's content using any allocator that implements the Allocator trait.
566 pub fn parse<A: Allocator + Clone + 'a>(&self, allocator: A) -> CowStr<'a, A> {
567 debug_assert!(self.token() != Kind::Delim);
568 let start = self.token().leading_len() as usize;
569 let end = self.source.len() - self.token().trailing_len() as usize;
570 if !self.token().contains_escape_chars() {
571 return CowStr::<A>::Borrowed(&self.source[start..end]);
572 }
573 let mut chars = self.source[start..end].chars().peekable();
574 let mut i = 0;
575 let mut vec: Option<Vec<u8, A>> = None;
576 while let Some(c) = chars.next() {
577 if c == '\0' {
578 if vec.is_none() {
579 vec = if i == 0 {
580 Some(Vec::new_in(allocator.clone()))
581 } else {
582 Some({
583 let mut v = Vec::new_in(allocator.clone());
584 v.extend(self.source[start..(start + i)].bytes());
585 v
586 })
587 }
588 }
589 let mut buf = [0; 4];
590 let bytes = REPLACEMENT_CHARACTER.encode_utf8(&mut buf).as_bytes();
591 vec.as_mut().unwrap().extend_from_slice(bytes);
592 i += 1;
593 } else if c == '\\' {
594 if vec.is_none() {
595 vec = if i == 0 {
596 Some(Vec::new_in(allocator.clone()))
597 } else {
598 Some({
599 let mut v = Vec::new_in(allocator.clone());
600 v.extend(self.source[start..(start + i)].bytes());
601 v
602 })
603 }
604 }
605 // String has special rules
606 // https://drafts.csswg.org/css-syntax-3/#consume-string-cursor
607 if self.token().kind_bits() == Kind::String as u8 {
608 // When the token is a string, escaped EOF points are not consumed
609 // U+005C REVERSE SOLIDUS (\)
610 // If the next input code point is EOF, do nothing.
611 // Otherwise, if the next input code point is a newline, consume it.
612 let c = chars.peek();
613 if let Some(c) = c {
614 if is_newline(*c) {
615 chars.next();
616 if chars.peek() == Some(&'\n') {
617 i += 1;
618 }
619 i += 2;
620 chars = self.source[(start + i)..end].chars().peekable();
621 continue;
622 }
623 } else {

Callers 1

convert_tokenFunction · 0.45

Calls 11

is_newlineFunction · 0.85
leading_lenMethod · 0.80
trailing_lenMethod · 0.80
contains_escape_charsMethod · 0.80
cloneMethod · 0.80
kind_bitsMethod · 0.80
tokenMethod · 0.45
lenMethod · 0.45
nextMethod · 0.45
peekMethod · 0.45
parse_escape_sequenceMethod · 0.45

Tested by 1

convert_tokenFunction · 0.36