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

Enforce validation with typestate #185

Open
abonander opened this issue Feb 1, 2022 · 2 comments
Open

Enforce validation with typestate #185

abonander opened this issue Feb 1, 2022 · 2 comments

Comments

@abonander
Copy link

abonander commented Feb 1, 2022

@mehcode just reminded me that this crate exists after the following discussion on Reddit: https://www.reddit.com/r/rust/comments/shetb1/show_rrust_a_rust_implementation_of_the_realworld/hv6og8t/?context=10000

@mehcode himself had previously suggested something like this, but linked directly to Actix-web: #68

However, the approach I'm thinking of would be agnostic of any kind of web framework. I'm just thinking an API like this:

// inner value is not accessible
#[derive(serde::Deserialize)]
pub struct Unvalidated<T>(T);

impl<T: Validate> Unvalidated<T> {
    pub fn validate(self) -> Result<T, ValidationErrors> { ... }
}

So in either Actix-web or Axum, you could have as a parameter to a request handler, Json<Unvalidated<FooRequestBody>>, and you can't access fields of FooRequestBody until you've applied validation so the developer can't forget to do it.

@Keats
Copy link
Owner

Keats commented Feb 2, 2022

I think it's fine to add such a type to the library but you should still be able to use the current way.

@evbo
Copy link

evbo commented Feb 14, 2025

I get how higher-kinded types could be helpful flagging a type as not yet validated, but unless T is private it's not stopping the dev from instantiating T directly, and then forgetting to call validate.

One additional suggestion then is to derive-new (a separate crate) and inside that new call validate. With private struct fields, this would guarantee validation: #371

Unfortunately it doesn't permit customizing new at all (e.g. to call validate) so currently no workaround I'm aware of exists. The closest is to use derive-build to accomplish this, but builder pattern implies optional fields, which isn't as clean either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants