From aea1e9cd9226b954001f9820ba28b81f62a2f182 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 27 Jun 2026 01:05:57 +0300 Subject: [PATCH] beer-protocols/codex: add hex -> numerical value helper Co-authored-by: faukah Signed-off-by: NotAShelf Change-Id: I55a55d89e886a1c4f8c0a415089607b16a6a6964 --- crates/beer-protocols/src/codec.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/beer-protocols/src/codec.rs b/crates/beer-protocols/src/codec.rs index 1fe38e3..05cf144 100644 --- a/crates/beer-protocols/src/codec.rs +++ b/crates/beer-protocols/src/codec.rs @@ -75,22 +75,27 @@ pub fn decode_hex(s: &[u8]) -> Option> { if s.is_empty() || !s.len().is_multiple_of(2) { return None; } - let nibble = |b: u8| (b as char).to_digit(16).map(|d| d as u8); + s.chunks_exact(2) - .map(|pair| Some((nibble(pair[0])? << 4) | nibble(pair[1])?)) + .map(|pair| Some((hex_nibble(pair[0])? << 4) | hex_nibble(pair[1])?)) .collect() } +/// Turn a hexadecimal character into its numerical value. +fn hex_nibble(b: u8) -> Option { + (b as char).to_digit(16).map(|d| d as u8) +} + /// Percent-decode `%XX` byte escapes in a URI path, passing other bytes through. pub fn percent_decode(s: &[u8]) -> Vec { let mut out = Vec::with_capacity(s.len()); let mut i = 0; while i < s.len() { if s[i] == b'%' && i + 2 < s.len() { - let hi = (s[i + 1] as char).to_digit(16); - let lo = (s[i + 2] as char).to_digit(16); + let hi = hex_nibble(s[i + 1]); + let lo = hex_nibble(s[i + 2]); if let (Some(hi), Some(lo)) = (hi, lo) { - out.push((hi * 16 + lo) as u8); + out.push(hi << 4 | lo); i += 3; continue; }