Arbitrary derive doesn't play nicely with cfg_attr
silvergasp opened this issue · comments
So I'm trying to keep the arbitrary crate as an optional dependency for a project. So I'd like to conditionally derive the arbitrary implementation e.g.
#[derive(Clone, Debug, Deserialize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Number {
Int(i64),
Float(f64),
Decimal(BigDecimal),
}
This works fine when every var/enum variant also implements derive (or I can implement it manually). However in this case bigdecimal::BigDecimal
is in an external crate that I don't have control over so I'd like to be able to do something like this;
#[derive(Clone, Debug, Deserialize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Number {
Int(i64),
Float(f64),
#[cfg_attr(feature = "arbitrary", arbitrary(with = |u: &mut Unstructured| BigDecimal::from(u64::arbitrary(&mut u))))]
Decimal(BigDecimal),
}
Where I conditionally enable lambda implementation for that variant type. However for whatever reason this doesn't actually work and I get an error like;
27 | #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
| ^^^^^^^^^^^^^^^^^^^^ the trait `Arbitrary<'_>` is not implemented for `BigDecimal`
Hm, that's strange, cfg_attr
is handled by the compiler and the proc macro has no visibility of that in the first place.
The cfg_attr is a red herring, the with
is simply not working. I don't know why.
Oh weird, perhaps it's just because it's an enum variant. To be honest I haven't tried using that attribute with an enum before, only structs. I'll investigate a little further.
Oh!
The attribute needs to be on the field, not the variant.
That explains that.
We should perhaps throw an error if you use #[arbitrary(with)]
on a variant.
Closing as works-as-intended, but filed #150 for the diagnostics (and potentially making the case you laid out automatic)
Thanks for reporting!
No worries thanks for being so responsive!