mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-15 22:44:01 +00:00
Optimize color::try_parse_rgb()
The function was repeatedly calling `s.char_at(n)` which is O(1) only for UTF-32 strings (so not a problem at the moment). But it was also calling `hex_digit(n)` twice for each `n` in the 3-digit case, causing unnecessary repeated parsing of individual characters into their radix-16 numeric equivalents, which could be avoided just by reusing the already calculated result.
This commit is contained in:
parent
ebbba10608
commit
5b79f267d6
1 changed files with 21 additions and 19 deletions
40
src/color.rs
40
src/color.rs
|
@ -257,34 +257,36 @@ impl RgbColor {
|
|||
/// - `FA3`
|
||||
/// - `F3A035`
|
||||
|
||||
/// Parses input in the form of `#RGB` or `#RRGGBB` with an optional single leading `#` into
|
||||
/// an instance of [`RgbColor`].
|
||||
///
|
||||
/// Returns `None` if the input contains invalid hexadecimal characters or is not in the
|
||||
/// expected `#RGB` or `#RRGGBB` formats.
|
||||
fn try_parse_rgb(mut s: &wstr) -> Option<Self> {
|
||||
// Skip any leading #.
|
||||
// Skip one leading #
|
||||
if s.chars().next()? == '#' {
|
||||
s = &s[1..];
|
||||
}
|
||||
|
||||
let hex_digit = |i| -> Option<u8> {
|
||||
s.char_at(i)
|
||||
.to_digit(16)
|
||||
.map(|n| n.try_into().expect("hex digit should always be < 256"))
|
||||
};
|
||||
let mut hex = s.chars().map_while(|c| c.to_digit(16).map(|b| b as u8));
|
||||
|
||||
let r;
|
||||
let g;
|
||||
let b;
|
||||
if s.len() == 3 {
|
||||
// Format: FA3
|
||||
r = hex_digit(0)? * 16 + hex_digit(0)?;
|
||||
g = hex_digit(1)? * 16 + hex_digit(1)?;
|
||||
b = hex_digit(2)? * 16 + hex_digit(2)?;
|
||||
let (r, g, b) = if s.len() == 3 {
|
||||
// Expected format: FA3
|
||||
(
|
||||
hex.next().map(|d| d * 16 + d)?,
|
||||
hex.next().map(|d| d * 16 + d)?,
|
||||
hex.next().map(|d| d * 16 + d)?,
|
||||
)
|
||||
} else if s.len() == 6 {
|
||||
// Format: F3A035
|
||||
r = hex_digit(0)? * 16 + hex_digit(1)?;
|
||||
g = hex_digit(2)? * 16 + hex_digit(3)?;
|
||||
b = hex_digit(4)? * 16 + hex_digit(5)?;
|
||||
// Expected format: F3A035
|
||||
(
|
||||
hex.next()? * 16 + hex.next()?,
|
||||
hex.next()? * 16 + hex.next()?,
|
||||
hex.next()? * 16 + hex.next()?,
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(RgbColor::from_rgb(r, g, b))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue