further refactor parsing of hex colors

This commit is contained in:
ConnorSkees 2020-06-17 06:25:38 -04:00
parent 00bd9f3847
commit 042935f362
2 changed files with 31 additions and 19 deletions

View File

@ -526,41 +526,38 @@ impl<'a> Parser<'a> {
}
fn parse_hex(&mut self) -> SassResult<Spanned<Value>> {
let mut s = String::with_capacity(8);
let mut s = String::with_capacity(7);
s.push('#');
if self
.toks
.peek()
.ok_or(("Expected identifier.", self.span_before))?
.kind
.is_ascii_digit()
.is_ascii_hexdigit()
{
while let Some(c) = self.toks.peek() {
if !c.kind.is_ascii_hexdigit() || s.len() == 8 {
if !c.kind.is_ascii_hexdigit() {
break;
}
let tok = self.toks.next().unwrap();
self.span_before = self.span_before.merge(tok.pos());
s.push(tok.kind);
}
// this branch exists so that we can emit `#` combined with
// identifiers. e.g. `#ooobar` should be emitted exactly as written;
// that is, `#ooobar`.
} else {
let i = self.parse_identifier()?;
if i.node.chars().all(|c| c.is_ascii_hexdigit()) {
s = i.node;
self.span_before = self.span_before.merge(i.span);
} else {
return Ok(Spanned {
node: Value::String(format!("#{}", i.node), QuoteKind::None),
span: i.span,
});
}
let ident = self.parse_identifier()?;
return Ok(Spanned {
node: Value::String(format!("#{}", ident.node), QuoteKind::None),
span: ident.span,
});
}
let v = match u32::from_str_radix(&s, 16) {
let v = match u32::from_str_radix(&s[1..], 16) {
Ok(a) => a,
Err(_) => {
return Ok(Value::String(format!("#{}", s), QuoteKind::None).span(self.span_before))
}
Err(_) => return Ok(Value::String(s, QuoteKind::None).span(self.span_before)),
};
let (red, green, blue, alpha) = match s.len() {
let (red, green, blue, alpha) = match s.len().saturating_sub(1) {
3 => (
(((v & 0x0f00) >> 8) * 0x11) as u8,
(((v & 0x00f0) >> 4) * 0x11) as u8,
@ -587,7 +584,7 @@ impl<'a> Parser<'a> {
),
_ => return Err(("Expected hex digit.", self.span_before).into()),
};
let color = Color::new(red, green, blue, alpha, format!("#{}", s));
let color = Color::new(red, green, blue, alpha, s);
Ok(Value::Color(Box::new(color)).span(self.span_before))
}

View File

@ -582,3 +582,18 @@ test!(
"a {\n color: hsl(-1 -1 -1);\n}\n",
"a {\n color: black;\n}\n"
);
test!(
interpolation_after_hash_containing_only_hex_chars,
"a {\n color: ##{123};\n color: type-of(##{123});\n}\n",
"a {\n color: #123;\n color: string;\n}\n"
);
test!(
non_hex_chars_after_hash_are_still_touching_hash,
"a {\n color: #ooobar;\n}\n",
"a {\n color: #ooobar;\n}\n"
);
test!(
more_than_8_hex_chars_after_hash,
"a {\n color: #ffffffffff;\n}\n",
"a {\n color: #ffffffffff;\n}\n"
);