Snap for 8730993 from 5cfc303e713cca1503bdff268f126fe96311ddba to mainline-tzdata3-release
Change-Id: I985fa7f22ce697262f7ffc6b92e7673b75b1c0dc
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 508adbd..cfe44cd 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,5 @@
{
"git": {
- "sha1": "d0d238d880276fd617c38f7e4712bf40db58aad6"
- },
- "path_in_vcs": ""
-}
\ No newline at end of file
+ "sha1": "83b852c9bba47359ad33fc5b1f81f29425bc97e8"
+ }
+}
diff --git a/Android.bp b/Android.bp
index 83c7cf4..b90737f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
+// This file is generated by cargo2android.py --run --dependencies --device --features derive --patch patches/Android.bp.patch.
// Do not modify this file as changes will be overridden on upgrade.
package {
@@ -37,67 +37,21 @@
],
}
-rust_test {
- name: "arbitrary_test_src_lib",
- // has rustc warnings
- host_supported: true,
- crate_name: "arbitrary",
- cargo_env_compat: true,
- cargo_pkg_version: "1.1.0",
- srcs: ["src/lib.rs"],
- test_suites: ["general-tests"],
- auto_gen_config: true,
- test_options: {
- unit_test: true,
- },
- edition: "2018",
- features: [
- "derive",
- "derive_arbitrary",
- ],
- proc_macros: ["libderive_arbitrary"],
-}
-
-rust_test {
- name: "arbitrary_test_tests_derive",
- // has rustc warnings
- host_supported: true,
- crate_name: "arbitrary",
- cargo_env_compat: true,
- cargo_pkg_version: "1.1.0",
- srcs: ["tests/derive.rs"],
- test_suites: ["general-tests"],
- auto_gen_config: true,
- test_options: {
- unit_test: true,
- },
- edition: "2018",
- features: [
- "derive",
- "derive_arbitrary",
- ],
- rustlibs: [
- "libarbitrary",
- ],
- proc_macros: ["libderive_arbitrary"],
-}
-
rust_library_rlib {
name: "libarbitrary",
- // has rustc warnings
host_supported: true,
crate_name: "arbitrary",
- cargo_env_compat: true,
- cargo_pkg_version: "1.1.0",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
"derive",
- "derive_arbitrary",
],
proc_macros: ["libderive_arbitrary"],
- apex_available: [
- "com.android.uwb",
- ],
- min_sdk_version: "Tiramisu",
}
+
+// dependent_library ["feature_list"]
+// derive_arbitrary-1.0.0
+// proc-macro2-1.0.26 "default,proc-macro"
+// quote-1.0.9 "default,proc-macro"
+// syn-1.0.68 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
+// unicode-xid-0.2.1 "default"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a7c179..6542d53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,60 +28,6 @@
--------------------------------------------------------------------------------
-## 1.1.0
-
-Released 2022-02-09.
-
-### Added
-
-* Added the `Unstructured::ratio` method to generate a boolean that is `true` at
- the given rate.
-
-* Added the `Unstructured::arbitrary_loop` method to call a function an
- arbitrary number of times.
-
---------------------------------------------------------------------------------
-
-## 1.0.3
-
-Released 2021-11-20.
-
-### Fixed
-
-* Fixed documentation for `Unstructured::fill_bytes`. We forgot to update this
- way back in [#53](https://github.com/rust-fuzz/arbitrary/pull/53) when the
- behavior changed.
-
---------------------------------------------------------------------------------
-
-## 1.0.2
-
-Released 2021-08-25.
-
-### Added
-
-* `Arbitrary` impls for `HashMap`s and `HashSet`s with custom `Hasher`s
- [#87](https://github.com/rust-fuzz/arbitrary/pull/87)
-
---------------------------------------------------------------------------------
-
-## 1.0.1
-
-Released 2021-05-20.
-
-### Added
-
-* `Arbitrary` impls for `NonZeroX` types [#79](https://github.com/rust-fuzz/arbitrary/pull/79)
-* `Arbitrary` impls for all arrays using const generics [#55](https://github.com/rust-fuzz/arbitrary/pull/55)
-* `Arbitrary` impls for `Ipv4Addr` and `Ipv6Addr` [#84](https://github.com/rust-fuzz/arbitrary/pull/84)
-
-### Fixed
-
-* Use fewer bytes for `Unstructured::int_in_range()` [#80](https://github.com/rust-fuzz/arbitrary/pull/80)
-* Use correct range for `char` generation [#83](https://github.com/rust-fuzz/arbitrary/pull/83)
-
---------------------------------------------------------------------------------
-
## 1.0.0
Released 2020-02-24.
diff --git a/Cargo.toml b/Cargo.toml
index a42a90b..b57a351 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,33 +3,24 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
+# to registry (e.g., crates.io) dependencies
#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "arbitrary"
-version = "1.1.0"
-authors = [
- "The Rust-Fuzz Project Developers",
- "Nick Fitzgerald <fitzgen@gmail.com>",
- "Manish Goregaokar <manishsmail@gmail.com>",
- "Simonas Kazlauskas <arbitrary@kazlauskas.me>",
- "Brian L. Troutwine <brian@troutwine.us>",
- "Corey Farwell <coreyf@rwell.org>",
-]
+version = "1.0.0"
+authors = ["The Rust-Fuzz Project Developers", "Nick Fitzgerald <fitzgen@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>", "Simonas Kazlauskas <arbitrary@kazlauskas.me>", "Brian L. Troutwine <brian@troutwine.us>", "Corey Farwell <coreyf@rwell.org>"]
description = "The trait for generating structured data from unstructured data"
documentation = "https://docs.rs/arbitrary/"
readme = "README.md"
-keywords = [
- "arbitrary",
- "testing",
-]
+keywords = ["arbitrary", "testing"]
categories = ["development-tools::testing"]
-license = "MIT OR Apache-2.0"
+license = "MIT/Apache-2.0"
repository = "https://github.com/rust-fuzz/arbitrary/"
[[example]]
@@ -40,7 +31,6 @@
name = "derive"
path = "./tests/derive.rs"
required-features = ["derive"]
-
[dependencies.derive_arbitrary]
version = "1.0.0"
optional = true
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index df4e2a1..f177ed4 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "arbitrary"
-version = "1.1.0" # Make sure this matches the derive crate version
+version = "1.0.0" # Make sure this matches the derive crate version
authors = [
"The Rust-Fuzz Project Developers",
"Nick Fitzgerald <fitzgen@gmail.com>",
@@ -14,7 +14,7 @@
keywords = ["arbitrary", "testing"]
readme = "README.md"
description = "The trait for generating structured data from unstructured data"
-license = "MIT OR Apache-2.0"
+license = "MIT/Apache-2.0"
repository = "https://github.com/rust-fuzz/arbitrary/"
documentation = "https://docs.rs/arbitrary/"
diff --git a/METADATA b/METADATA
index 00cf505..1029866 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/arbitrary/arbitrary-1.1.0.crate"
+ value: "https://static.crates.io/crates/arbitrary/arbitrary-1.0.0.crate"
}
- version: "1.1.0"
+ version: "1.0.0"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 3
+ year: 2021
+ month: 4
day: 1
}
}
diff --git a/README.md b/README.md
index 38bd949..fce547a 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
## About
-The `Arbitrary` crate lets you construct arbitrary instances of a type.
+The `Arbitrary` crate lets you construct arbitrary instance of a type.
This crate is primarily intended to be combined with a fuzzer like [libFuzzer
and `cargo-fuzz`](https://github.com/rust-fuzz/cargo-fuzz) or
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index 707daa8..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,19 +0,0 @@
-// Generated by update_crate_tests.py for tests that depend on this crate.
-{
- "presubmit": [
- {
- "name": "arbitrary_test_src_lib"
- },
- {
- "name": "arbitrary_test_tests_derive"
- }
- ],
- "presubmit-rust": [
- {
- "name": "arbitrary_test_src_lib"
- },
- {
- "name": "arbitrary_test_tests_derive"
- }
- ]
-}
diff --git a/cargo2android.json b/cargo2android.json
deleted file mode 100644
index 47d3147..0000000
--- a/cargo2android.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "apex_available": [
- "com.android.uwb"
- ],
- "dependencies": true,
- "device": true,
- "features": "derive",
- "force-rlib": true,
- "min_sdk_version": "Tiramisu",
- "run": true,
- "tests": true
-}
\ No newline at end of file
diff --git a/patches/Android.bp.patch b/patches/Android.bp.patch
new file mode 100644
index 0000000..f6b7c1e
--- /dev/null
+++ b/patches/Android.bp.patch
@@ -0,0 +1,20 @@
+diff --git a/Android.bp b/Android.bp
+index fa383fd..7c098db 100644
+--- a/Android.bp
++++ b/Android.bp
+@@ -1,6 +1,6 @@
+ // This file is generated by cargo2android.py --run --dependencies --device --features derive --patch patches/Android.bp.patch.
+
+-rust_library {
++rust_library_rlib {
+ name: "libarbitrary",
+ host_supported: true,
+ crate_name: "arbitrary",
+@@ -8,7 +8,6 @@ rust_library {
+ edition: "2018",
+ features: [
+ "derive",
+- "derive_arbitrary",
+ ],
+ proc_macros: ["libderive_arbitrary"],
+ }
diff --git a/src/lib.rs b/src/lib.rs
index 7b791ab..48898a8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -37,16 +37,12 @@
use core::cell::{Cell, RefCell, UnsafeCell};
use core::iter;
use core::mem;
-use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
-use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
use core::str;
use core::time::Duration;
use std::borrow::{Cow, ToOwned};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::ffi::{CString, OsString};
-use std::hash::BuildHasher;
-use std::net::{Ipv4Addr, Ipv6Addr};
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
@@ -99,7 +95,7 @@
/// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary`
/// arbitrary implementations for each of your `struct` or `enum`'s members. But
/// sometimes you need some amount of raw data, or you need to generate a
-/// variably-sized collection type, or something of that sort. The
+/// variably-sized collection type, or you something of that sort. The
/// [`Unstructured`][crate::Unstructured] type helps you with these tasks.
///
/// ```
@@ -208,7 +204,7 @@
/// not a recursive type, or your implementation is not transitively calling
/// any other `size_hint` methods, you can ignore the `depth` parameter.
/// Note that if you are implementing `Arbitrary` for a generic type, you
- /// cannot guarantee the lack of type recursion!
+ /// cannot guarantee the lack of type recrusion!
///
/// Otherwise, you need to use
/// [`arbitrary::size_hint::recursion_guard(depth)`][crate::size_hint::recursion_guard]
@@ -349,13 +345,12 @@
impl<'a> Arbitrary<'a> for char {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
use std::char;
- // The highest unicode code point is 0x11_FFFF
- const CHAR_END: u32 = 0x11_0000;
+ const CHAR_END: u32 = 0x0011_000;
// The size of the surrogate blocks
const SURROGATES_START: u32 = 0xD800;
let mut c = <u32 as Arbitrary<'a>>::arbitrary(u)? % CHAR_END;
if let Some(c) = char::from_u32(c) {
- Ok(c)
+ return Ok(c);
} else {
// We found a surrogate, wrap and try again
c -= SURROGATES_START;
@@ -576,91 +571,61 @@
}
arbitrary_tuple!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
-// Helper to safely create arrays since the standard library doesn't
-// provide one yet. Shouldn't be necessary in the future.
-struct ArrayGuard<T, const N: usize> {
- dst: *mut T,
- initialized: usize,
-}
+macro_rules! arbitrary_array {
+ {$n:expr, ($t:ident, $a:ident) $(($ts:ident, $as:ident))*} => {
+ arbitrary_array!{($n - 1), $(($ts, $as))*}
-impl<T, const N: usize> Drop for ArrayGuard<T, N> {
- fn drop(&mut self) {
- debug_assert!(self.initialized <= N);
- let initialized_part = core::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
- unsafe {
- core::ptr::drop_in_place(initialized_part);
+ impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; $n] {
+ fn arbitrary(u: &mut Unstructured<'a>) -> Result<[T; $n]> {
+ Ok([
+ Arbitrary::arbitrary(u)?,
+ $(<$ts as Arbitrary>::arbitrary(u)?),*
+ ])
+ }
+
+ #[allow(unused_mut)]
+ fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<[T; $n]> {
+ $(let $as = $ts::arbitrary(&mut u)?;)*
+ let last = Arbitrary::arbitrary_take_rest(u)?;
+
+ Ok([
+ $($as,)* last
+ ])
+ }
+
+ #[inline]
+ fn size_hint(depth: usize) -> (usize, Option<usize>) {
+ crate::size_hint::and_all(&[
+ <$t as Arbitrary>::size_hint(depth),
+ $( <$ts as Arbitrary>::size_hint(depth) ),*
+ ])
+ }
}
- }
-}
-
-fn create_array<F, T, const N: usize>(mut cb: F) -> [T; N]
-where
- F: FnMut(usize) -> T,
-{
- let mut array: mem::MaybeUninit<[T; N]> = mem::MaybeUninit::uninit();
- let array_ptr = array.as_mut_ptr();
- let dst = array_ptr as _;
- let mut guard: ArrayGuard<T, N> = ArrayGuard {
- dst,
- initialized: 0,
};
- unsafe {
- for (idx, value_ptr) in (&mut *array.as_mut_ptr()).iter_mut().enumerate() {
- core::ptr::write(value_ptr, cb(idx));
- guard.initialized += 1;
- }
- mem::forget(guard);
- array.assume_init()
- }
+ ($n: expr,) => {};
}
-fn try_create_array<F, T, const N: usize>(mut cb: F) -> Result<[T; N]>
-where
- F: FnMut(usize) -> Result<T>,
-{
- let mut array: mem::MaybeUninit<[T; N]> = mem::MaybeUninit::uninit();
- let array_ptr = array.as_mut_ptr();
- let dst = array_ptr as _;
- let mut guard: ArrayGuard<T, N> = ArrayGuard {
- dst,
- initialized: 0,
- };
- unsafe {
- for (idx, value_ptr) in (&mut *array.as_mut_ptr()).iter_mut().enumerate() {
- core::ptr::write(value_ptr, cb(idx)?);
- guard.initialized += 1;
- }
- mem::forget(guard);
- Ok(array.assume_init())
+impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; 0] {
+ fn arbitrary(_: &mut Unstructured<'a>) -> Result<[T; 0]> {
+ Ok([])
}
-}
-impl<'a, T, const N: usize> Arbitrary<'a> for [T; N]
-where
- T: Arbitrary<'a>,
-{
- #[inline]
- fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
- try_create_array(|_| <T as Arbitrary<'a>>::arbitrary(u))
+ fn arbitrary_take_rest(_: Unstructured<'a>) -> Result<[T; 0]> {
+ Ok([])
}
#[inline]
- fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
- let mut array = Self::arbitrary(&mut u)?;
- if let Some(last) = array.last_mut() {
- *last = Arbitrary::arbitrary_take_rest(u)?;
- }
- Ok(array)
- }
-
- #[inline]
- fn size_hint(d: usize) -> (usize, Option<usize>) {
- crate::size_hint::and_all(&create_array::<_, (usize, Option<usize>), N>(|_| {
- <T as Arbitrary>::size_hint(d)
- }))
+ fn size_hint(_: usize) -> (usize, Option<usize>) {
+ crate::size_hint::and_all(&[])
}
}
+arbitrary_array! { 32, (T, a) (T, b) (T, c) (T, d) (T, e) (T, f) (T, g) (T, h)
+(T, i) (T, j) (T, k) (T, l) (T, m) (T, n) (T, o) (T, p)
+(T, q) (T, r) (T, s) (T, u) (T, v) (T, w) (T, x) (T, y)
+(T, z) (T, aa) (T, ab) (T, ac) (T, ad) (T, ae) (T, af)
+(T, ag) }
+
impl<'a> Arbitrary<'a> for &'a [u8] {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let len = u.arbitrary_len::<u8>()?;
@@ -737,8 +702,8 @@
}
}
-impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default>
- Arbitrary<'a> for HashMap<K, V, S>
+impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>> Arbitrary<'a>
+ for HashMap<K, V>
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
@@ -754,9 +719,7 @@
}
}
-impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Arbitrary<'a>
- for HashSet<A, S>
-{
+impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash> Arbitrary<'a> for HashSet<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
@@ -909,7 +872,7 @@
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
- crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
+ crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
@@ -955,7 +918,7 @@
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
- crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
+ crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
@@ -966,7 +929,7 @@
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
- crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
+ crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
@@ -1047,59 +1010,6 @@
}
}
-macro_rules! implement_nonzero_int {
- ($nonzero:ty, $int:ty) => {
- impl<'a> Arbitrary<'a> for $nonzero {
- fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
- match Self::new(<$int as Arbitrary<'a>>::arbitrary(u)?) {
- Some(n) => Ok(n),
- None => Err(Error::IncorrectFormat),
- }
- }
-
- #[inline]
- fn size_hint(depth: usize) -> (usize, Option<usize>) {
- <$int as Arbitrary<'a>>::size_hint(depth)
- }
- }
- };
-}
-
-implement_nonzero_int! { NonZeroI8, i8 }
-implement_nonzero_int! { NonZeroI16, i16 }
-implement_nonzero_int! { NonZeroI32, i32 }
-implement_nonzero_int! { NonZeroI64, i64 }
-implement_nonzero_int! { NonZeroI128, i128 }
-implement_nonzero_int! { NonZeroIsize, isize }
-implement_nonzero_int! { NonZeroU8, u8 }
-implement_nonzero_int! { NonZeroU16, u16 }
-implement_nonzero_int! { NonZeroU32, u32 }
-implement_nonzero_int! { NonZeroU64, u64 }
-implement_nonzero_int! { NonZeroU128, u128 }
-implement_nonzero_int! { NonZeroUsize, usize }
-
-impl<'a> Arbitrary<'a> for Ipv4Addr {
- fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
- Ok(Ipv4Addr::from(u32::arbitrary(u)?))
- }
-
- #[inline]
- fn size_hint(_depth: usize) -> (usize, Option<usize>) {
- (4, Some(4))
- }
-}
-
-impl<'a> Arbitrary<'a> for Ipv6Addr {
- fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
- Ok(Ipv6Addr::from(u128::arbitrary(u)?))
- }
-
- #[inline]
- fn size_hint(_depth: usize) -> (usize, Option<usize>) {
- (16, Some(16))
- }
-}
-
#[cfg(test)]
mod test {
use super::*;
diff --git a/src/unstructured.rs b/src/unstructured.rs
index ff3e1f3..9e2f497 100644
--- a/src/unstructured.rs
+++ b/src/unstructured.rs
@@ -10,7 +10,6 @@
use crate::{Arbitrary, Error, Result};
use std::marker::PhantomData;
-use std::ops::ControlFlow;
use std::{mem, ops};
/// A source of unstructured data.
@@ -222,7 +221,7 @@
}
fn arbitrary_byte_size(&mut self) -> Result<usize> {
- if self.data.is_empty() {
+ if self.data.len() == 0 {
Ok(0)
} else if self.data.len() == 1 {
self.data = &[];
@@ -323,7 +322,7 @@
let mut offset: usize = 0;
while offset < mem::size_of::<T>()
- && (range >> T::Widest::from_usize(offset * 8)) > T::Widest::ZERO
+ && (range >> T::Widest::from_usize(offset)) > T::Widest::ZERO
{
let byte = bytes.next().ok_or(Error::NotEnoughData)?;
result = (result << 8) | T::Widest::from_u8(byte);
@@ -383,41 +382,6 @@
Ok(&choices[idx])
}
- /// Generate a boolean according to the given ratio.
- ///
- /// # Panics
- ///
- /// Panics when the numerator and denominator do not meet these constraints:
- ///
- /// * `0 < numerator <= denominator`
- ///
- /// # Example
- ///
- /// Generate a boolean that is `true` five sevenths of the time:
- ///
- /// ```
- /// # fn foo() -> arbitrary::Result<()> {
- /// use arbitrary::Unstructured;
- ///
- /// # let my_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
- /// let mut u = Unstructured::new(&my_data);
- ///
- /// if u.ratio(5, 7)? {
- /// // Take this branch 5/7 of the time.
- /// }
- /// # Ok(())
- /// # }
- /// ```
- pub fn ratio<T>(&mut self, numerator: T, denominator: T) -> Result<bool>
- where
- T: Int,
- {
- assert!(T::ZERO < numerator);
- assert!(numerator <= denominator);
- let x = self.int_in_range(T::ONE..=denominator)?;
- Ok(x <= numerator)
- }
-
/// Fill a `buffer` with bytes from the underlying raw data.
///
/// This should only be called within an `Arbitrary` implementation. This is
@@ -425,8 +389,8 @@
/// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
/// `String::arbitrary` over using this method directly.
///
- /// If this `Unstructured` does not have enough underlying data to fill the
- /// whole `buffer`, it pads the buffer out with zeros.
+ /// If this `Unstructured` does not have enough data to fill the whole
+ /// `buffer`, an error is returned.
///
/// # Example
///
@@ -436,21 +400,16 @@
/// let mut u = Unstructured::new(&[1, 2, 3, 4]);
///
/// let mut buf = [0; 2];
- ///
/// assert!(u.fill_buffer(&mut buf).is_ok());
- /// assert_eq!(buf, [1, 2]);
- ///
/// assert!(u.fill_buffer(&mut buf).is_ok());
- /// assert_eq!(buf, [3, 4]);
- ///
- /// assert!(u.fill_buffer(&mut buf).is_ok());
- /// assert_eq!(buf, [0, 0]);
/// ```
pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> {
let n = std::cmp::min(buffer.len(), self.data.len());
- buffer[..n].copy_from_slice(&self.data[..n]);
- for byte in buffer[n..].iter_mut() {
- *byte = 0;
+ for i in 0..n {
+ buffer[i] = self.data[i];
+ }
+ for i in self.data.len()..buffer.len() {
+ buffer[i] = 0;
}
self.data = &self.data[n..];
Ok(())
@@ -559,100 +518,6 @@
_marker: PhantomData,
})
}
-
- /// Call the given function an arbitrary number of times.
- ///
- /// The function is given this `Unstructured` so that it can continue to
- /// generate arbitrary data and structures.
- ///
- /// You may optionaly specify minimum and maximum bounds on the number of
- /// times the function is called.
- ///
- /// You may break out of the loop early by returning
- /// `Ok(std::ops::ControlFlow::Break)`. To continue the loop, return
- /// `Ok(std::ops::ControlFlow::Continue)`.
- ///
- /// # Panics
- ///
- /// Panics if `min > max`.
- ///
- /// # Example
- ///
- /// Call a closure that generates an arbitrary type inside a context an
- /// arbitrary number of times:
- ///
- /// ```
- /// use arbitrary::{Result, Unstructured};
- /// use std::ops::ControlFlow;
- ///
- /// enum Type {
- /// /// A boolean type.
- /// Bool,
- ///
- /// /// An integer type.
- /// Int,
- ///
- /// /// A list of the `i`th type in this type's context.
- /// List(usize),
- /// }
- ///
- /// fn arbitrary_types_context(u: &mut Unstructured) -> Result<Vec<Type>> {
- /// let mut context = vec![];
- ///
- /// u.arbitrary_loop(Some(10), Some(20), |u| {
- /// let num_choices = if context.is_empty() {
- /// 2
- /// } else {
- /// 3
- /// };
- /// let ty = match u.int_in_range::<u8>(1..=num_choices)? {
- /// 1 => Type::Bool,
- /// 2 => Type::Int,
- /// 3 => Type::List(u.int_in_range(0..=context.len() - 1)?),
- /// _ => unreachable!(),
- /// };
- /// context.push(ty);
- /// Ok(ControlFlow::Continue(()))
- /// })?;
- ///
- /// // The number of loop iterations are constrained by the min/max
- /// // bounds that we provided.
- /// assert!(context.len() >= 10);
- /// assert!(context.len() <= 20);
- ///
- /// Ok(context)
- /// }
- /// ```
- pub fn arbitrary_loop(
- &mut self,
- min: Option<u32>,
- max: Option<u32>,
- mut f: impl FnMut(&mut Self) -> Result<ControlFlow<(), ()>>,
- ) -> Result<()> {
- let min = min.unwrap_or(0);
- let max = max.unwrap_or(u32::MAX);
- assert!(min <= max);
-
- for _ in 0..min {
- match f(self)? {
- ControlFlow::Continue(_) => continue,
- ControlFlow::Break(_) => return Ok(()),
- }
- }
-
- for _ in 0..(max - min) {
- let keep_going = self.arbitrary().unwrap_or(false);
- if !keep_going {
- break;
- }
- match f(self)? {
- ControlFlow::Continue(_) => continue,
- ControlFlow::Break(_) => break,
- }
- }
-
- Ok(())
- }
}
/// Utility iterator produced by [`Unstructured::arbitrary_iter`]
@@ -836,16 +701,4 @@
let choice = *u.choose(&[42]).unwrap();
assert_eq!(choice, 42)
}
-
- #[test]
- fn int_in_range_uses_minimal_amount_of_bytes() {
- let mut u = Unstructured::new(&[1]);
- u.int_in_range::<u8>(0..=u8::MAX).unwrap();
-
- let mut u = Unstructured::new(&[1]);
- u.int_in_range::<u32>(0..=u8::MAX as u32).unwrap();
-
- let mut u = Unstructured::new(&[1]);
- u.int_in_range::<u32>(0..=u8::MAX as u32 + 1).unwrap_err();
- }
}
diff --git a/tests/derive.rs b/tests/derive.rs
old mode 100755
new mode 100644
index adf1188..9dfbbd5
--- a/tests/derive.rs
+++ b/tests/derive.rs
@@ -164,7 +164,7 @@
assert_eq!("abc", lifetime.alpha);
let (lower, upper) = <OneLifetime as Arbitrary>::size_hint(0);
- assert_eq!(lower, std::mem::size_of::<usize>());
+ assert_eq!(lower, 8);
assert_eq!(upper, None);
}
@@ -183,6 +183,6 @@
assert_eq!("def", lifetime.beta);
let (lower, upper) = <TwoLifetimes as Arbitrary>::size_hint(0);
- assert_eq!(lower, std::mem::size_of::<usize>() * 2);
+ assert_eq!(lower, 16);
assert_eq!(upper, None);
}