Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ println!("{}", "Back to plain text".red().bold().clear());

- RGB values must be in range 0-255 (enforced at compile time via `u8` type)
- Attempting to use RGB values > 255 will result in a compile error
- Hex color codes can be provided with or without the '#' prefix
- Hex color codes can be provided with or without the '#' prefix in either
3-character shorthand or 6-character full form
- Invalid hex codes (wrong length, invalid characters) will result in plain
unstyled text
- All color methods are guaranteed to return a valid string, never panicking
Expand All @@ -153,10 +154,11 @@ println!("{}", "Gray".hsl(0.0, 0.0, 50.0)); // 50% gray
// Hex colors work with or without #
println!("{}", "Hex color".hex("#ff8000"));
println!("{}", "Also valid".hex("ff8000"));
println!("{}", "Shorthand".hex("#f80"));

// Invalid hex codes return uncolored text
println!("{}", "Invalid".hex("xyz")); // Returns uncolored text
println!("{}", "Too short".hex("#f8")); // Returns uncolored text
println!("{}", "Wrong length".hex("#1234")); // Returns uncolored text
```

## NO_COLOR Support
Expand Down
2 changes: 0 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@

- Revisit whether to add `rust-version` to `Cargo.toml` once we want to commit
to an explicit MSRV policy.
- Support 3-character shorthand hex colors like `#f80` in addition to 6-digit
hex input.
3 changes: 3 additions & 0 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ fn main() {
println!("{}", "HSL Background".on_hsl(200.0, 100.0, 50.0));

println!("{}", "Hex color (#ff8000)".hex("#ff8000"));
println!("{}", "Hex without # (ff8000)".hex("ff8000"));
println!("{}", "Hex shorthand (#f80)".hex("#f80"));
println!("{}", "Hex shorthand without # (f80)".hex("f80"));
println!("{}", "Hex background (#0080ff)".on_hex("#0080ff"));

// Chaining styles
Expand Down
21 changes: 15 additions & 6 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,22 @@ pub(crate) fn hsl_to_rgb(h: f32, s: f32, l: f32) -> (u8, u8, u8) {

pub(crate) fn hex_to_rgb(hex: &str) -> Option<(u8, u8, u8)> {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return None;
}
let expanded = match hex.len() {
3 => {
let mut expanded = String::with_capacity(6);
for ch in hex.chars() {
expanded.push(ch);
expanded.push(ch);
}
expanded
}
6 => hex.to_string(),
_ => return None,
};

let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
let r = u8::from_str_radix(&expanded[0..2], 16).ok()?;
let g = u8::from_str_radix(&expanded[2..4], 16).ok()?;
let b = u8::from_str_radix(&expanded[4..6], 16).ok()?;

Some((r, g, b))
}
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
//!
//! - RGB values must be in range 0-255 (enforced at compile time via `u8` type)
//! - Attempting to use RGB values > 255 will result in a compile error
//! - Hex color codes can be provided with or without the `#` prefix
//! - Hex color codes can be provided with or without the `#` prefix in 3-digit
//! shorthand or 6-digit full form
//! - Invalid hex codes (wrong length or invalid characters) return plain
//! unstyled text
//! - All color methods are guaranteed to return a valid string, never panicking
Expand All @@ -59,10 +60,11 @@
//! // Valid hex codes (with or without #)
//! println!("{}", "Valid hex".hex("#ff8000"));
//! println!("{}", "Also valid".hex("ff8000"));
//! println!("{}", "Shorthand".hex("#f80"));
//!
//! // Invalid hex codes return plain text
//! println!("{}", "Invalid hex".hex("xyz")); // Returns plain text
//! println!("{}", "Too short".hex("#f8")); // Returns plain text
//! println!("{}", "Wrong length".hex("#1234")); // Returns plain text
//! ```
//!
//! # Runtime Color Control
Expand Down
4 changes: 4 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ fn test_rgb_colors(#[case] r: u8, #[case] g: u8, #[case] b: u8) {

#[rstest]
#[case("#ff8000", 255, 128, 0)]
#[case("#f80", 255, 136, 0)]
#[case("#00ff00", 0, 255, 0)]
#[case("0f8", 0, 255, 136)]
#[case("#808080", 128, 128, 128)]
#[case("#000000", 0, 0, 0)]
#[case("#ffffff", 255, 255, 255)]
Expand Down Expand Up @@ -224,6 +226,8 @@ fn test_hex_colors(#[case] hex: &str, #[case] r: u8, #[case] g: u8, #[case] b: u
#[rstest]
#[case("invalid")]
#[case("#12")]
#[case("#1234")]
#[case("#12345678")]
#[case("not-a-color")]
#[case("#12345")]
#[case("#1234567")]
Expand Down
Loading