Validot icon indicating copy to clipboard operation
Validot copied to clipboard

AsType scope command - validate as different type

Open bartoszlenar opened this issue 4 years ago • 3 comments

Feature description

Feature in action

Full custom option:

Specification<CustomType> customTypeSpecification = s => s;

TryConvertDelegate<int, CustomType> intToCustomType = (int input, out CustomType output) =>
{
    if (input < 0)
    {
        output = null;
        return false;
    }

    output = new CustomType(input);

    return true;
};

Specification<int> specification = s => s
    .AsType<CustomType>(customTypeSpecification)
    .WithConversion(intToCustomType) // might be required for custom conversion
    .WithConversionErrorMessage("Conversion error!") // optional, if not present, message would be taken from dict;

Predefined options:

Specification<int> specification = s => s
    .AsString(stringSpecification);

Specification<string> specification = s => s
    .AsInt(intSpecification)
    .WithConversionErrorMessage("Invalid string as int!");

Feature details

  • New scope command: AsType<T>.
  • Could (should?) be followed by WithConversion parameter command that would set the conversion logic
    • If not present, throw exception?
    • Enforce WithConversion in fluent api? It is possible if AsType would allow only one following command and NOT ISpecificationOut.
  • WithConversionErrorMessage - optional, setting error message.
  • Plenty of built-in converters. AsInt, AsString, etc.

bartoszlenar avatar Jun 11 '20 15:06 bartoszlenar

Hello @bartoszlenar, I'd like to know if there's any pans of adding this feature? Thank you a lot for your work on this library!

tim-fay avatar Jul 13 '22 12:07 tim-fay

Hi @tim-fay. Sorry for the late reply, I'm on my holidays until the end of month.

I haven't abandoned the project, but the pace slowed down significantly lately. Partially because I don't know what other developers really want from this lib. And now I do, thanks to you.

Thank you for adding your comment and please expect this feature... well... this year for sure. Alongside other features I'm slowly (but consistently!) adding to the codebase.

bartoszlenar avatar Jul 18 '22 14:07 bartoszlenar

@tim-fay I'm on the task and so far, this is the progress with the planning:

  • The fluent API command syntax will be .AsType(tryConvertFunction, specification), so everything in a single one, without a separate command for the error message. Why? AsType<TargetType> doesn't work in the fluent API unfortunately, because all commands already have the first generic parameter. So it's either taken from the arguments, or you need to deliver both generic parameter (like AsType<TSource, TTarget>). Same reason for specification as the second parameter - it's just convenient to deliver the conversion method first so then compiler knows what is the TTarget in the Specification<TTarget>.
  • The context value either passes the conversion and the validation is continued with the delivered specification (in the same path) or doesn't pass the conversion and nothing happens (no error whatsoever). If the error is needed for some reason, that would be a subject for a custom rule.
  • Additionally, .AsType(convertFunction, specification) will be delivered which works exactly the same, but it doesn't assume the conversion could fail.

Please expect the feature sooner rather than later 😄

bartoszlenar avatar Jul 27 '22 20:07 bartoszlenar

The final version for this api is:

.AsConverted(converted, specification).

  • converter is the standard dotnet's Converter<TInput, TOutput>
  • specification is of type Specifiction<TOutput>, where TOutput is determined by the given converted declaration
  • AsType becomes AsConverted, because technically nothing stops you from using it as a method to pre-process the value before the further validation (so no change of type, just a little bit of work over the scope value)
  • For now, AsConverted doesn't assume the conversion could fail. You can always add WithCondition to make it conditional. If a try-DoSomething mechanism is required, it will be added in the subsequent versions.

bartoszlenar avatar Aug 12 '22 17:08 bartoszlenar

Merged to the main branch with this commit: https://github.com/bartoszlenar/Validot/commit/d379a9912e8df5b02217e51410634a2140afbc09

bartoszlenar avatar Aug 12 '22 17:08 bartoszlenar

Merged to the main branch with this commit: d379a99

Thanks so much, @bartoszlenar ! Really appreciate you for this PR and the whole project!

tim-fay avatar Aug 15 '22 13:08 tim-fay