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

Allow for custom TypeDescription values for fields using a function instead of newtypes #192

Open
samsieber opened this issue May 17, 2023 · 3 comments

Comments

@samsieber
Copy link

Context

I'm using the Decimal type from the rust_decimal crate. It doesn't have a AsTypeDescription impl. In order to use it with my types (using the TypeDescription derive macro), I have to wrap it in a new type that I manually implement AsTypeDescription for.

What I'd love to do instead is just write a function that provides a TypeDescription, and then annotate the field with the name of that method.

So, currently:

impl Deref for Decimal {
    type Target = rust_decimal::Decimal;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl AsTypeDescription for Decimal {
    fn as_type_description() -> TypeDescription {
        TypeDescription::new(
              "Decimal".to_string(), 
              TypeKind::Float { size: 128 }, 
              Some("A decimal type used to precisely store floats")
        )
    }
}


#[derive(Copy, Clone, PartialEq, Eq, Deserialize, Serialize, TypeDescription)]
#[serde(rename_all = "camelCase")]
pub struct ImageProperties {
    pub inches_w: Decimal,
    pub inches_h: Decimal,
    // Other fields that it can auto-derive
}

But what I'd like is to have this:

fn decimal_type_description() -> TypeDescription {
    TypeDescription::new(
        "Decimal".to_string(), 
         TypeKind::Float { size: 128 }, 
         Some("A decimal type used to precisely store floats")
    )
}

#[derive(Copy, Clone, PartialEq, Eq, Deserialize, Serialize, TypeDescription)]
#[serde(rename_all = "camelCase")]
pub struct ImageProperties {
    #[description(provider = decimal_type_description)]
    pub inches_w: rust_decimal::Decimal,
    #[description(provider = decimal_type_description)]
    pub inches_h: rust_decimal::Decimal,
    // Other fields that it can auto-derive
}

Alternatives

Has the feature been requested before?

If the feature request is approved, would you be willing to submit a PR?

I think so, though I'd need help submitting a PR.

@matthiasbeyer
Copy link
Collaborator

I must say I like the idea. Am looking forward to @TheNeikos opinion on this!

Either way: is there any benefit using a "provider" instead of wrapping the type?

@TheNeikos
Copy link
Owner

I like it! Shouldn't be too hard to integrate into the derive macro either.

@TheNeikos
Copy link
Owner

The easiest way would be to extend this enum:

It describes the individual fields used. You should be able to then check the call sites, and for example add a check to the following iterator where you look for the new attribute.

You should be able to check if you cover all cases by making tests for all situations where it could be used:

  • On struct fields
  • On a tuple struct field
  • On enum struct fields
  • On enum tuple fields

Some negative tests are also great (check out the compile fail examples), mainly making sure the function actually gets typechecked + the output should be somewhat sane.

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