nutype icon indicating copy to clipboard operation
nutype copied to clipboard

Conditional derive

Open lecanard539 opened this issue 1 year ago β€’ 6 comments

When implementing REST API clients, I usually derive Serialize and Default conditionally for tests, like so:

#[derive(Debug, Deserialize)]
#[cfg_attr(test, derive(Serialize, Default))]
pub struct SlavaUkraini {
    pub field: String,
    pub something: u64,
}

This enables me to use Default and Serialize in tests to easily and quickly instantiate mock responses, while at the same time keeping the prod binary smaller and prod compile times lower. Unfortunately conditional derive doesn't currently seem possible in nutype.

Would it be possible to enable nutype to do something similar? Like

#[nutype(derive(Debug, Deserialize, AsRef), cfg_attr(test, derive(Default, Serialize))]
pub struct HeroyamSlava(String);

#[derive(Debug, Deserialize)]
#[cfg_attr(test, derive(Serialize, Default))]
pub struct SlavaUkraini {
    pub field: HeroyamSlava,
    pub something: u64,
}

Or maybe

#[nutype(derive(Debug, Deserialize, AsRef)]
#[cfg_attr(test, nutype(derive(Default, Serialize))]
pub struct HeroyamSlava(String);

Whatever makes the most sense. I am a complete noob when it comes to Rust macros, and proc macros especially, so no idea what the best solution would be.

This request is not super important, as it works just fine without the conditional derive, it would just be nice to have.

Actually now that I think about it, it would also be nice to have this for libraries wanting to conditionally derive on feature flags, not just on tests.

lecanard539 avatar Oct 03 '24 07:10 lecanard539

Hi! I knew this is gonna be requested some day, this day has come :)

Technically there is nothing that limits us to implement it, it will just require some effort though. Whatever goes into #[nutype()] is pure DSL.

greyblake avatar Oct 09 '24 20:10 greyblake

Is there a reason why you can't just let the user add separate derives?

musjj avatar Oct 23 '24 19:10 musjj

Is there a reason why you can't just let the user add separate derives?

Answered in https://github.com/greyblake/nutype/issues/191#issuecomment-2434690325

I copy answer here for other readers:

Nutype takes a full control over derive(..) to ensure that it's not possible to derive traits that possibly can mutate value avoiding the constraints. E.g. deriving DerefMut would make a problem.

I guess I need to add an FAQ section

greyblake avatar Oct 29 '24 10:10 greyblake

Hi! I knew this is gonna be requested some day, this day has come :)

Technically there is nothing that limits us to implement it, it will just require some effort though. Whatever goes into #[nutype()] is pure DSL.

Is there a short term fix that can be applied in the meantime?

LockedThread avatar Oct 31 '24 01:10 LockedThread

@LockedThread Which trait do you need?

What it is possible is to implement a trait manually in terms of other traits. (if it's very repetitive, a macro rules can be used).

greyblake avatar Oct 31 '24 08:10 greyblake

@LockedThread Which trait do you need?

What it is possible is to implement a trait manually in terms of other traits. (if it's very repetitive, a macro rules can be used).

Serde traits, enabled by feature.

I wasn't able to use cfg_attr to enable them. However, I was able to make 2 modules and enable those based on the feature and then reexport the nutype's defined inside of them.

Not a very clean solution, but it works.

LockedThread avatar Nov 02 '24 16:11 LockedThread