proptest_arbitrary/_std/
ffi.rs

1//! Arbitrary implementations for `std::ffi`.
2
3use super::*;
4use std::ffi::*;
5use std::ops::Range;
6use proptest::collection::{VecStrategy, vec};
7use _std::string::not_utf8_bytes;
8
9arbitrary!(CString,
10    SFnPtrMap<VecStrategy<Range<u8>>, Self>, SizeBounds;
11    args => static_map(vec(1..std::u8::MAX, (args + 1).into()), |mut vec| {
12        vec.pop().unwrap();
13        // Could use: Self::from_vec_unchecked(vec) safely.
14        Self::new(vec).unwrap()
15    })
16);
17
18arbitrary!(OsString, FMapped<'a, String, Self>,
19    <String as Arbitrary<'a>>::Parameters; a => any_with_sinto::<String, _>(a)
20);
21
22macro_rules! dst_wrapped {
23    ($($w: ident),*) => {
24        $(arbitrary!($w<CStr>, FMapped<'a, CString, Self>, SizeBounds;
25            a => any_with_sinto::<CString, _>(a)
26        );)*
27        $(arbitrary!($w<OsStr>, FMapped<'a, OsString, Self>,
28            <String as Arbitrary<'a>>::Parameters;
29            a => any_with_sinto::<OsString, _>(a)
30        );)*
31    };
32}
33
34dst_wrapped!(Box);
35
36#[cfg(MIN_VER_1_24_0)]
37use std::rc::Rc;
38#[cfg(MIN_VER_1_24_0)]
39use std::sync::Arc;
40#[cfg(MIN_VER_1_24_0)]
41dst_wrapped!(Rc, Arc);
42
43arbitrary!(FromBytesWithNulError, SMapped<'a, Option<u16>, Self>; {
44    static_map(any::<Option<u16>>(), |opt_pos| {
45        // We make some assumptions about the internal structure of
46        // FromBytesWithNulError. However, these assumptions do not
47        // involve any non-public API.
48        if let Some(pos) = opt_pos {
49            let pos = pos as usize;
50            // Allocate pos + 2 so that we never reallocate:
51            let mut v = Vec::<u8>::with_capacity(pos + 2);
52            v.extend(::std::iter::repeat(1).take(pos));
53            v.push(0);
54            v.push(1);
55            CStr::from_bytes_with_nul(v.as_slice()).unwrap_err()
56        } else {
57            CStr::from_bytes_with_nul(b"").unwrap_err()
58        }
59    })
60});
61
62arbitrary!(IntoStringError, SFnPtrMap<BoxedStrategy<Vec<u8>>, Self>;
63    static_map(not_utf8_bytes(false), |bytes|
64        CString::new(bytes).unwrap().into_string().unwrap_err()
65    )
66);
67
68#[cfg(test)]
69mod test {
70    no_panic_test!(
71        c_string => CString,
72        os_string => OsString,
73        box_c_str => Box<CStr>,
74        box_os_str => Box<OsStr>,
75        into_string_error => IntoStringError,
76        from_bytes_with_nul => FromBytesWithNulError
77    );
78    #[cfg(MIN_VER_1_24_0)]
79    no_panic_test!(
80        rc_c_str => Rc<CStr>,
81        rc_os_str => Rc<OsStr>,
82        arc_c_str => Arc<CStr>,
83        arc_os_str => Arc<OsStr>
84    );
85}