Skip to content

Ideas for 0.3 #2

@ronlobo

Description

@ronlobo

Spoiler: This project is for learning Rust.

After getting some super helpful feedback from the Rust community, writing down some thoughts for improvements.

Although it works as expected and is well tested, the usage is non-idiomatic.

What's the original idea?

A struct like this, for example:

pub struct EmailAddress (pub String);

This can be instantiated without a check for the correctness of the String actually being a valid email address.

Downstream, this can lead to hard to track bugs, so in general, it's a good practice to do the actual validation right before instantiation. This will lead to usable structures that hold up their invariants.

A more idiomatic Rust way for the above email address structure is to encapsulate the field by not making it public beyond the crate level (useful for testing) and use a constructor function to instantiate the struct:

pub struct EmailAddress(pub(crate) String);

impl FromStr for EmailAddress {
    type Err = InvalidPattern;

    fn from_str(s: &str) Result<Self, Self::Err> {
        // validation goes here
       ...
    }
}

It's still some boilerplate to write, so taking some ideas from other crates, it might be a good idea to turn this into a proc macro:

#[derive(constrained_type)]
#[constrained_type("pattern" = r".+@.+")]
pub struct EmailAddress(pub(crate) String);

This would then generate the FromStr implementation for the structure.
I'll think about this more in detail and, in the meantime, play around with some ideas for the proc macro.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions