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
use peekmore::PeekMoreIterator;

use crate::{error::SassResult, Token};

use super::{read_until_closing_paren, read_until_closing_quote};
/// Reads until the char is found, consuming the char,
/// or until the end of the iterator is hit
pub(crate) fn read_until_char<I: Iterator<Item = Token>>(
    toks: &mut PeekMoreIterator<I>,
    c: char,
) -> SassResult<Vec<Token>> {
    let mut v = Vec::new();
    while let Some(tok) = toks.next() {
        match tok.kind {
            '"' | '\'' => {
                v.push(tok);
                v.extend(read_until_closing_quote(toks, tok.kind)?);
                continue;
            }
            '(' => {
                v.push(tok);
                v.extend(read_until_closing_paren(toks)?);
                continue;
            }
            t if t == c => break,
            _ => {}
        }
        v.push(tok)
    }
    Ok(v)
}

pub(crate) fn hex_char_for(number: u32) -> char {
    debug_assert!(number < 0x10);
    std::char::from_u32(if number < 0xA {
        0x30 + number
    } else {
        0x61 - 0xA + number
    })
    .unwrap()
}

pub(crate) fn is_name(c: char) -> bool {
    is_name_start(c) || c.is_ascii_digit() || c == '-'
}

pub(crate) fn is_name_start(c: char) -> bool {
    // NOTE: in the dart-sass implementation, identifiers cannot start
    // with numbers. We explicitly differentiate from the reference
    // implementation here in order to support selectors beginning with numbers.
    // This can be considered a hack and in the future it would be nice to refactor
    // how this is handled.
    c == '_' || c.is_alphanumeric() || c as u32 >= 0x0080
}

pub(crate) fn as_hex(c: char) -> u32 {
    match c {
        '0'..='9' => c as u32 - '0' as u32,
        'A'..='F' => 10 + c as u32 - 'A' as u32,
        'a'..='f' => 10 + c as u32 - 'a' as u32,
        _ => panic!(),
    }
}