compact_str/features/
quickcheck.rs

1//! Implements the [`quickcheck::Arbitrary`] trait for [`CompactString`]
2
3use alloc::boxed::Box;
4use alloc::vec::Vec;
5
6use quickcheck::{Arbitrary, Gen};
7
8use crate::CompactString;
9
10#[cfg_attr(docsrs, doc(cfg(feature = "quickcheck")))]
11impl Arbitrary for CompactString {
12    fn arbitrary(g: &mut Gen) -> CompactString {
13        let max = g.size();
14
15        // pick some value in [0, max]
16        let x = usize::arbitrary(g);
17        let ratio = (x as f64) / (usize::MAX as f64);
18        let size = (ratio * max as f64) as usize;
19
20        (0..size).map(|_| char::arbitrary(g)).collect()
21    }
22
23    fn shrink(&self) -> Box<dyn Iterator<Item = CompactString>> {
24        // Shrink a string by shrinking a vector of its characters.
25        let chars: Vec<char> = self.chars().collect();
26        Box::new(
27            chars
28                .shrink()
29                .map(|x| x.into_iter().collect::<CompactString>()),
30        )
31    }
32}
33
34#[cfg(test)]
35mod test {
36    use alloc::string::String;
37
38    use quickcheck_macros::quickcheck;
39
40    use crate::CompactString;
41
42    #[quickcheck]
43    #[cfg_attr(miri, ignore)]
44    fn quickcheck_sanity(compact: CompactString) {
45        let control: String = compact.clone().into();
46        assert_eq!(control, compact);
47    }
48
49    #[quickcheck]
50    #[cfg_attr(miri, ignore)]
51    fn quickcheck_inlines_strings(compact: CompactString) {
52        if compact.len() <= core::mem::size_of::<String>() {
53            assert!(!compact.is_heap_allocated())
54        } else {
55            assert!(compact.is_heap_allocated())
56        }
57    }
58}