Coverage Report

Created: 2025-07-23 06:36

/rust/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/hex.rs
Line
Count
Source (jump to first uncovered line)
1
//! Generic array are commonly used as a return value for hash digests, so
2
//! it's a good idea to allow to hexlify them easily. This module implements
3
//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
4
//!
5
//! Example:
6
//!
7
//! ```rust
8
//! # #[macro_use]
9
//! # extern crate generic_array;
10
//! # extern crate typenum;
11
//! # fn main() {
12
//! let array = arr![u8; 10, 20, 30];
13
//! assert_eq!(format!("{:x}", array), "0a141e");
14
//! # }
15
//! ```
16
//!
17
18
use core::{fmt, str, ops::Add, cmp::min};
19
20
use typenum::*;
21
22
use crate::{ArrayLength, GenericArray};
23
24
static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
25
static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
26
27
impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
28
where
29
    T: Add<T>,
30
    <T as Add<T>>::Output: ArrayLength<u8>,
31
{
32
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33
0
        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
34
0
        let max_hex = (max_digits >> 1) + (max_digits & 1);
35
0
36
0
        if T::USIZE < 1024 {
37
            // For small arrays use a stack allocated
38
            // buffer of 2x number of bytes
39
0
            let mut res = GenericArray::<u8, Sum<T, T>>::default();
40
0
41
0
            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
42
0
                res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
43
0
                res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
44
0
            });
45
0
46
0
            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
47
        } else {
48
            // For large array use chunks of up to 1024 bytes (2048 hex chars)
49
0
            let mut buf = [0u8; 2048];
50
0
            let mut digits_left = max_digits;
51
52
0
            for chunk in self[..max_hex].chunks(1024) {
53
0
                chunk.iter().enumerate().for_each(|(i, c)| {
54
0
                    buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
55
0
                    buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
56
0
                });
57
0
58
0
                let n = min(chunk.len() * 2, digits_left);
59
0
                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
60
0
                digits_left -= n;
61
            }
62
        }
63
0
        Ok(())
64
0
    }
65
}
66
67
impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
68
where
69
    T: Add<T>,
70
    <T as Add<T>>::Output: ArrayLength<u8>,
71
{
72
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73
0
        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
74
0
        let max_hex = (max_digits >> 1) + (max_digits & 1);
75
0
76
0
        if T::USIZE < 1024 {
77
            // For small arrays use a stack allocated
78
            // buffer of 2x number of bytes
79
0
            let mut res = GenericArray::<u8, Sum<T, T>>::default();
80
0
81
0
            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
82
0
                res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
83
0
                res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
84
0
            });
85
0
86
0
            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
87
        } else {
88
            // For large array use chunks of up to 1024 bytes (2048 hex chars)
89
0
            let mut buf = [0u8; 2048];
90
0
            let mut digits_left = max_digits;
91
92
0
            for chunk in self[..max_hex].chunks(1024) {
93
0
                chunk.iter().enumerate().for_each(|(i, c)| {
94
0
                    buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
95
0
                    buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
96
0
                });
97
0
98
0
                let n = min(chunk.len() * 2, digits_left);
99
0
                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
100
0
                digits_left -= n;
101
            }
102
        }
103
0
        Ok(())
104
0
    }
105
}