From 5664355bd6a550f744d3077d5c6ba583685ca508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Thu, 4 Jan 2024 19:32:06 +0100 Subject: [PATCH] Avoid small allocations when parsing short hex format The `.repeat()` calls allocate a `String`, instead it's possible to parse the single digit into an `u8` and then repeat the hex value with bitwise operations. --- src/parser/mod.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 0d1c2da..9c59a14 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -349,16 +349,19 @@ fn parse_hex(s: &str) -> Result { let n = s.len(); + fn parse_single_digit(digit: &str) -> Result { + u8::from_str_radix(digit, 16) + .map(|n| (n << 4) | n) + .map_err(|_| ParseColorError::InvalidHex) + } + if n == 3 || n == 4 { - let r = - u8::from_str_radix(&s[0..1].repeat(2), 16).map_err(|_| ParseColorError::InvalidHex)?; - let g = - u8::from_str_radix(&s[1..2].repeat(2), 16).map_err(|_| ParseColorError::InvalidHex)?; - let b = - u8::from_str_radix(&s[2..3].repeat(2), 16).map_err(|_| ParseColorError::InvalidHex)?; + let r = parse_single_digit(&s[0..1])?; + let g = parse_single_digit(&s[1..2])?; + let b = parse_single_digit(&s[2..3])?; let a = if n == 4 { - u8::from_str_radix(&s[3..4].repeat(2), 16).map_err(|_| ParseColorError::InvalidHex)? + parse_single_digit(&s[3..4])? } else { 255 };