130 lines
2.9 KiB
Rust
130 lines
2.9 KiB
Rust
use std::iter::Peekable;
|
|
|
|
use crate::record::Direction;
|
|
|
|
fn hex_digit(c: u8) -> u32 {
|
|
((c & !(16 | 32 | 64)) + ((c & 64) >> 6) * 9) as _
|
|
}
|
|
|
|
pub fn parse_hex(s: &[u8]) -> u32 {
|
|
let mut r = 0;
|
|
for i in s.iter() {
|
|
r <<= 4;
|
|
r |= hex_digit(*i);
|
|
}
|
|
r
|
|
}
|
|
|
|
pub fn is_hex(s: &[u8]) -> bool {
|
|
s.iter().all(|c| {
|
|
let c = *c | 32;
|
|
(c >= b'a' && c <= b'f') || (c >= b'0' && c <= b'9')
|
|
})
|
|
}
|
|
|
|
/// Print ASCII if possible
|
|
pub fn print_bin(s: &[u8]) {
|
|
if let Ok(s) = str::from_utf8(s) {
|
|
println!("{s}");
|
|
} else {
|
|
let mut buf = String::new();
|
|
for c in s {
|
|
if c.is_ascii_control() && *c != b'\n' {
|
|
continue;
|
|
}
|
|
if let Some(c) = c.as_ascii() {
|
|
buf.push_str(c.as_str());
|
|
} else {
|
|
for c in std::ascii::escape_default(*c) {
|
|
buf.push(c.as_ascii().unwrap().into());
|
|
}
|
|
}
|
|
}
|
|
println!("{buf}");
|
|
}
|
|
}
|
|
|
|
pub struct ResponseStreamer<I: Iterator>(Peekable<I>);
|
|
|
|
impl<'a, I: Iterator> ResponseStreamer<I> {
|
|
pub fn new(inner: I) -> Self {
|
|
Self(inner.peekable())
|
|
}
|
|
}
|
|
|
|
impl<'a, I: Iterator<Item = &'a (Direction, Vec<u8>)>> Iterator for ResponseStreamer<I> {
|
|
type Item = (&'a Direction, Vec<&'a Vec<u8>>);
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let (direction, first_item) = self.0.next()?;
|
|
let mut items = vec![first_item];
|
|
while let Some((item_direction, _item)) = self.0.peek()
|
|
&& item_direction == direction
|
|
{
|
|
items.push(&self.0.next().unwrap().1);
|
|
}
|
|
Some((direction, items))
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_hex_digit() {
|
|
assert_eq!(hex_digit(b'0'), 0);
|
|
assert_eq!(hex_digit(b'1'), 1);
|
|
assert_eq!(hex_digit(b'2'), 2);
|
|
assert_eq!(hex_digit(b'3'), 3);
|
|
assert_eq!(hex_digit(b'4'), 4);
|
|
assert_eq!(hex_digit(b'5'), 5);
|
|
assert_eq!(hex_digit(b'6'), 6);
|
|
assert_eq!(hex_digit(b'7'), 7);
|
|
assert_eq!(hex_digit(b'8'), 8);
|
|
assert_eq!(hex_digit(b'9'), 9);
|
|
assert_eq!(hex_digit(b'a'), 10);
|
|
assert_eq!(hex_digit(b'b'), 11);
|
|
assert_eq!(hex_digit(b'c'), 12);
|
|
assert_eq!(hex_digit(b'd'), 13);
|
|
assert_eq!(hex_digit(b'e'), 14);
|
|
assert_eq!(hex_digit(b'f'), 15);
|
|
assert_eq!(hex_digit(b'A'), 10);
|
|
assert_eq!(hex_digit(b'B'), 11);
|
|
assert_eq!(hex_digit(b'C'), 12);
|
|
assert_eq!(hex_digit(b'D'), 13);
|
|
assert_eq!(hex_digit(b'E'), 14);
|
|
assert_eq!(hex_digit(b'F'), 15);
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_hex() {
|
|
assert_eq!(parse_hex(b"abc123"), 0xabc123);
|
|
assert_eq!(parse_hex(b"1"), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_is_hex() {
|
|
assert!(is_hex(b"0"));
|
|
assert!(is_hex(b"1"));
|
|
assert!(is_hex(b"2"));
|
|
assert!(is_hex(b"3"));
|
|
assert!(is_hex(b"4"));
|
|
assert!(is_hex(b"5"));
|
|
assert!(is_hex(b"6"));
|
|
assert!(is_hex(b"7"));
|
|
assert!(is_hex(b"8"));
|
|
assert!(is_hex(b"9"));
|
|
assert!(is_hex(b"a"));
|
|
assert!(is_hex(b"b"));
|
|
assert!(is_hex(b"c"));
|
|
assert!(is_hex(b"d"));
|
|
assert!(is_hex(b"e"));
|
|
assert!(is_hex(b"f"));
|
|
assert!(is_hex(b"A"));
|
|
assert!(is_hex(b"B"));
|
|
assert!(is_hex(b"C"));
|
|
assert!(is_hex(b"D"));
|
|
assert!(is_hex(b"E"));
|
|
assert!(is_hex(b"F"));
|
|
}
|
|
}
|