Coverage Report

Created: 2026-02-26 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tinystr-0.8.2/src/unvalidated.rs
Line
Count
Source
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
use crate::ParseError;
6
use crate::TinyAsciiStr;
7
use core::fmt;
8
9
/// A fixed-length bytes array that is expected to be an ASCII string but does not enforce that invariant.
10
///
11
/// Use this type instead of `TinyAsciiStr` if you don't need to enforce ASCII during deserialization. For
12
/// example, strings that are keys of a map don't need to ever be reified as `TinyAsciiStr`s.
13
///
14
/// The main advantage of this type over `[u8; N]` is that it serializes as a string in
15
/// human-readable formats like JSON.
16
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
17
pub struct UnvalidatedTinyAsciiStr<const N: usize>(pub(crate) [u8; N]);
18
19
impl<const N: usize> fmt::Debug for UnvalidatedTinyAsciiStr<N> {
20
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21
        // Debug as a string if possible
22
0
        match self.try_into_tinystr() {
23
0
            Ok(s) => fmt::Debug::fmt(&s, f),
24
0
            Err(_) => fmt::Debug::fmt(&self.0, f),
25
        }
26
0
    }
27
}
28
29
impl<const N: usize> UnvalidatedTinyAsciiStr<N> {
30
    #[inline]
31
    /// Converts into a [`TinyAsciiStr`]. Fails if the bytes are not valid ASCII.
32
0
    pub fn try_into_tinystr(self) -> Result<TinyAsciiStr<N>, ParseError> {
33
0
        TinyAsciiStr::try_from_raw(self.0)
34
0
    }
35
36
    #[inline]
37
    /// Unsafely converts into a [`TinyAsciiStr`].
38
0
    pub const fn from_utf8_unchecked(bytes: [u8; N]) -> Self {
39
0
        Self(bytes)
40
0
    }
41
}
42
43
impl<const N: usize> TinyAsciiStr<N> {
44
    #[inline]
45
    // Converts into a [`UnvalidatedTinyAsciiStr`]
46
0
    pub const fn to_unvalidated(self) -> UnvalidatedTinyAsciiStr<N> {
47
0
        UnvalidatedTinyAsciiStr(*self.all_bytes())
48
0
    }
49
}
50
51
impl<const N: usize> From<TinyAsciiStr<N>> for UnvalidatedTinyAsciiStr<N> {
52
0
    fn from(other: TinyAsciiStr<N>) -> Self {
53
0
        other.to_unvalidated()
54
0
    }
55
}
56
57
#[cfg(feature = "serde")]
58
impl<const N: usize> serde_core::Serialize for UnvalidatedTinyAsciiStr<N> {
59
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60
    where
61
        S: serde_core::Serializer,
62
    {
63
        use serde_core::ser::Error;
64
        self.try_into_tinystr()
65
            .map_err(|_| S::Error::custom("invalid ascii in UnvalidatedTinyAsciiStr"))?
66
            .serialize(serializer)
67
    }
68
}
69
70
macro_rules! deserialize {
71
    ($size:literal) => {
72
        #[cfg(feature = "serde")]
73
        impl<'de, 'a> serde_core::Deserialize<'de> for UnvalidatedTinyAsciiStr<$size>
74
        where
75
            'de: 'a,
76
        {
77
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78
            where
79
                D: serde_core::Deserializer<'de>,
80
            {
81
                if deserializer.is_human_readable() {
82
                    Ok(TinyAsciiStr::deserialize(deserializer)?.to_unvalidated())
83
                } else {
84
                    Ok(Self(<[u8; $size]>::deserialize(deserializer)?))
85
                }
86
            }
87
        }
88
    };
89
}
90
91
deserialize!(1);
92
deserialize!(2);
93
deserialize!(3);
94
deserialize!(4);
95
deserialize!(5);
96
deserialize!(6);
97
deserialize!(7);
98
deserialize!(8);
99
deserialize!(9);
100
deserialize!(10);
101
deserialize!(11);
102
deserialize!(12);
103
deserialize!(13);
104
deserialize!(14);
105
deserialize!(15);
106
deserialize!(16);
107
deserialize!(17);
108
deserialize!(18);
109
deserialize!(19);
110
deserialize!(20);
111
deserialize!(21);
112
deserialize!(22);
113
deserialize!(23);
114
deserialize!(24);
115
deserialize!(25);
116
deserialize!(26);
117
deserialize!(27);
118
deserialize!(28);
119
deserialize!(29);
120
deserialize!(30);
121
deserialize!(31);
122
deserialize!(32);