Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional derive #188

Open
Ducky2048 opened this issue Oct 3, 2024 · 6 comments
Open

Conditional derive #188

Ducky2048 opened this issue Oct 3, 2024 · 6 comments

Comments

@Ducky2048
Copy link

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.

@greyblake
Copy link
Owner

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.

@musjj
Copy link

musjj commented Oct 23, 2024

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

@greyblake
Copy link
Owner

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

Answered in #191 (comment)

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

@LockedThread
Copy link

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?

@greyblake
Copy link
Owner

@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).

@LockedThread
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants