greyblake / nutype

Rust newtype with guarantees 🇺🇦 🦀

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Move derive into nutype attributes

greyblake opened this issue · comments

Context

At the moment it's possible to derive traits by using the regular #[derive] macro. For example:

#[nutype(validate(not_empty))]
#[derive(Debug)]
pub struct Name(String);

The initial idea behind this was to give a "natural" syntax/feeling to Rust developers.
In reality however, nutype fully controls #[derive()]: it parses it, and generates code. It's not done by the standard derive macro.

Note also that the following will not compile:

#[derive(Debug)]
#[nutype(validate(not_empty))]
pub struct Name(String);

Because in this case, nutype has no notion about derive and the standard derive macro is applied on tuple struct with private inner value, which cannot be access directly.
However, people got confused sometimes, thinking that the 2 snippets above are equal.

Motivation

To eliminate confusion and make it clear for the library users, we want to move derive macro into set of nutype attributes, e.g.:

#[nutype(
    validate(not_empty),
    derive(Debug)
)]
pub struct Name(String);

Spec

  • Add a new field to ParseableAttributes : derive_traits: Vec<SpannedItem<DeriveTrait>>,
  • Update impl Parse for ParseableAttributes to parse derive into derive_traits, for inspiration take the current implementation in fn parse_ident_into_derive_trait
  • Adjust the tests (to run all possible tests run make test)
  • When #[derive(...)] is used outside of #[nutype(...)] return a compilation error, explaining how to use derive correctly. Add a compiletests to test the error message.
  • Update CHANGELOG.md with the information about the breaking change. Do not update README (will do it before the release).

Acceptance Criteria

  1. The following code should compile and Name should have Debug implemented:
#[nutype(
    validate(not_empty),
    derive(Debug)
)]
pub struct Name(String)
  1. The following code should result into an error message with an example how to use derive(..) properly:
#[nutype(
    validate(not_empty)
)]
#[derive(Debug)]
pub struct Name(String)