diesel/pg/types/floats/
quickcheck_impls.rs1#![allow(clippy::cast_sign_loss)] use quickcheck::{Arbitrary, Gen};
4
5use super::PgNumeric;
6
7const SCALE_MASK: u16 = 0x3FFF;
8
9impl Arbitrary for PgNumeric {
10 fn arbitrary(g: &mut Gen) -> Self {
11 let mut variant = Option::<bool>::arbitrary(g);
12 let mut weight = -1;
13 while weight < 0 {
14 weight = i16::arbitrary(g);
16 }
17 let scale = u16::arbitrary(g) & SCALE_MASK;
18 let digits = gen_vec_of_appropriate_length_valid_digits(g, weight as u16, scale);
19 if digits.is_empty() {
20 weight = 0;
21 variant = Some(true);
22 }
23
24 match variant {
25 Some(true) => PgNumeric::Positive {
26 digits: digits,
27 weight: weight,
28 scale: scale,
29 },
30 Some(false) => PgNumeric::Negative {
31 digits: digits,
32 weight: weight,
33 scale: scale,
34 },
35 None => PgNumeric::NaN,
36 }
37 }
38}
39
40fn gen_vec_of_appropriate_length_valid_digits(g: &mut Gen, weight: u16, scale: u16) -> Vec<i16> {
41 let max_digits = ::std::cmp::min(weight, scale);
42 let mut digits = Vec::<Digit>::arbitrary(g)
43 .into_iter()
44 .map(|d| d.0)
45 .skip_while(|d| d == &0) .take(max_digits as usize)
47 .collect::<Vec<_>>();
48 while digits.last() == Some(&0) {
49 digits.pop(); }
51 digits
52}
53
54#[derive(Debug, Clone, Copy)]
55struct Digit(i16);
56
57impl Arbitrary for Digit {
58 fn arbitrary(g: &mut Gen) -> Self {
59 let mut n = -1;
60 while !(0..10_000).contains(&n) {
61 n = i16::arbitrary(g);
62 }
63 Digit(n)
64 }
65}