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

Ideas for 0.3 #2

Open
ronlobo opened this issue Aug 19, 2021 · 2 comments
Open

Ideas for 0.3 #2

ronlobo opened this issue Aug 19, 2021 · 2 comments

Comments

@ronlobo
Copy link
Owner

ronlobo commented Aug 19, 2021

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.

@ms-ati
Copy link

ms-ati commented Jul 6, 2022

Hi! I’ve been exploring the same ideas.

Would it be even more idiomatic for Rust value objects to implement the interface TryFrom rather thanFromStr in general?

@ronlobo
Copy link
Owner Author

ronlobo commented Aug 2, 2023

Hey,

Late reply xD

Yes, of course you can use the TryFrom trait as constructor as well!

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

2 participants