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`
|
/// - `FA3`
|
||||||
/// - `F3A035`
|
/// - `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> {
|
fn try_parse_rgb(mut s: &wstr) -> Option<Self> {
|
||||||
// Skip any leading #.
|
// Skip one leading #
|
||||||
if s.chars().next()? == '#' {
|
if s.chars().next()? == '#' {
|
||||||
s = &s[1..];
|
s = &s[1..];
|
||||||
}
|
}
|
||||||
|
|
||||||
let hex_digit = |i| -> Option<u8> {
|
let mut hex = s.chars().map_while(|c| c.to_digit(16).map(|b| b as u8));
|
||||||
s.char_at(i)
|
|
||||||
.to_digit(16)
|
|
||||||
.map(|n| n.try_into().expect("hex digit should always be < 256"))
|
|
||||||
};
|
|
||||||
|
|
||||||
let r;
|
let (r, g, b) = if s.len() == 3 {
|
||||||
let g;
|
// Expected format: FA3
|
||||||
let b;
|
(
|
||||||
if s.len() == 3 {
|
hex.next().map(|d| d * 16 + d)?,
|
||||||
// Format: FA3
|
hex.next().map(|d| d * 16 + d)?,
|
||||||
r = hex_digit(0)? * 16 + hex_digit(0)?;
|
hex.next().map(|d| d * 16 + d)?,
|
||||||
g = hex_digit(1)? * 16 + hex_digit(1)?;
|
)
|
||||||
b = hex_digit(2)? * 16 + hex_digit(2)?;
|
|
||||||
} else if s.len() == 6 {
|
} else if s.len() == 6 {
|
||||||
// Format: F3A035
|
// Expected format: F3A035
|
||||||
r = hex_digit(0)? * 16 + hex_digit(1)?;
|
(
|
||||||
g = hex_digit(2)? * 16 + hex_digit(3)?;
|
hex.next()? * 16 + hex.next()?,
|
||||||
b = hex_digit(4)? * 16 + hex_digit(5)?;
|
hex.next()? * 16 + hex.next()?,
|
||||||
|
hex.next()? * 16 + hex.next()?,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
};
|
||||||
Some(RgbColor::from_rgb(r, g, b))
|
Some(RgbColor::from_rgb(r, g, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue