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(Peekable); impl<'a, I: Iterator> ResponseStreamer { pub fn new(inner: I) -> Self { Self(inner.peekable()) } } impl<'a, I: Iterator)>> Iterator for ResponseStreamer { type Item = (&'a Direction, Vec<&'a Vec>); fn next(&mut self) -> Option { 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")); } }