1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use core::fmt::{self, Debug, Display, Formatter, Write};
#[derive(Debug)]
pub struct HexRepr<B>(pub B);
impl<B: AsRef<[u8]>> Display for HexRepr<B> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
for c in self.0.as_ref() {
f.write_fmt(format_args!("{:02x}", c))?;
}
Ok(())
}
}
impl<B: AsRef<[u8]>> PartialEq<[u8]> for HexRepr<B> {
fn eq(&self, other: &[u8]) -> bool {
struct CmpWrite<'s>(::core::slice::Iter<'s, u8>);
impl Write for CmpWrite<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.as_bytes() {
if self.0.next() != Some(c) {
return Err(fmt::Error);
}
}
Ok(())
}
}
write!(&mut CmpWrite(other.into_iter()), "{}", self).is_ok()
}
}
impl<B: AsRef<[u8]>> PartialEq<&str> for HexRepr<B> {
fn eq(&self, other: &&str) -> bool {
self == other.as_bytes()
}
}
pub struct MaybeStr<'a>(pub &'a [u8]);
impl Debug for MaybeStr<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if let Ok(sval) = core::str::from_utf8(self.0) {
write!(f, "{:?}", sval)
} else {
write!(f, "<{}>", HexRepr(self.0))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hex_repr_output() {
assert_eq!(format!("{}", HexRepr(&[])), "");
assert_eq!(format!("{}", HexRepr(&[255, 0, 255, 0])), "ff00ff00");
}
#[test]
fn hex_repr_cmp() {
assert_eq!(HexRepr(&[0, 255, 0, 255]), "00ff00ff");
assert_ne!(HexRepr(&[100, 101, 102]), "00ff00ff");
}
#[test]
fn maybe_str_output() {
assert_eq!(format!("{:?}", MaybeStr(&[])), "\"\"");
assert_eq!(format!("{:?}", MaybeStr(&[255, 0])), "<ff00>");
}
}