Closed greyblake closed 1 month ago
I would love to see this - is one of the main reasons I'm unable to use nutype
@AlisCode @gobanos @boyswan What do you guys think of the following syntax?
#[nutype(
sanitize(trim),
validate(with = validate_name, error = NameError),
derive(Debug, AsRef, PartialEq, Deref),
)]
struct Name(String);
where
fn validate_name(name: &str) -> Result<(), NameError> {
if name.len() < 3 {
Err(NameError::TooShort)
} else if name.len() > 20 {
Err(NameError::TooLong)
} else {
Ok(())
}
}
// This actually probably will need to implement fully std::error::Error
#[derive(Debug)]
enum NameError {
TooShort,
TooLong,
}
Do you have any alternative proposal to consider?
Looks great!
Looks cool!
Although I have to say this breaks a lot with the current nutype
philosophy.
Right now, nutype
supports e.g. the following attribute :
validate(not_empty, len_char_max = 20)
, which produces an error enum with 2 variants (NotEmptyViolated
, LenCharMaxViolated
)
I think it's a good feat of nutype that you're able to provide a multi-step validation, and this proposal attemps to do exactly the reverse which is that you would provide one custom validation function which would contain all your logic in one place. It would probably mean having a lot of code dedicated to the special case.
What if instead, nutype
still produced an enum which contains one variant for each step of the validation ?
For example :
struct TooLongError;
fn max_len(input: &str) -> Result<(), TooLongError> {
if name.len() > 20 {
Err(TooLongError)
} else {
Ok(())
}
}
struct TooShortError;
fn min_len(input: &str) -> Result<(), TooShortError> {
if name.len() < 3 {
Err(TooShortError)
} else {
Ok(())
}
}
#[nutype(
sanitize(trim),
validate(
with(max_len, variant = TooLong),
with(min_len, variant = TooShort),
)
derive(Debug, AsRef, PartialEq, Deref),
)]
struct Name(String);
Produced code :
enum NameError {
TooLong(TooLongError),
TooShort(TooShortError),
// And here you can support other potential validation steps ...
}
Also right now nutype
supports passing in arguments to validators such as for len_char_max = 20
. What if the customized validation function needs to be reused between different newtypes, and you wanted to pass in an argument just like for len_char_max
? How do you see that working ?
@AlisCode Thank you for your valuable input! I had a similar thing to what you suggest in mind, though I see it as an orthogonal to this story (support of custom errors VS custom error variants). Ideally I'd like to have both in some or other form implement, because they serve different needs.
What if instead,
nutype
still produced an enum which contains one variant for each step of the validation ?
This would "pollute" (even more than it currently does) the public API of libraries that want to use nutype
. Maybe a different approach, more centered towards fixing #75, fits better?
Maybe good inspiration on how to handle "let users customize errors" can be taken from parser combinator libraries? Feels like nutype
validation errors can take inspiration on how they handle parsing errors (?) I don't know, just throwing ideas out there.
Maybe there is something to copy from the work that @epage has done in winnow? Again, I don't know, just throwing random ideas around.
@DJDuque Could you explain how winnow
error idea would fit here?
@boyswan @AlisCode @DJDuque I just released 0.5.0-beta.2, with the support of custom validation and errors.
I'd appreciate if you find a bit of time to try it out and give me feedback before I release 0.5.0
(planning in ~1 week).
See the docs in the Custom validation with a custom error type section.
I don't recall being involved in this issue, maybe you meant to tag someone else, @greyblake?
@memark Sorry my bad.
Context
Some orgs and people are not quite happy with auto-generated error types, e.g. it's not possible to customize them, inject extra details, etc.
Requirement
Provide a way for users to:
Result<(), CustomError>
, whereCustomError
is a user defined error.Technically it's possible, but the syntax for this needs to be decided.
Consideration
Having this may clash with "unified error": https://github.com/greyblake/nutype/issues/75, so requires careful thinking.