Skip to content

Commit

Permalink
Avoid small allocations when parsing short hex format
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
goto-bus-stop committed Jan 4, 2024
1 parent 6501cbb commit 5664355
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,16 +349,19 @@ fn parse_hex(s: &str) -> Result<Color, ParseColorError> {

let n = s.len();

fn parse_single_digit(digit: &str) -> Result<u8, ParseColorError> {
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
};
Expand Down

0 comments on commit 5664355

Please sign in to comment.