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

Support serde attributes #201

Open
TheBestTvarynka opened this issue Jan 5, 2025 · 5 comments
Open

Support serde attributes #201

TheBestTvarynka opened this issue Jan 5, 2025 · 5 comments

Comments

@TheBestTvarynka
Copy link

TheBestTvarynka commented Jan 5, 2025

Hi,
I like your library a lot and I use it regularly.

Today I tried to use serde attributes on my new-type struct but failed. Here is an example:

#[nutype(
    validate(predicate = |token| !token.is_empty()),
    derive(Debug, Serialize, Deserialize, AsRef, Deref, TryFrom),
)]
#[serde(serialize_with = "...", deserialize_with = "...")]
pub struct InvitationToken(Vec<u8>);

The compiler says error: #[nutype] does not support this attribute.. I also tried this one:

#[nutype(
    validate(predicate = |token| !token.is_empty()),
    derive(Debug, Serialize, Deserialize, AsRef, Deref, TryFrom),
)]
pub struct InvitationToken(#[serde(serialize_with = "...", deserialize_with = "...")] Vec<u8>);

As I understand, this is unsupported yet. Am I right?

@greyblake
Copy link
Owner

greyblake commented Jan 7, 2025

@TheBestTvarynka Thanks for the report!

Yeah, at the moment nutype generates it's own Deserialize implementation with respect to the sanitization & validaiton, not paying any attention to serde attributes.

Does your implementation of deserialize_with return Vec<u8> ?

@TheBestTvarynka
Copy link
Author

Does your implementation of deserialize_with return Vec<u8> ?

yes

This is my use case:

// https://github.com/TheBestTvarynka/Dataans/blob/582dd48b5e8f05f859d1b8d21db1b97f0c56cab7/crates/web-api-types/src/lib.rs#L14-L18
#[nutype(
    validate(predicate = |token| !token.is_empty()),
    derive(Debug, Serialize, Deserialize, AsRef, Deref, TryFrom),
)]
pub struct InvitationToken(Vec<u8>);

// https://github.com/TheBestTvarynka/Dataans/blob/582dd48b5e8f05f859d1b8d21db1b97f0c56cab7/crates/web-api-types/src/auth.rs#L10-L14
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignUpRequest {
    pub invitation_token: InvitationToken,
    pub username: Username,
    pub password: Password,
}

This invitation token is a bunch of bytes, but I want these bytes to be base64 or hex-encoded in the resulting json.

I found a workaround: I can set the deserialize_with attribute on the invitation_token field of the SignUpRequest struct. However, this forces me to do this every time I use the InvitationToken struct.

@greyblake
Copy link
Owner

Would you mind sharing your implementations of deserialize_with and serialize_with?

Unfortunately I cannot promise a fix for this quickly.

For now I'd suggest you to go maybe with your own manually implemented type.

@TheBestTvarynka
Copy link
Author

TheBestTvarynka commented Jan 7, 2025

Would you mind sharing your implementations of deserialize_with and serialize_with?

Something like this: github/TheBestTvarynka/crypto-helper/69dd4cd/src/serde.rs#L8-L37. I planned to copy-paste this code into my current project 😅

@atezet
Copy link
Contributor

atezet commented Feb 19, 2025

I have the same wish. Posting my use case s.t. you have something to work against when you find the time:

#[nutype(validate(predicate = |u| u.scheme().is_some_and(|u| u == "https")), derive(Serialize, Deserialize))]
pub struct HttpsUri(Uri);

Then I'd like to use #[serde(with = "http_serde::uri")] :)

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

3 participants