1use core::fmt;
2use super::BitSet;
3
4#[repr(transparent)]
6pub struct BitFmt<T: ?Sized>(T);
7
8fn bitstring<T: ?Sized + BitSet>(this: &T, f: &mut fmt::Formatter) -> fmt::Result {
9 const ALPHABET: [u8; 2] = [b'0', b'1'];
10 let mut buf = [0u8; 9];
11 let mut first = true;
12 buf[0] = b'_';
13 let mut i = 0;
14 while i < this.bit_len() {
15 buf[1] = ALPHABET[this.bit_test(i + 0) as usize];
16 buf[2] = ALPHABET[this.bit_test(i + 1) as usize];
17 buf[3] = ALPHABET[this.bit_test(i + 2) as usize];
18 buf[4] = ALPHABET[this.bit_test(i + 3) as usize];
19 buf[5] = ALPHABET[this.bit_test(i + 4) as usize];
20 buf[6] = ALPHABET[this.bit_test(i + 5) as usize];
21 buf[7] = ALPHABET[this.bit_test(i + 6) as usize];
22 buf[8] = ALPHABET[this.bit_test(i + 7) as usize];
23 let s = unsafe { &*((&buf[first as usize..]) as *const _ as *const str) };
24 f.write_str(s)?;
25 i += 8;
26 first = false;
27 }
28 Ok(())
29}
30
31const UPPERHEX_ALPHABET: [u8; 16] = *b"0123456789ABCDEF";
32const LOWERHEX_ALPHABET: [u8; 16] = *b"0123456789abcdef";
33
34fn hexstring<T: ?Sized + BitSet>(this: &T, f: &mut fmt::Formatter, alphabet: &[u8; 16]) -> fmt::Result {
35 let mut buf = [0u8; 2];
36 let mut i = 0;
37 while i < this.bit_len() {
38 let byte =
39 (this.bit_test(i + 0) as u8) << 7 |
40 (this.bit_test(i + 1) as u8) << 6 |
41 (this.bit_test(i + 2) as u8) << 5 |
42 (this.bit_test(i + 3) as u8) << 4 |
43 (this.bit_test(i + 4) as u8) << 3 |
44 (this.bit_test(i + 5) as u8) << 2 |
45 (this.bit_test(i + 6) as u8) << 1 |
46 (this.bit_test(i + 7) as u8) << 0;
47 buf[0] = alphabet[(byte >> 4) as usize];
48 buf[1] = alphabet[(byte & 0xf) as usize];
49 let s = unsafe { &*((&buf[..]) as *const _ as *const str) };
50 f.write_str(s)?;
51 i += 8;
52 }
53 Ok(())
54}
55
56impl<T: ?Sized + BitSet> fmt::Display for BitFmt<T> {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 bitstring(&self.0, f)
59 }
60}
61impl<T: ?Sized + BitSet> fmt::Debug for BitFmt<T> {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 f.write_str("\"")?;
64 hexstring(&self.0, f, &UPPERHEX_ALPHABET)?;
65 f.write_str("\"")?;
66 Ok(())
67 }
68}
69
70impl<T: ?Sized + BitSet> fmt::UpperHex for BitFmt<T> {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 hexstring(&self.0, f, &UPPERHEX_ALPHABET)
73 }
74}
75impl<T: ?Sized + BitSet> fmt::LowerHex for BitFmt<T> {
76 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77 hexstring(&self.0, f, &LOWERHEX_ALPHABET)
78 }
79}