use crate::serve::storage::Failure;
const DIGITS: &[u8; 16] = b"0123456789abcdef";
pub fn invalid() -> Failure {
Failure::new(
"query_continuation_invalid",
"continuation is not a canonical encoded value",
)
}
pub fn encode(bytes: &[u8]) -> String {
let mut encoded = String::new();
for byte in bytes {
encoded.push(char::from(DIGITS[usize::from(byte >> 4)]));
encoded.push(char::from(DIGITS[usize::from(byte & 15)]));
}
encoded
}
fn digit(byte: u8) -> Result<u8, Failure> {
match byte {
b'0'..=b'9' => Ok(byte - b'0'),
b'a'..=b'f' => Ok(byte - b'a' + 10),
_ => Err(invalid()),
}
}
pub fn decode(encoded: &str) -> Result<Vec<u8>, Failure> {
let (pairs, rest) = encoded.as_bytes().as_chunks::<2>();
if !rest.is_empty() {
return Err(invalid());
}
pairs
.iter()
.map(|pair| Ok((digit(pair[0])? << 4) | digit(pair[1])?))
.collect()
}