ufmt/impls/
hex.rs

1use crate::{uDisplayHex, uWrite, Formatter, HexOptions};
2
3macro_rules! hex_format {
4    ($buf:expr, $val:expr, $options:expr) => {{
5        let mut cursor = $buf.len();
6        let mut val = $val;
7        if val <= 0 {
8            cursor -= 1;
9            $buf[cursor] = b'0';
10        } else {
11            while val != 0 && cursor > 0 {
12                let rem = val & 0xf;
13                cursor -= 1;
14                $buf[cursor] = hex_digit(rem as u8, $options.upper_case);
15                val >>= 4;
16            }
17        }
18        unsafe { core::str::from_utf8_unchecked(&$buf[cursor..]) }
19    }};
20}
21
22macro_rules! hex_pattern {
23    ($itype: ty, $utype:ty) => {
24        impl uDisplayHex for $itype {
25            fn fmt_hex<W>(
26                &self,
27                fmt: &mut Formatter<'_, W>,
28                options: HexOptions,
29            ) -> Result<(), W::Error>
30            where
31                W: uWrite + ?Sized,
32            {
33                let positive = if false && // the standard rust library doesn't format negative numbers with a minus sign
34                *self < 0 {
35                    fmt.write_char('-')?;
36                    ((!*self) as $utype).wrapping_add(1)
37                } else {
38                    *self as $utype
39                };
40                <$utype as uDisplayHex>::fmt_hex(&positive, fmt, options)
41            }
42        }
43
44        impl uDisplayHex for $utype {
45            fn fmt_hex<W>(
46                &self,
47                fmt: &mut Formatter<'_, W>,
48                options: HexOptions,
49            ) -> Result<(), W::Error>
50            where
51                W: uWrite + ?Sized,
52            {
53                let mut buffer = [b'0'; 2 * core::mem::size_of::<$utype>()];
54                let hex_string = hex_format!(buffer, *self, options);
55                options.with_stuff(fmt, hex_string)
56            }
57        }
58    };
59}
60
61hex_pattern! {i8, u8}
62hex_pattern! {i16, u16}
63hex_pattern! {i32, u32}
64hex_pattern! {i64, u64}
65hex_pattern! {i128, u128}
66hex_pattern! {isize, usize}
67
68fn hex_digit(val: u8, upper_case: bool) -> u8 {
69    if val < 10 {
70        b'0' + val
71    } else {
72        (if upper_case { b'A' } else { b'a' }) + (val - 10)
73    }
74}