improve hex parser for text protocol

This commit is contained in:
Noa Aarts 2024-10-06 23:11:26 +02:00
parent bed946b4a0
commit 0978664188
Signed by: noa
GPG key ID: 1850932741EFF672
4 changed files with 45 additions and 16 deletions

7
Cargo.lock generated
View file

@ -108,7 +108,6 @@ dependencies = [
"async-trait",
"atoi_radix10",
"bytes",
"hex",
"tokio",
"tokio-test",
]
@ -131,12 +130,6 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "libc"
version = "0.2.155"

View file

@ -7,7 +7,6 @@ edition = "2021"
async-trait = "0.1.83"
atoi_radix10 = "0.0.1"
bytes = "1.6.0"
hex = "0.4.3"
tokio = { version = "1.38", features = ["full"] }
tokio-test = "*"

View file

@ -1,5 +1,6 @@
#![feature(test)]
#![feature(sync_unsafe_cell)]
#![feature(if_let_guard)]
mod binary_protocol;
mod grid;

View file

@ -20,16 +20,46 @@ fn parse_coordinate(string: &str) -> io::Result<Coordinate> {
}
}
fn parse_color(color: &str) -> io::Result<Color> {
if let Ok(bytes) = hex::decode(color) {
match bytes.len() {
1 => return Ok(Color::W8(bytes[0])),
3 => return Ok(Color::RGB24(bytes[0], bytes[1], bytes[2])),
4 => return Ok(Color::RGBA32(bytes[0], bytes[1], bytes[2], bytes[3])),
type HexChar = u8;
fn val(c1: u8, c2: u8) -> io::Result<HexChar> {
Ok((match c1 {
b'A'..=b'F' => c1 - b'A' + 10,
b'a'..=b'f' => c1 - b'a' + 10,
b'0'..=b'9' => c1 - b'0',
_ => return Err(Error::from(ErrorKind::InvalidInput)),
}) << 4
| (match c2 {
b'A'..=b'F' => c2 - b'A' + 10,
b'a'..=b'f' => c2 - b'a' + 10,
b'0'..=b'9' => c2 - b'0',
_ => return Err(Error::from(ErrorKind::InvalidInput)),
}))
}
fn parse_color(color: &str) -> io::Result<Color> {
let color = color.as_bytes();
match color.len() {
2 if let Ok(w) = val(color[0], color[1]) => Ok(Color::W8(w)),
6 if let (Ok(r), Ok(g), Ok(b)) = (
val(color[0], color[1]),
val(color[2], color[3]),
val(color[4], color[5]),
) =>
{
Ok(Color::RGB24(r, g, b))
}
8 if let (Ok(r), Ok(g), Ok(b), Ok(a)) = (
val(color[0], color[1]),
val(color[2], color[3]),
val(color[4], color[5]),
val(color[6], color[7]),
) =>
{
Ok(Color::RGBA32(r, g, b, a))
}
_ => Err(Error::from(ErrorKind::InvalidInput)),
}
Err(Error::from(ErrorKind::InvalidInput))
}
impl TextParser {
@ -117,7 +147,13 @@ impl<W: AsyncWriteExt + std::marker::Unpin> Responder<W> for TextParser {
Response::Size(x, y) => writer.write_all(format!("SIZE {x} {y}\n").as_bytes()).await,
Response::GetPixel(x, y, color) => {
writer
.write_all(format!("PX {x} {y} {}\n", hex::encode_upper(color)).as_bytes())
.write_all(
format!(
"PX {x} {y} {:02X}{:02X}{:02X}\n",
color[0], color[1], color[2]
)
.as_bytes(),
)
.await
}
}