/rust/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.0.0/src/unstructured.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright © 2019 The Rust Fuzz Project Developers. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
6 | | // option. This file may not be copied, modified, or distributed |
7 | | // except according to those terms. |
8 | | |
9 | | //! Wrappers around raw, unstructured bytes. |
10 | | |
11 | | use crate::{Arbitrary, Error, Result}; |
12 | | use std::marker::PhantomData; |
13 | | use std::{mem, ops}; |
14 | | |
15 | | /// A source of unstructured data. |
16 | | /// |
17 | | /// An `Unstructured` helps `Arbitrary` implementations interpret raw data |
18 | | /// (typically provided by a fuzzer) as a "DNA string" that describes how to |
19 | | /// construct the `Arbitrary` type. The goal is that a small change to the "DNA |
20 | | /// string" (the raw data wrapped by an `Unstructured`) results in a small |
21 | | /// change to the generated `Arbitrary` instance. This helps a fuzzer |
22 | | /// efficiently explore the `Arbitrary`'s input space. |
23 | | /// |
24 | | /// `Unstructured` is deterministic: given the same raw data, the same series of |
25 | | /// API calls will return the same results (modulo system resource constraints, |
26 | | /// like running out of memory). However, `Unstructured` does not guarantee |
27 | | /// anything beyond that: it makes not guarantee that it will yield bytes from |
28 | | /// the underlying data in any particular order. |
29 | | /// |
30 | | /// You shouldn't generally need to use an `Unstructured` unless you are writing |
31 | | /// a custom `Arbitrary` implementation by hand, instead of deriving it. Mostly, |
32 | | /// you should just be passing it through to nested `Arbitrary::arbitrary` |
33 | | /// calls. |
34 | | /// |
35 | | /// # Example |
36 | | /// |
37 | | /// Imagine you were writing a color conversion crate. You might want to write |
38 | | /// fuzz tests that take a random RGB color and assert various properties, run |
39 | | /// functions and make sure nothing panics, etc. |
40 | | /// |
41 | | /// Below is what translating the fuzzer's raw input into an `Unstructured` and |
42 | | /// using that to generate an arbitrary RGB color might look like: |
43 | | /// |
44 | | /// ``` |
45 | | /// # #[cfg(feature = "derive")] fn foo() { |
46 | | /// use arbitrary::{Arbitrary, Unstructured}; |
47 | | /// |
48 | | /// /// An RGB color. |
49 | | /// #[derive(Arbitrary)] |
50 | | /// pub struct Rgb { |
51 | | /// r: u8, |
52 | | /// g: u8, |
53 | | /// b: u8, |
54 | | /// } |
55 | | /// |
56 | | /// // Get the raw bytes from the fuzzer. |
57 | | /// # let get_input_from_fuzzer = || &[]; |
58 | | /// let raw_data: &[u8] = get_input_from_fuzzer(); |
59 | | /// |
60 | | /// // Wrap it in an `Unstructured`. |
61 | | /// let mut unstructured = Unstructured::new(raw_data); |
62 | | /// |
63 | | /// // Generate an `Rgb` color and run our checks. |
64 | | /// if let Ok(rgb) = Rgb::arbitrary(&mut unstructured) { |
65 | | /// # let run_my_color_conversion_checks = |_| {}; |
66 | | /// run_my_color_conversion_checks(rgb); |
67 | | /// } |
68 | | /// # } |
69 | | /// ``` |
70 | | pub struct Unstructured<'a> { |
71 | | data: &'a [u8], |
72 | | } |
73 | | |
74 | | impl<'a> Unstructured<'a> { |
75 | | /// Create a new `Unstructured` from the given raw data. |
76 | | /// |
77 | | /// # Example |
78 | | /// |
79 | | /// ``` |
80 | | /// use arbitrary::Unstructured; |
81 | | /// |
82 | | /// let u = Unstructured::new(&[1, 2, 3, 4]); |
83 | | /// ``` |
84 | 7.50k | pub fn new(data: &'a [u8]) -> Self { |
85 | 7.50k | Unstructured { data } |
86 | 7.50k | } |
87 | | |
88 | | /// Get the number of remaining bytes of underlying data that are still |
89 | | /// available. |
90 | | /// |
91 | | /// # Example |
92 | | /// |
93 | | /// ``` |
94 | | /// use arbitrary::{Arbitrary, Unstructured}; |
95 | | /// |
96 | | /// let mut u = Unstructured::new(&[1, 2, 3]); |
97 | | /// |
98 | | /// // Initially have three bytes of data. |
99 | | /// assert_eq!(u.len(), 3); |
100 | | /// |
101 | | /// // Generating a `bool` consumes one byte from the underlying data, so |
102 | | /// // we are left with two bytes afterwards. |
103 | | /// let _ = bool::arbitrary(&mut u); |
104 | | /// assert_eq!(u.len(), 2); |
105 | | /// ``` |
106 | | #[inline] |
107 | 0 | pub fn len(&self) -> usize { |
108 | 0 | self.data.len() |
109 | 0 | } |
110 | | |
111 | | /// Is the underlying unstructured data exhausted? |
112 | | /// |
113 | | /// `unstructured.is_empty()` is the same as `unstructured.len() == 0`. |
114 | | /// |
115 | | /// # Example |
116 | | /// |
117 | | /// ``` |
118 | | /// use arbitrary::{Arbitrary, Unstructured}; |
119 | | /// |
120 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4]); |
121 | | /// |
122 | | /// // Initially, we are not empty. |
123 | | /// assert!(!u.is_empty()); |
124 | | /// |
125 | | /// // Generating a `u32` consumes all four bytes of the underlying data, so |
126 | | /// // we become empty afterwards. |
127 | | /// let _ = u32::arbitrary(&mut u); |
128 | | /// assert!(u.is_empty()); |
129 | | /// ``` |
130 | | #[inline] |
131 | 0 | pub fn is_empty(&self) -> bool { |
132 | 0 | self.len() == 0 |
133 | 0 | } |
134 | | |
135 | | /// Generate an arbitrary instance of `A`. |
136 | | /// |
137 | | /// This is simply a helper method that is equivalent to `<A as |
138 | | /// Arbitrary>::arbitrary(self)`. This helper is a little bit more concise, |
139 | | /// and can be used in situations where Rust's type inference will figure |
140 | | /// out what `A` should be. |
141 | | /// |
142 | | /// # Example |
143 | | /// |
144 | | /// ``` |
145 | | /// # #[cfg(feature="derive")] fn foo() -> arbitrary::Result<()> { |
146 | | /// use arbitrary::{Arbitrary, Unstructured}; |
147 | | /// |
148 | | /// #[derive(Arbitrary)] |
149 | | /// struct MyType { |
150 | | /// // ... |
151 | | /// } |
152 | | /// |
153 | | /// fn do_stuff(value: MyType) { |
154 | | /// # let _ = value; |
155 | | /// // ... |
156 | | /// } |
157 | | /// |
158 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4]); |
159 | | /// |
160 | | /// // Rust's type inference can figure out that `value` should be of type |
161 | | /// // `MyType` here: |
162 | | /// let value = u.arbitrary()?; |
163 | | /// do_stuff(value); |
164 | | /// # Ok(()) } |
165 | | /// ``` |
166 | 0 | pub fn arbitrary<A>(&mut self) -> Result<A> |
167 | 0 | where |
168 | 0 | A: Arbitrary<'a>, |
169 | 0 | { |
170 | 0 | <A as Arbitrary<'a>>::arbitrary(self) |
171 | 0 | } |
172 | | |
173 | | /// Get the number of elements to insert when building up a collection of |
174 | | /// arbitrary `ElementType`s. |
175 | | /// |
176 | | /// This uses the [`<ElementType as |
177 | | /// Arbitrary>::size_hint`][crate::Arbitrary::size_hint] method to smartly |
178 | | /// choose a length such that we most likely have enough underlying bytes to |
179 | | /// construct that many arbitrary `ElementType`s. |
180 | | /// |
181 | | /// This should only be called within an `Arbitrary` implementation. |
182 | | /// |
183 | | /// # Example |
184 | | /// |
185 | | /// ``` |
186 | | /// use arbitrary::{Arbitrary, Result, Unstructured}; |
187 | | /// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> } |
188 | | /// # impl<T> MyCollection<T> { |
189 | | /// # pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: std::marker::PhantomData } } |
190 | | /// # pub fn insert(&mut self, element: T) {} |
191 | | /// # } |
192 | | /// |
193 | | /// impl<'a, T> Arbitrary<'a> for MyCollection<T> |
194 | | /// where |
195 | | /// T: Arbitrary<'a>, |
196 | | /// { |
197 | | /// fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { |
198 | | /// // Get the number of `T`s we should insert into our collection. |
199 | | /// let len = u.arbitrary_len::<T>()?; |
200 | | /// |
201 | | /// // And then create a collection of that length! |
202 | | /// let mut my_collection = MyCollection::with_capacity(len); |
203 | | /// for _ in 0..len { |
204 | | /// let element = T::arbitrary(u)?; |
205 | | /// my_collection.insert(element); |
206 | | /// } |
207 | | /// |
208 | | /// Ok(my_collection) |
209 | | /// } |
210 | | /// } |
211 | | /// ``` |
212 | 0 | pub fn arbitrary_len<ElementType>(&mut self) -> Result<usize> |
213 | 0 | where |
214 | 0 | ElementType: Arbitrary<'a>, |
215 | 0 | { |
216 | 0 | let byte_size = self.arbitrary_byte_size()?; |
217 | 0 | let (lower, upper) = <ElementType as Arbitrary>::size_hint(0); |
218 | 0 | let elem_size = upper.unwrap_or_else(|| lower * 2); |
219 | 0 | let elem_size = std::cmp::max(1, elem_size); |
220 | 0 | Ok(byte_size / elem_size) |
221 | 0 | } |
222 | | |
223 | 0 | fn arbitrary_byte_size(&mut self) -> Result<usize> { |
224 | 0 | if self.data.len() == 0 { |
225 | 0 | Ok(0) |
226 | 0 | } else if self.data.len() == 1 { |
227 | 0 | self.data = &[]; |
228 | 0 | Ok(0) |
229 | | } else { |
230 | | // Take lengths from the end of the data, since the `libFuzzer` folks |
231 | | // found that this lets fuzzers more efficiently explore the input |
232 | | // space. |
233 | | // |
234 | | // https://github.com/rust-fuzz/libfuzzer-sys/blob/0c450753/libfuzzer/utils/FuzzedDataProvider.h#L92-L97 |
235 | | |
236 | | // We only consume as many bytes as necessary to cover the entire |
237 | | // range of the byte string. |
238 | 0 | let len = if self.data.len() <= std::u8::MAX as usize + 1 { |
239 | 0 | let bytes = 1; |
240 | 0 | let max_size = self.data.len() - bytes; |
241 | 0 | let (rest, for_size) = self.data.split_at(max_size); |
242 | 0 | self.data = rest; |
243 | 0 | Self::int_in_range_impl(0..=max_size as u8, for_size.iter().copied())?.0 as usize |
244 | 0 | } else if self.data.len() <= std::u16::MAX as usize + 1 { |
245 | 0 | let bytes = 2; |
246 | 0 | let max_size = self.data.len() - bytes; |
247 | 0 | let (rest, for_size) = self.data.split_at(max_size); |
248 | 0 | self.data = rest; |
249 | 0 | Self::int_in_range_impl(0..=max_size as u16, for_size.iter().copied())?.0 as usize |
250 | 0 | } else if self.data.len() <= std::u32::MAX as usize + 1 { |
251 | 0 | let bytes = 4; |
252 | 0 | let max_size = self.data.len() - bytes; |
253 | 0 | let (rest, for_size) = self.data.split_at(max_size); |
254 | 0 | self.data = rest; |
255 | 0 | Self::int_in_range_impl(0..=max_size as u32, for_size.iter().copied())?.0 as usize |
256 | | } else { |
257 | 0 | let bytes = 8; |
258 | 0 | let max_size = self.data.len() - bytes; |
259 | 0 | let (rest, for_size) = self.data.split_at(max_size); |
260 | 0 | self.data = rest; |
261 | 0 | Self::int_in_range_impl(0..=max_size as u64, for_size.iter().copied())?.0 as usize |
262 | | }; |
263 | | |
264 | 0 | Ok(len) |
265 | | } |
266 | 0 | } |
267 | | |
268 | | /// Generate an integer within the given range. |
269 | | /// |
270 | | /// Do not use this to generate the size of a collection. Use |
271 | | /// `arbitrary_len` instead. |
272 | | /// |
273 | | /// # Panics |
274 | | /// |
275 | | /// Panics if `range.start >= range.end`. That is, the given range must be |
276 | | /// non-empty. |
277 | | /// |
278 | | /// # Example |
279 | | /// |
280 | | /// ``` |
281 | | /// use arbitrary::{Arbitrary, Unstructured}; |
282 | | /// |
283 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4]); |
284 | | /// |
285 | | /// let x: i32 = u.int_in_range(-5_000..=-1_000) |
286 | | /// .expect("constructed `u` with enough bytes to generate an `i32`"); |
287 | | /// |
288 | | /// assert!(-5_000 <= x); |
289 | | /// assert!(x <= -1_000); |
290 | | /// ``` |
291 | 0 | pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T> |
292 | 0 | where |
293 | 0 | T: Int, |
294 | 0 | { |
295 | 0 | let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?; |
296 | 0 | self.data = &self.data[bytes_consumed..]; |
297 | 0 | Ok(result) |
298 | 0 | } |
299 | | |
300 | 0 | fn int_in_range_impl<T>( |
301 | 0 | range: ops::RangeInclusive<T>, |
302 | 0 | mut bytes: impl Iterator<Item = u8>, |
303 | 0 | ) -> Result<(T, usize)> |
304 | 0 | where |
305 | 0 | T: Int, |
306 | 0 | { |
307 | 0 | let start = range.start(); |
308 | 0 | let end = range.end(); |
309 | 0 | assert!( |
310 | 0 | start <= end, |
311 | 0 | "`arbitrary::Unstructured::int_in_range` requires a non-empty range" |
312 | 0 | ); |
313 | | |
314 | | // When there is only one possible choice, don't waste any entropy from |
315 | | // the underlying data. |
316 | 0 | if start == end { |
317 | 0 | return Ok((*start, 0)); |
318 | 0 | } |
319 | 0 |
|
320 | 0 | let range: T::Widest = end.as_widest() - start.as_widest(); |
321 | 0 | let mut result = T::Widest::ZERO; |
322 | 0 | let mut offset: usize = 0; |
323 | | |
324 | 0 | while offset < mem::size_of::<T>() |
325 | 0 | && (range >> T::Widest::from_usize(offset)) > T::Widest::ZERO |
326 | | { |
327 | 0 | let byte = bytes.next().ok_or(Error::NotEnoughData)?; |
328 | 0 | result = (result << 8) | T::Widest::from_u8(byte); |
329 | 0 | offset += 1; |
330 | | } |
331 | | |
332 | | // Avoid division by zero. |
333 | 0 | if let Some(range) = range.checked_add(T::Widest::ONE) { |
334 | 0 | result = result % range; |
335 | 0 | } |
336 | | |
337 | 0 | Ok(( |
338 | 0 | T::from_widest(start.as_widest().wrapping_add(result)), |
339 | 0 | offset, |
340 | 0 | )) |
341 | 0 | } Unexecuted instantiation: <arbitrary::unstructured::Unstructured>::int_in_range_impl::<u8, core::iter::adapters::copied::Copied<core::slice::iter::Iter<u8>>> Unexecuted instantiation: <arbitrary::unstructured::Unstructured>::int_in_range_impl::<u32, core::iter::adapters::cloned::Cloned<core::slice::iter::Iter<u8>>> Unexecuted instantiation: <arbitrary::unstructured::Unstructured>::int_in_range_impl::<u32, core::iter::adapters::copied::Copied<core::slice::iter::Iter<u8>>> Unexecuted instantiation: <arbitrary::unstructured::Unstructured>::int_in_range_impl::<u16, core::iter::adapters::copied::Copied<core::slice::iter::Iter<u8>>> Unexecuted instantiation: <arbitrary::unstructured::Unstructured>::int_in_range_impl::<u64, core::iter::adapters::copied::Copied<core::slice::iter::Iter<u8>>> |
342 | | |
343 | | /// Choose one of the given choices. |
344 | | /// |
345 | | /// This should only be used inside of `Arbitrary` implementations. |
346 | | /// |
347 | | /// Returns an error if there is not enough underlying data to make a |
348 | | /// choice or if no choices are provided. |
349 | | /// |
350 | | /// # Examples |
351 | | /// |
352 | | /// Selecting from an array of choices: |
353 | | /// |
354 | | /// ``` |
355 | | /// use arbitrary::Unstructured; |
356 | | /// |
357 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); |
358 | | /// let choices = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; |
359 | | /// |
360 | | /// let choice = u.choose(&choices).unwrap(); |
361 | | /// |
362 | | /// println!("chose {}", choice); |
363 | | /// ``` |
364 | | /// |
365 | | /// An error is returned if no choices are provided: |
366 | | /// |
367 | | /// ``` |
368 | | /// use arbitrary::Unstructured; |
369 | | /// |
370 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); |
371 | | /// let choices: [char; 0] = []; |
372 | | /// |
373 | | /// let result = u.choose(&choices); |
374 | | /// |
375 | | /// assert!(result.is_err()); |
376 | | /// ``` |
377 | 0 | pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> { |
378 | 0 | if choices.is_empty() { |
379 | 0 | return Err(Error::EmptyChoose); |
380 | 0 | } |
381 | 0 | let idx = self.int_in_range(0..=choices.len() - 1)?; |
382 | 0 | Ok(&choices[idx]) |
383 | 0 | } |
384 | | |
385 | | /// Fill a `buffer` with bytes from the underlying raw data. |
386 | | /// |
387 | | /// This should only be called within an `Arbitrary` implementation. This is |
388 | | /// a very low-level operation. You should generally prefer calling nested |
389 | | /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and |
390 | | /// `String::arbitrary` over using this method directly. |
391 | | /// |
392 | | /// If this `Unstructured` does not have enough data to fill the whole |
393 | | /// `buffer`, an error is returned. |
394 | | /// |
395 | | /// # Example |
396 | | /// |
397 | | /// ``` |
398 | | /// use arbitrary::Unstructured; |
399 | | /// |
400 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4]); |
401 | | /// |
402 | | /// let mut buf = [0; 2]; |
403 | | /// assert!(u.fill_buffer(&mut buf).is_ok()); |
404 | | /// assert!(u.fill_buffer(&mut buf).is_ok()); |
405 | | /// ``` |
406 | 0 | pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> { |
407 | 0 | let n = std::cmp::min(buffer.len(), self.data.len()); |
408 | 0 | for i in 0..n { |
409 | 0 | buffer[i] = self.data[i]; |
410 | 0 | } |
411 | 0 | for i in self.data.len()..buffer.len() { |
412 | 0 | buffer[i] = 0; |
413 | 0 | } |
414 | 0 | self.data = &self.data[n..]; |
415 | 0 | Ok(()) |
416 | 0 | } |
417 | | |
418 | | /// Provide `size` bytes from the underlying raw data. |
419 | | /// |
420 | | /// This should only be called within an `Arbitrary` implementation. This is |
421 | | /// a very low-level operation. You should generally prefer calling nested |
422 | | /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and |
423 | | /// `String::arbitrary` over using this method directly. |
424 | | /// |
425 | | /// # Example |
426 | | /// |
427 | | /// ``` |
428 | | /// use arbitrary::Unstructured; |
429 | | /// |
430 | | /// let mut u = Unstructured::new(&[1, 2, 3, 4]); |
431 | | /// |
432 | | /// assert!(u.bytes(2).unwrap() == &[1, 2]); |
433 | | /// assert!(u.bytes(2).unwrap() == &[3, 4]); |
434 | | /// ``` |
435 | 0 | pub fn bytes(&mut self, size: usize) -> Result<&'a [u8]> { |
436 | 0 | if self.data.len() < size { |
437 | 0 | return Err(Error::NotEnoughData); |
438 | 0 | } |
439 | 0 |
|
440 | 0 | let (for_buf, rest) = self.data.split_at(size); |
441 | 0 | self.data = rest; |
442 | 0 | Ok(for_buf) |
443 | 0 | } |
444 | | |
445 | | /// Peek at `size` number of bytes of the underlying raw input. |
446 | | /// |
447 | | /// Does not consume the bytes, only peeks at them. |
448 | | /// |
449 | | /// Returns `None` if there are not `size` bytes left in the underlying raw |
450 | | /// input. |
451 | | /// |
452 | | /// # Example |
453 | | /// |
454 | | /// ``` |
455 | | /// use arbitrary::Unstructured; |
456 | | /// |
457 | | /// let u = Unstructured::new(&[1, 2, 3]); |
458 | | /// |
459 | | /// assert_eq!(u.peek_bytes(0).unwrap(), []); |
460 | | /// assert_eq!(u.peek_bytes(1).unwrap(), [1]); |
461 | | /// assert_eq!(u.peek_bytes(2).unwrap(), [1, 2]); |
462 | | /// assert_eq!(u.peek_bytes(3).unwrap(), [1, 2, 3]); |
463 | | /// |
464 | | /// assert!(u.peek_bytes(4).is_none()); |
465 | | /// ``` |
466 | 0 | pub fn peek_bytes(&self, size: usize) -> Option<&'a [u8]> { |
467 | 0 | self.data.get(..size) |
468 | 0 | } |
469 | | |
470 | | /// Consume all of the rest of the remaining underlying bytes. |
471 | | /// |
472 | | /// Returns a slice of all the remaining, unconsumed bytes. |
473 | | /// |
474 | | /// # Example |
475 | | /// |
476 | | /// ``` |
477 | | /// use arbitrary::Unstructured; |
478 | | /// |
479 | | /// let mut u = Unstructured::new(&[1, 2, 3]); |
480 | | /// |
481 | | /// let mut remaining = u.take_rest(); |
482 | | /// |
483 | | /// assert_eq!(remaining, [1, 2, 3]); |
484 | | /// ``` |
485 | 7.50k | pub fn take_rest(mut self) -> &'a [u8] { |
486 | 7.50k | mem::replace(&mut self.data, &[]) |
487 | 7.50k | } |
488 | | |
489 | | /// Provide an iterator over elements for constructing a collection |
490 | | /// |
491 | | /// This is useful for implementing [`Arbitrary::arbitrary`] on collections |
492 | | /// since the implementation is simply `u.arbitrary_iter()?.collect()` |
493 | 0 | pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>( |
494 | 0 | &'b mut self, |
495 | 0 | ) -> Result<ArbitraryIter<'a, 'b, ElementType>> { |
496 | 0 | Ok(ArbitraryIter { |
497 | 0 | u: &mut *self, |
498 | 0 | _marker: PhantomData, |
499 | 0 | }) |
500 | 0 | } |
501 | | |
502 | | /// Provide an iterator over elements for constructing a collection from |
503 | | /// all the remaining bytes. |
504 | | /// |
505 | | /// This is useful for implementing [`Arbitrary::arbitrary_take_rest`] on collections |
506 | | /// since the implementation is simply `u.arbitrary_take_rest_iter()?.collect()` |
507 | 0 | pub fn arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>( |
508 | 0 | self, |
509 | 0 | ) -> Result<ArbitraryTakeRestIter<'a, ElementType>> { |
510 | 0 | let (lower, upper) = ElementType::size_hint(0); |
511 | 0 |
|
512 | 0 | let elem_size = upper.unwrap_or(lower * 2); |
513 | 0 | let elem_size = std::cmp::max(1, elem_size); |
514 | 0 | let size = self.len() / elem_size; |
515 | 0 | Ok(ArbitraryTakeRestIter { |
516 | 0 | size, |
517 | 0 | u: Some(self), |
518 | 0 | _marker: PhantomData, |
519 | 0 | }) |
520 | 0 | } |
521 | | } |
522 | | |
523 | | /// Utility iterator produced by [`Unstructured::arbitrary_iter`] |
524 | | pub struct ArbitraryIter<'a, 'b, ElementType> { |
525 | | u: &'b mut Unstructured<'a>, |
526 | | _marker: PhantomData<ElementType>, |
527 | | } |
528 | | |
529 | | impl<'a, 'b, ElementType: Arbitrary<'a>> Iterator for ArbitraryIter<'a, 'b, ElementType> { |
530 | | type Item = Result<ElementType>; |
531 | 0 | fn next(&mut self) -> Option<Result<ElementType>> { |
532 | 0 | let keep_going = self.u.arbitrary().unwrap_or(false); |
533 | 0 | if keep_going { |
534 | 0 | Some(Arbitrary::arbitrary(self.u)) |
535 | | } else { |
536 | 0 | None |
537 | | } |
538 | 0 | } |
539 | | } |
540 | | |
541 | | /// Utility iterator produced by [`Unstructured::arbitrary_take_rest_iter`] |
542 | | pub struct ArbitraryTakeRestIter<'a, ElementType> { |
543 | | u: Option<Unstructured<'a>>, |
544 | | size: usize, |
545 | | _marker: PhantomData<ElementType>, |
546 | | } |
547 | | |
548 | | impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, ElementType> { |
549 | | type Item = Result<ElementType>; |
550 | 0 | fn next(&mut self) -> Option<Result<ElementType>> { |
551 | 0 | if let Some(mut u) = self.u.take() { |
552 | 0 | if self.size == 1 { |
553 | 0 | Some(Arbitrary::arbitrary_take_rest(u)) |
554 | 0 | } else if self.size == 0 { |
555 | 0 | None |
556 | | } else { |
557 | 0 | self.size -= 1; |
558 | 0 | let ret = Arbitrary::arbitrary(&mut u); |
559 | 0 | self.u = Some(u); |
560 | 0 | Some(ret) |
561 | | } |
562 | | } else { |
563 | 0 | None |
564 | | } |
565 | 0 | } |
566 | | } |
567 | | |
568 | | /// A trait that is implemented for all of the primitive integers: |
569 | | /// |
570 | | /// * `u8` |
571 | | /// * `u16` |
572 | | /// * `u32` |
573 | | /// * `u64` |
574 | | /// * `u128` |
575 | | /// * `usize` |
576 | | /// * `i8` |
577 | | /// * `i16` |
578 | | /// * `i32` |
579 | | /// * `i64` |
580 | | /// * `i128` |
581 | | /// * `isize` |
582 | | /// |
583 | | /// Don't implement this trait yourself. |
584 | | pub trait Int: |
585 | | Copy |
586 | | + PartialOrd |
587 | | + Ord |
588 | | + ops::Sub<Self, Output = Self> |
589 | | + ops::Rem<Self, Output = Self> |
590 | | + ops::Shr<Self, Output = Self> |
591 | | + ops::Shl<usize, Output = Self> |
592 | | + ops::BitOr<Self, Output = Self> |
593 | | { |
594 | | #[doc(hidden)] |
595 | | type Widest: Int; |
596 | | |
597 | | #[doc(hidden)] |
598 | | const ZERO: Self; |
599 | | |
600 | | #[doc(hidden)] |
601 | | const ONE: Self; |
602 | | |
603 | | #[doc(hidden)] |
604 | | fn as_widest(self) -> Self::Widest; |
605 | | |
606 | | #[doc(hidden)] |
607 | | fn from_widest(w: Self::Widest) -> Self; |
608 | | |
609 | | #[doc(hidden)] |
610 | | fn from_u8(b: u8) -> Self; |
611 | | |
612 | | #[doc(hidden)] |
613 | | fn from_usize(u: usize) -> Self; |
614 | | |
615 | | #[doc(hidden)] |
616 | | fn checked_add(self, rhs: Self) -> Option<Self>; |
617 | | |
618 | | #[doc(hidden)] |
619 | | fn wrapping_add(self, rhs: Self) -> Self; |
620 | | } |
621 | | |
622 | | macro_rules! impl_int { |
623 | | ( $( $ty:ty : $widest:ty ; )* ) => { |
624 | | $( |
625 | | impl Int for $ty { |
626 | | type Widest = $widest; |
627 | | |
628 | | const ZERO: Self = 0; |
629 | | |
630 | | const ONE: Self = 1; |
631 | | |
632 | 0 | fn as_widest(self) -> Self::Widest { |
633 | 0 | self as $widest |
634 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::as_widest Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::as_widest |
635 | | |
636 | 0 | fn from_widest(w: Self::Widest) -> Self { |
637 | 0 | let x = <$ty>::max_value().as_widest(); |
638 | 0 | (w % x) as Self |
639 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::from_widest Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::from_widest |
640 | | |
641 | 0 | fn from_u8(b: u8) -> Self { |
642 | 0 | b as Self |
643 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::from_u8 Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::from_u8 |
644 | | |
645 | 0 | fn from_usize(u: usize) -> Self { |
646 | 0 | u as Self |
647 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::from_usize Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::from_usize |
648 | | |
649 | 0 | fn checked_add(self, rhs: Self) -> Option<Self> { |
650 | 0 | <$ty>::checked_add(self, rhs) |
651 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::checked_add Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::checked_add |
652 | | |
653 | 0 | fn wrapping_add(self, rhs: Self) -> Self { |
654 | 0 | <$ty>::wrapping_add(self, rhs) |
655 | 0 | } Unexecuted instantiation: <u8 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <u16 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <u32 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <u64 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <u128 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <usize as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <i8 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <i16 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <i32 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <i64 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <i128 as arbitrary::unstructured::Int>::wrapping_add Unexecuted instantiation: <isize as arbitrary::unstructured::Int>::wrapping_add |
656 | | } |
657 | | )* |
658 | | } |
659 | | } |
660 | | |
661 | | impl_int! { |
662 | | u8: u128; |
663 | | u16: u128; |
664 | | u32: u128; |
665 | | u64: u128; |
666 | | u128: u128; |
667 | | usize: u128; |
668 | | i8: i128; |
669 | | i16: i128; |
670 | | i32: i128; |
671 | | i64: i128; |
672 | | i128: i128; |
673 | | isize: i128; |
674 | | } |
675 | | |
676 | | #[cfg(test)] |
677 | | mod tests { |
678 | | use super::*; |
679 | | |
680 | | #[test] |
681 | | fn test_byte_size() { |
682 | | let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]); |
683 | | // Should take one byte off the end |
684 | | assert_eq!(u.arbitrary_byte_size().unwrap(), 6); |
685 | | assert_eq!(u.len(), 9); |
686 | | let mut v = vec![]; |
687 | | v.resize(260, 0); |
688 | | v.push(1); |
689 | | v.push(4); |
690 | | let mut u = Unstructured::new(&v); |
691 | | // Should read two bytes off the end |
692 | | assert_eq!(u.arbitrary_byte_size().unwrap(), 0x104); |
693 | | assert_eq!(u.len(), 260); |
694 | | } |
695 | | |
696 | | #[test] |
697 | | fn int_in_range_of_one() { |
698 | | let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]); |
699 | | let x = u.int_in_range(0..=0).unwrap(); |
700 | | assert_eq!(x, 0); |
701 | | let choice = *u.choose(&[42]).unwrap(); |
702 | | assert_eq!(choice, 42) |
703 | | } |
704 | | } |