Use checked str
slices in Rgba::TryFrom<str>
(#12097)
Release Notes: - N/A --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
parent
70e8737918
commit
d116f3c292
1 changed files with 59 additions and 9 deletions
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::bail;
|
use anyhow::{bail, Context};
|
||||||
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ impl TryFrom<&'_ str> for Rgba {
|
||||||
const RRGGBBAA: usize = "rrggbbaa".len();
|
const RRGGBBAA: usize = "rrggbbaa".len();
|
||||||
|
|
||||||
const EXPECTED_FORMATS: &str = "Expected #rgb, #rgba, #rrggbb, or #rrggbbaa";
|
const EXPECTED_FORMATS: &str = "Expected #rgb, #rgba, #rrggbb, or #rrggbbaa";
|
||||||
|
const INVALID_UNICODE: &str = "invalid unicode characters in color";
|
||||||
|
|
||||||
let Some(("", hex)) = value.trim().split_once('#') else {
|
let Some(("", hex)) = value.trim().split_once('#') else {
|
||||||
bail!("invalid RGBA hex color: '{value}'. {EXPECTED_FORMATS}");
|
bail!("invalid RGBA hex color: '{value}'. {EXPECTED_FORMATS}");
|
||||||
|
@ -133,11 +134,31 @@ impl TryFrom<&'_ str> for Rgba {
|
||||||
|
|
||||||
let (r, g, b, a) = match hex.len() {
|
let (r, g, b, a) = match hex.len() {
|
||||||
RGB | RGBA => {
|
RGB | RGBA => {
|
||||||
let r = u8::from_str_radix(&hex[0..1], 16)?;
|
let r = u8::from_str_radix(
|
||||||
let g = u8::from_str_radix(&hex[1..2], 16)?;
|
hex.get(0..1).with_context(|| {
|
||||||
let b = u8::from_str_radix(&hex[2..3], 16)?;
|
format!("{INVALID_UNICODE}: r component of #rgb/#rgba for value: '{value}'")
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
|
let g = u8::from_str_radix(
|
||||||
|
hex.get(1..2).with_context(|| {
|
||||||
|
format!("{INVALID_UNICODE}: g component of #rgb/#rgba for value: '{value}'")
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
|
let b = u8::from_str_radix(
|
||||||
|
hex.get(2..3).with_context(|| {
|
||||||
|
format!("{INVALID_UNICODE}: b component of #rgb/#rgba for value: '{value}'")
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
let a = if hex.len() == RGBA {
|
let a = if hex.len() == RGBA {
|
||||||
u8::from_str_radix(&hex[3..4], 16)?
|
u8::from_str_radix(
|
||||||
|
hex.get(3..4).with_context(|| {
|
||||||
|
format!("{INVALID_UNICODE}: a component of #rgba for value: '{value}'")
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
0xf
|
0xf
|
||||||
};
|
};
|
||||||
|
@ -151,11 +172,40 @@ impl TryFrom<&'_ str> for Rgba {
|
||||||
(duplicate(r), duplicate(g), duplicate(b), duplicate(a))
|
(duplicate(r), duplicate(g), duplicate(b), duplicate(a))
|
||||||
}
|
}
|
||||||
RRGGBB | RRGGBBAA => {
|
RRGGBB | RRGGBBAA => {
|
||||||
let r = u8::from_str_radix(&hex[0..2], 16)?;
|
let r = u8::from_str_radix(
|
||||||
let g = u8::from_str_radix(&hex[2..4], 16)?;
|
hex.get(0..2).with_context(|| {
|
||||||
let b = u8::from_str_radix(&hex[4..6], 16)?;
|
format!(
|
||||||
|
"{}: r component of #rrggbb/#rrggbbaa for value: '{}'",
|
||||||
|
INVALID_UNICODE, value
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
|
let g = u8::from_str_radix(
|
||||||
|
hex.get(2..4).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"{INVALID_UNICODE}: g component of #rrggbb/#rrggbbaa for value: '{value}'"
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
|
let b = u8::from_str_radix(
|
||||||
|
hex.get(4..6).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"{INVALID_UNICODE}: b component of #rrggbb/#rrggbbaa for value: '{value}'"
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?;
|
||||||
let a = if hex.len() == RRGGBBAA {
|
let a = if hex.len() == RRGGBBAA {
|
||||||
u8::from_str_radix(&hex[6..8], 16)?
|
u8::from_str_radix(
|
||||||
|
hex.get(6..8).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"{INVALID_UNICODE}: a component of #rrggbbaa for value: '{value}'"
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
16,
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
0xff
|
0xff
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue