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