Description
From #430 (comment)
Currently we do a first pass in strict mode for unions and then a pass in lax mode. If we moved forward with something like #430 we'd be adding a third pass.
To avoid the cost of re-doing work we already did, we should let validators pass some sort of "state" or "token" up to their caller. The caller can then call back into them with that thing and they can resume from where they left off.
For example, a list validator might know that that it made it up to the 100th item in strict mode, so it can just start off from the 100th item in lax mode.
A string validator might know that strict mode and lax mode are the same as far as it's concerned so if the thing it's validating failed the first pass in strict mode it doesn't need to try again in lax mode, it can just fail fast.
One way to approach this would be to have:
trait Valdiator<ValStateTokenType> {
type ValStateToken;
fn validate(..., state: Option<ValStateTokenType>) -> (Option<ValStateTokenType>, ValResult<...>);
}
And then validators that don't use this can be:
impl Validator for SomeStatelessValidator {
type ValStateToken = ();
...
};
Or:
struct ValidatedIndex { idx: usize, strict: bool };
struct ListValidator {};
impl Validato for ListValidator {
type ValStateToken = ValidatedIndex;
...
};