macro_rules! shrink_a_field {
($obj:expr, $field:ident) => { ... };
($obj:expr, $field:ident, $wrap_fn:expr, $unwrap_fn:expr) => { ... };
}
Expand description
Shrinks one field of an object.
For any object t
of type T
and a
is one of its field,
shrink_a_field!(t, a)
will result in an iterator of type T
,
whose a
fields are shrinked and the other fields are kept untouched.
For example,
use rs_quickcheck_util::shrink_a_field;
#[derive(Debug, Clone)]
struct T {
a: i64,
b: i64,
}
let t = T {
a: 100,
b: 42,
};
for x in shrink_a_field!(t, a) {
assert!(x.a < t.a);
assert_eq!(x.b, t.b);
}
Sometimes, a field must be shrinked with a different behaviour, e.g., for a Vec field, shrinking the vector but not shrinking their elements. This can be achieved by “wrapping” the field.
use rs_quickcheck_util::{shrink_a_field, Unshrinkable};
#[derive(Debug, Clone)]
struct T {
a: Vec<i64>,
}
let t = T {
a: [10, 10].into(),
};
let it = shrink_a_field!(
t,
a,
|xs: &Vec<i64>| {
xs.iter().map(|x| Unshrinkable::new(*x)).collect::<Vec<_>>()
},
|xs: Vec<Unshrinkable::<i64>>| {
xs.into_iter()
.map(|x| x.take())
.collect::<Vec<_>>()
}
);
for x in it {
assert!(x.a.iter().all(|y| *y == 10));
}