diff --git a/Cargo.lock b/Cargo.lock index cc011d5..1efcbf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + [[package]] name = "atty" version = "0.2.14" @@ -500,6 +506,7 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" name = "smallvec" version = "2.0.0-alpha.12" dependencies = [ + "arbitrary", "bytes", "criterion", "malloc_size_of", diff --git a/Cargo.toml b/Cargo.toml index fc1e447..1b7957f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ serde = ["dep:serde_core"] internals = [] [dependencies] +arbitrary = { version = "1", optional = true, default-features = false } bytes = { version = "1", optional = true, default-features = false } serde_core = { version = "1.0.221", optional = true, default-features = false } malloc_size_of = { version = "0.1.1", optional = true, default-features = false } @@ -29,6 +30,10 @@ malloc_size_of = { version = "0.1.1", optional = true, default-features = false serde_test = "1.0" criterion = "0.4.0" +[[test]] +name = "arbitrary" +required-features = ["arbitrary"] + [[test]] name = "bytes" required-features = ["bytes"] diff --git a/src/lib.rs b/src/lib.rs index 9aa7009..7890ac9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2978,6 +2978,25 @@ impl Debug for Drain<'_, T, N> { } } +#[cfg(feature = "arbitrary")] +#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))] +impl<'a, T, const N: usize> arbitrary::Arbitrary<'a> for SmallVec +where + T: arbitrary::Arbitrary<'a>, +{ + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + u.arbitrary_iter()?.collect() + } + + fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> arbitrary::Result { + u.arbitrary_take_rest_iter()?.collect() + } + + fn size_hint(depth: usize) -> (usize, Option) { + arbitrary::size_hint::and(::size_hint(depth), (0, None)) + } +} + #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for SmallVec diff --git a/tests/arbitrary.rs b/tests/arbitrary.rs new file mode 100644 index 0000000..8bc7bb4 --- /dev/null +++ b/tests/arbitrary.rs @@ -0,0 +1,10 @@ +use arbitrary::{Arbitrary, Unstructured}; +use smallvec::SmallVec; + +#[test] +fn test_arbitrary() { + // Deterministic for fixed input bytes; assert it builds a consistent SmallVec. + let mut u = Unstructured::new(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); + let v = SmallVec::::arbitrary(&mut u).unwrap(); + assert_eq!(v.len(), v.iter().count()); +}