#Can you derive(Serialize) only if a dependent type T is Serialize?
15 messages · Page 1 of 1 (latest)
I think this is how it works by default.
oh wow
I can't believe this just worked
... I didn't try to just do it 😛
I just assumed that #derive would try to generate the trait and fail if T isn't Serialize
okay how do I close this shameful thread? Thanks though 🙂
Idk if you can, but it'll expire after a while automatically
There is one case of an issue I've run into: It's smart enough to work it out if it just requires the derived trait, but if it requires some other trait for checking equality (e.g. HashMap requiring BuildHasher be implemented for its S type), you'll have to implement it by hand...
yeah there’s all sorts of limitations with derive macros
thankfully they work 95% of the time
Tbh you can make it work 100% of the time by tricking it into writing the bounds for the field types rather than the generic parameters (which the derive since it's kind of a more cautious default overall, but you can decide to push things further than the default)
The easiest way to do this is with more customizable derives, such as https://docs.rs/derivative
API documentation for the Rust derivative crate.
Another option is to still use the stdlib derive, but with a helper internal data structure:
#[derive(YourDerivesHere)]
pub struct GridFields<Tiles, Default, Width, Height> {
tiles: Tiles,
default: Default,
width: Width,
height: Height,
}
pub type Grid<T> = GridFields<
Vec<T>,
T,
i32,
i32,
>;
this tricks the derive into writing:
impl<…> Trait for Grid<T>
where
// Bounds of fields!!
Vec<T> : Trait,
T : Trait,
i32 : Trait,
i32 : Trait,
{
rather than:
impl<…> Trait for Grid<T>
where
// Bounds on generics by default
T : Trait,
{
so it works even with more complex trait implications (such as the aforementioned HashMap example)