icu_collections/codepointinvlist/
utils.rs
1use core::{
6 char,
7 ops::{Bound::*, RangeBounds},
8};
9use zerovec::ule::AsULE;
10use zerovec::ZeroVec;
11
12#[allow(clippy::indexing_slicing)] #[allow(clippy::unwrap_used)] pub fn is_valid_zv(inv_list_zv: &ZeroVec<'_, u32>) -> bool {
17 inv_list_zv.is_empty()
18 || (inv_list_zv.len() % 2 == 0
19 && inv_list_zv.as_ule_slice().windows(2).all(|chunk| {
20 <u32 as AsULE>::from_unaligned(chunk[0]) < <u32 as AsULE>::from_unaligned(chunk[1])
21 })
22 && inv_list_zv.last().unwrap() <= char::MAX as u32 + 1)
23}
24
25pub fn deconstruct_range<T, R: RangeBounds<T>>(range: &R) -> (u32, u32)
27where
28 T: Into<u32> + Copy,
29{
30 let from = match range.start_bound() {
31 Included(b) => (*b).into(),
32 Excluded(_) => unreachable!(),
33 Unbounded => 0,
34 };
35 let till = match range.end_bound() {
36 Included(b) => (*b).into() + 1,
37 Excluded(b) => (*b).into(),
38 Unbounded => (char::MAX as u32) + 1,
39 };
40 (from, till)
41}
42
43#[cfg(test)]
44mod tests {
45 use super::{deconstruct_range, is_valid_zv};
46 use core::char;
47 use zerovec::ZeroVec;
48
49 #[test]
50 fn test_is_valid_zv() {
51 let check = ZeroVec::from_slice_or_alloc(&[0x2, 0x3, 0x4, 0x5]);
52 assert!(is_valid_zv(&check));
53 }
54
55 #[test]
56 fn test_is_valid_zv_empty() {
57 let check = ZeroVec::from_slice_or_alloc(&[]);
58 assert!(is_valid_zv(&check));
59 }
60
61 #[test]
62 fn test_is_valid_zv_overlapping() {
63 let check = ZeroVec::from_slice_or_alloc(&[0x2, 0x5, 0x4, 0x6]);
64 assert!(!is_valid_zv(&check));
65 }
66
67 #[test]
68 fn test_is_valid_zv_out_of_order() {
69 let check = ZeroVec::from_slice_or_alloc(&[0x5, 0x4, 0x5, 0x6, 0x7]);
70 assert!(!is_valid_zv(&check));
71 }
72
73 #[test]
74 fn test_is_valid_zv_duplicate() {
75 let check = ZeroVec::from_slice_or_alloc(&[0x1, 0x2, 0x3, 0x3, 0x5]);
76 assert!(!is_valid_zv(&check));
77 }
78
79 #[test]
80 fn test_is_valid_zv_odd() {
81 let check = ZeroVec::from_slice_or_alloc(&[0x1, 0x2, 0x3, 0x4, 0x5]);
82 assert!(!is_valid_zv(&check));
83 }
84
85 #[test]
86 fn test_is_valid_zv_out_of_range() {
87 let check = ZeroVec::from_slice_or_alloc(&[0x1, 0x2, 0x3, 0x4, (char::MAX as u32) + 1]);
88 assert!(!is_valid_zv(&check));
89 }
90
91 #[test]
94 fn test_deconstruct_range() {
95 let expected = (0x41, 0x45);
96 let check = deconstruct_range(&('A'..'E')); assert_eq!(check, expected);
98 let check = deconstruct_range(&('A'..='D')); assert_eq!(check, expected);
100 let check = deconstruct_range(&('A'..)); assert_eq!(check, (0x41, (char::MAX as u32) + 1));
102 let check = deconstruct_range(&(..'A')); assert_eq!(check, (0x0, 0x41));
104 let check = deconstruct_range(&(..='A')); assert_eq!(check, (0x0, 0x42));
106 let check = deconstruct_range::<char, _>(&(..)); assert_eq!(check, (0x0, (char::MAX as u32) + 1));
108 }
109}