/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.2/src/helpers.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 | | pub(crate) trait MaybeSplitAt<T> { |
6 | | /// Like slice::split_at but debug-panics and returns an empty second slice |
7 | | /// if the index is out of range. |
8 | | fn debug_split_at(&self, mid: usize) -> (&Self, &Self); |
9 | | } |
10 | | |
11 | | impl<T> MaybeSplitAt<T> for [T] { |
12 | | #[inline] |
13 | 0 | fn debug_split_at(&self, mid: usize) -> (&Self, &Self) { |
14 | 0 | self.split_at_checked(mid).unwrap_or_else(|| { |
15 | 0 | debug_assert!(false, "debug_split_at: {mid} expected to be in range"); |
16 | 0 | (self, &[]) |
17 | 0 | }) |
18 | 0 | } |
19 | | } |
20 | | |
21 | | pub(crate) trait DebugUnwrapOr<T> { |
22 | | /// Unwraps the option or panics in debug mode, returning the `gigo_value` |
23 | | fn debug_unwrap_or(self, gigo_value: T) -> T; |
24 | | } |
25 | | |
26 | | impl<T> DebugUnwrapOr<T> for Option<T> { |
27 | | #[inline] |
28 | 0 | fn debug_unwrap_or(self, gigo_value: T) -> T { |
29 | 0 | match self { |
30 | 0 | Some(x) => x, |
31 | | None => { |
32 | 0 | debug_assert!(false, "debug_unwrap_or called on a None value"); |
33 | 0 | gigo_value |
34 | | } |
35 | | } |
36 | 0 | } Unexecuted instantiation: <core::option::Option<&[u8]> as zerotrie::helpers::DebugUnwrapOr<&[u8]>>::debug_unwrap_or Unexecuted instantiation: <core::option::Option<&u8> as zerotrie::helpers::DebugUnwrapOr<&u8>>::debug_unwrap_or |
37 | | } |
38 | | |
39 | | macro_rules! debug_unwrap { |
40 | | ($expr:expr, return $retval:expr, $($arg:tt)+) => { |
41 | | match $expr { |
42 | | Some(x) => x, |
43 | | None => { |
44 | | debug_assert!(false, $($arg)*); |
45 | | return $retval; |
46 | | } |
47 | | } |
48 | | }; |
49 | | ($expr:expr, return $retval:expr) => { |
50 | | debug_unwrap!($expr, return $retval, "invalid trie") |
51 | | }; |
52 | | ($expr:expr, break, $($arg:tt)+) => { |
53 | | match $expr { |
54 | | Some(x) => x, |
55 | | None => { |
56 | | debug_assert!(false, $($arg)*); |
57 | | break; |
58 | | } |
59 | | } |
60 | | }; |
61 | | ($expr:expr, break) => { |
62 | | debug_unwrap!($expr, break, "invalid trie") |
63 | | }; |
64 | | ($expr:expr, $($arg:tt)+) => { |
65 | | debug_unwrap!($expr, return (), $($arg)*) |
66 | | }; |
67 | | ($expr:expr) => { |
68 | | debug_unwrap!($expr, return ()) |
69 | | }; |
70 | | } |
71 | | |
72 | | pub(crate) use debug_unwrap; |
73 | | |
74 | | /// The maximum number of base-10 digits required for rendering a usize. |
75 | | /// Note: 24/10 is an approximation of 8*log10(2) |
76 | | pub(crate) const MAX_USIZE_LEN_AS_DIGITS: usize = core::mem::size_of::<usize>() * 24 / 10 + 1; |
77 | | |
78 | | /// Formats a usize as a string of length N, padded with spaces, |
79 | | /// with the given prefix. |
80 | | /// |
81 | | /// If the string is too short, the function may panic. To prevent |
82 | | /// this, N should be MAX_USIZE_LEN_AS_DIGITS larger than M. |
83 | 0 | pub(crate) const fn const_fmt_int<const M: usize, const N: usize>( |
84 | 0 | prefix: [u8; M], |
85 | 0 | value: usize, |
86 | 0 | ) -> [u8; N] { |
87 | 0 | let mut output = [b' '; N]; |
88 | 0 | let mut i = 0; |
89 | 0 | while i < M { |
90 | 0 | output[i] = prefix[i]; |
91 | 0 | i += 1; |
92 | 0 | } |
93 | 0 | let mut int_only = [b' '; MAX_USIZE_LEN_AS_DIGITS]; |
94 | 0 | let mut value = value; |
95 | 0 | let mut i = MAX_USIZE_LEN_AS_DIGITS - 1; |
96 | | loop { |
97 | 0 | let x = (value % 10) as u8; |
98 | 0 | int_only[i] = x + b'0'; |
99 | 0 | value /= 10; |
100 | 0 | if value == 0 { |
101 | 0 | break; |
102 | 0 | } |
103 | 0 | i -= 1; |
104 | | } |
105 | 0 | let mut j = M; |
106 | 0 | while i < MAX_USIZE_LEN_AS_DIGITS { |
107 | 0 | output[j] = int_only[i]; |
108 | 0 | j += 1; |
109 | 0 | i += 1; |
110 | 0 | } |
111 | 0 | output |
112 | 0 | } |
113 | | |
114 | | #[test] |
115 | | fn test_const_fmt_int() { |
116 | | assert_eq!(*b"123", const_fmt_int::<0, 3>(*b"", 123)); |
117 | | assert_eq!(*b"123 ", const_fmt_int::<0, 6>(*b"", 123)); |
118 | | assert_eq!(*b"abc123", const_fmt_int::<3, 6>(*b"abc", 123)); |
119 | | } |