multiversx_sc/formatter/
formatter_impl_num.rs1use super::{SCBinary, SCDisplay, SCLowerHex, hex_util::byte_to_hex_digits};
2
3const MINUS_SYMBOL: &[u8] = b"-";
4
5const MAX_BASE_10_LEN: usize = 64;
7
8fn format_unsigned_to_buffer(
9 mut num: u64,
10 buffer: &mut [u8; MAX_BASE_10_LEN],
11 base_no: u64,
12) -> &[u8] {
13 let mut buf_index = MAX_BASE_10_LEN;
14 if num == 0 {
15 buf_index -= 1;
16 buffer[buf_index] = b'0';
17 } else {
18 while num > 0 {
19 buf_index -= 1;
20 let last_digit = (num % base_no) as u8;
21 let ascii_last_digit = byte_to_hex_digits(last_digit)[1];
22 buffer[buf_index] = ascii_last_digit;
23 num /= base_no;
24 }
25 }
26 &buffer[buf_index..]
27}
28
29fn format_unsigned<F: super::FormatByteReceiver>(num: u64, f: &mut F, base_no: u64) {
30 let mut buffer = [0u8; MAX_BASE_10_LEN];
31 let formatted = format_unsigned_to_buffer(num, &mut buffer, base_no);
32 f.append_bytes(formatted);
33}
34
35macro_rules! formatter_unsigned {
36 ($num_ty:ty) => {
37 impl SCDisplay for $num_ty {
38 #[inline]
39 fn fmt<F: super::FormatByteReceiver>(&self, f: &mut F) {
40 format_unsigned(*self as u64, f, 10);
41 }
42 }
43 impl SCLowerHex for $num_ty {
44 #[inline]
45 fn fmt<F: super::FormatByteReceiver>(&self, f: &mut F) {
46 format_unsigned(*self as u64, f, 16);
47 }
48 }
49 impl SCBinary for $num_ty {
50 #[inline]
51 fn fmt<F: super::FormatByteReceiver>(&self, f: &mut F) {
52 format_unsigned(*self as u64, f, 2);
53 }
54 }
55 };
56}
57
58formatter_unsigned! {u64}
59formatter_unsigned! {u32}
60formatter_unsigned! {usize}
61formatter_unsigned! {u16}
62formatter_unsigned! {u8}
63
64fn format_signed<F: super::FormatByteReceiver>(num: i64, f: &mut F) {
65 let abs = if num >= 0 {
66 num as u64
67 } else {
68 f.append_bytes(MINUS_SYMBOL);
69 if num == i64::MIN {
70 (i64::MAX as u64) + 1
72 } else {
73 (-num) as u64
74 }
75 };
76 format_unsigned(abs, f, 10);
77}
78
79fn format_signed_hex<F: super::FormatByteReceiver>(num: i64, f: &mut F, size_in_bits: u8) {
80 let abs = if num >= 0 {
81 num as u64
82 } else if size_in_bits == 64 {
83 (num | i64::MIN) as u64
85 } else {
86 ((1 << size_in_bits) - 1) & (num & i64::MAX) as u64
87 };
88 format_unsigned(abs, f, 16);
89}
90
91macro_rules! formatter_signed {
92 ($num_ty:ty) => {
93 impl SCDisplay for $num_ty {
94 #[inline]
95 fn fmt<F: super::FormatByteReceiver>(&self, f: &mut F) {
96 format_signed(*self as i64, f);
97 }
98 }
99 };
100}
101
102macro_rules! formatter_signed_hex {
103 ($num_ty:ty, $size_in_bits:expr) => {
104 impl SCLowerHex for $num_ty {
105 #[inline]
106 fn fmt<F: super::FormatByteReceiver>(&self, f: &mut F) {
107 format_signed_hex(*self as i64, f, $size_in_bits);
108 }
109 }
110 };
111}
112
113formatter_signed! {i64}
114formatter_signed! {i32}
115formatter_signed! {isize}
116formatter_signed! {i16}
117formatter_signed! {i8}
118
119formatter_signed_hex! {i64, 64}
120formatter_signed_hex! {i32, 32}
121formatter_signed_hex! {isize, 32}
122formatter_signed_hex! {i16, 16}
123formatter_signed_hex! {i8, 8}