mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add tests for Color::parse
This commit is contained in:
parent
45a9d54801
commit
29f85a4398
@ -155,14 +155,14 @@ impl Color {
|
||||
/// * `"#123456"` becomes `Color::Rgb(0x12, 0x34, 0x56)`
|
||||
pub fn parse(value: &str) -> Option<Self> {
|
||||
Some(match value {
|
||||
"black" => Color::Dark(BaseColor::Black),
|
||||
"red" => Color::Dark(BaseColor::Red),
|
||||
"green" => Color::Dark(BaseColor::Green),
|
||||
"yellow" => Color::Dark(BaseColor::Yellow),
|
||||
"blue" => Color::Dark(BaseColor::Blue),
|
||||
"magenta" => Color::Dark(BaseColor::Magenta),
|
||||
"cyan" => Color::Dark(BaseColor::Cyan),
|
||||
"white" => Color::Dark(BaseColor::White),
|
||||
"dark black" | "black" => Color::Dark(BaseColor::Black),
|
||||
"dark red" | "red" => Color::Dark(BaseColor::Red),
|
||||
"dark green" | "green" => Color::Dark(BaseColor::Green),
|
||||
"dark yellow" | "yellow" => Color::Dark(BaseColor::Yellow),
|
||||
"dark blue" | "blue" => Color::Dark(BaseColor::Blue),
|
||||
"dark magenta" | "magenta" => Color::Dark(BaseColor::Magenta),
|
||||
"dark cyan" | "cyan" => Color::Dark(BaseColor::Cyan),
|
||||
"dark white" | "white" => Color::Dark(BaseColor::White),
|
||||
"light black" => Color::Light(BaseColor::Black),
|
||||
"light red" => Color::Light(BaseColor::Red),
|
||||
"light green" => Color::Light(BaseColor::Green),
|
||||
@ -172,73 +172,136 @@ impl Color {
|
||||
"light cyan" => Color::Light(BaseColor::Cyan),
|
||||
"light white" => Color::Light(BaseColor::White),
|
||||
"default" => Color::TerminalDefault,
|
||||
value => return Color::parse_special(value),
|
||||
value => {
|
||||
return parse_special(value).or_else(|| {
|
||||
log::warn!("Could not parse color `{}`.", value);
|
||||
None
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_special(value: &str) -> Option<Color> {
|
||||
if value.starts_with('#') {
|
||||
let value = &value[1..];
|
||||
// Compute per-color length, and amplitude
|
||||
let (l, multiplier) = match value.len() {
|
||||
6 => (2, 1),
|
||||
3 => (1, 17),
|
||||
_ => panic!("Cannot parse color: {}", value),
|
||||
};
|
||||
let r = load_hex(&value[0..l]) * multiplier;
|
||||
let g = load_hex(&value[l..2 * l]) * multiplier;
|
||||
let b = load_hex(&value[2 * l..3 * l]) * multiplier;
|
||||
fn parse_special(value: &str) -> Option<Color> {
|
||||
if value.starts_with('#') {
|
||||
parse_hex(&value[1..])
|
||||
} else if value.starts_with("0x") {
|
||||
parse_hex(&value[2..])
|
||||
} else if value.len() == 6 {
|
||||
parse_hex(value)
|
||||
} else if value.len() == 3 {
|
||||
// RGB values between 0 and 5 maybe?
|
||||
// Like 050 for green
|
||||
let rgb: Vec<_> =
|
||||
value.chars().map(|c| c as i16 - '0' as i16).collect();
|
||||
|
||||
Some(Color::Rgb(r as u8, g as u8, b as u8))
|
||||
} else if value.len() == 3 {
|
||||
// RGB values between 0 and 5 maybe?
|
||||
// Like 050 for green
|
||||
let rgb: Vec<_> =
|
||||
value.chars().map(|c| c as i16 - '0' as i16).collect();
|
||||
|
||||
assert_eq!(rgb.len(), 3);
|
||||
if rgb.iter().all(|&i| i >= 0 && i < 6) {
|
||||
Some(Color::RgbLowRes(
|
||||
rgb[0] as u8,
|
||||
rgb[1] as u8,
|
||||
rgb[2] as u8,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
assert_eq!(rgb.len(), 3);
|
||||
if rgb.iter().all(|&i| i >= 0 && i < 6) {
|
||||
Some(Color::RgbLowRes(rgb[0] as u8, rgb[1] as u8, rgb[2] as u8))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_hex(value: &str) -> Option<Color> {
|
||||
// Compute per-color length, and amplitude
|
||||
let (l, multiplier) = match value.len() {
|
||||
6 => (2, 1),
|
||||
3 => (1, 17),
|
||||
_ => return None,
|
||||
};
|
||||
let r = load_hex(&value[0..l]) * multiplier;
|
||||
let g = load_hex(&value[l..2 * l]) * multiplier;
|
||||
let b = load_hex(&value[2 * l..3 * l]) * multiplier;
|
||||
|
||||
Some(Color::Rgb(r as u8, g as u8, b as u8))
|
||||
}
|
||||
|
||||
/// Loads a hexadecimal code
|
||||
fn load_hex(s: &str) -> u16 {
|
||||
let mut sum = 0;
|
||||
for c in s.chars() {
|
||||
sum *= 16;
|
||||
sum += match c {
|
||||
n @ '0'..='9' => n as i16 - '0' as i16,
|
||||
n @ 'a'..='f' => n as i16 - 'a' as i16 + 10,
|
||||
n @ 'A'..='F' => n as i16 - 'A' as i16 + 10,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
|
||||
sum as u16
|
||||
s.chars()
|
||||
.rev()
|
||||
.filter_map(|c| {
|
||||
Some(match c {
|
||||
'0'..='9' => c as u16 - '0' as u16,
|
||||
'a'..='f' => c as u16 - 'a' as u16 + 10,
|
||||
'A'..='F' => c as u16 - 'A' as u16 + 10,
|
||||
other => {
|
||||
log::warn!(
|
||||
"Invalid character `{}` in hexadecimal value `{}`.",
|
||||
other,
|
||||
s
|
||||
);
|
||||
return None;
|
||||
}
|
||||
})
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(i, c)| c * 16u16.pow(i as u32))
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Color;
|
||||
|
||||
#[test]
|
||||
fn test_256_colors() {
|
||||
// Make sure Color::from_256colors never panics
|
||||
use super::Color;
|
||||
|
||||
// TODO: use inclusive range when it gets stable
|
||||
for i in 0..256u16 {
|
||||
Color::from_256colors(i as u8);
|
||||
for i in 0..=255u8 {
|
||||
Color::from_256colors(i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
assert_eq!(Color::parse("#fff"), Some(Color::Rgb(255, 255, 255)));
|
||||
|
||||
assert_eq!(
|
||||
Color::parse("#abcdef"),
|
||||
Some(Color::Rgb(0xab, 0xcd, 0xef))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Color::parse("0xFEDCBA"),
|
||||
Some(Color::Rgb(0xfe, 0xdc, 0xba))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_low_res() {
|
||||
// Make sure Color::low_res always works with valid ranges.
|
||||
for r in 0..=5 {
|
||||
for g in 0..=5 {
|
||||
for b in 0..=5 {
|
||||
assert!(
|
||||
Color::low_res(r, g, b).is_some(),
|
||||
"Could not create lowres color {}:{}:{}",
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for r in 6..=10 {
|
||||
for g in 6..=10 {
|
||||
for b in 6..=10 {
|
||||
assert_eq!(
|
||||
Color::low_res(r, g, b),
|
||||
None,
|
||||
"Created invalid lowres color {}:{}:{}",
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user