diff --git a/src/Validus/Core.fs b/src/Validus/Core.fs index c7c1005..a2a5392 100644 --- a/src/Validus/Core.fs +++ b/src/Validus/Core.fs @@ -49,6 +49,7 @@ module ValidationMessages = let seqEmpty field = sprintf "'%s' must be empty" field let seqEqualsLen field len = sprintf "'%s' must be %i items" field len let seqExists field = sprintf "'%s' must contain the specified item" field + let seqForAll field = sprintf "'%s' must only contain items that satisfy the predicate" field let seqGreaterThanLen field min = sprintf "'%s' must be greater than %i items" field min let seqGreaterThanOrEqualToLen field min = sprintf "'%s' must be greater than or equal to %i items" field min let seqLessThanLen field max = sprintf "'%s' must be less than %i items" field max @@ -209,9 +210,8 @@ module Validator = (rule : 'a -> bool) : Validator<'a, 'a> = fun (field : string) (value : 'a) -> - let error = ValidationErrors.create field [ message field ] if rule value then Ok value - else error |> Error + else [ message field ] |> ValidationErrors.create field |> Error let success : Validator<'a, 'a> = fun field x -> Ok x let fail msg : Validator<'a, 'a> = fun field x -> Error (ValidationErrors.create field [ msg field ]) diff --git a/src/Validus/Validators.Default.fs b/src/Validus/Validators.Default.fs index 3a8d5df..645ea36 100644 --- a/src/Validus/Validators.Default.fs +++ b/src/Validus/Validators.Default.fs @@ -38,7 +38,7 @@ type DefaultComparisonValidator<'a when 'a /// error message member _.greaterThanOrEqualTo (min : 'a) (field : string) (input : 'a) = let msg field = ValidationMessages.greaterThanOrEqualTo field min - x.greaterThan min msg field input + x.greaterThanOrEqualTo min msg field input /// Value is less than provided max with the default error message member _.lessThan (max : 'a) (field : string) (input : 'a) = @@ -49,7 +49,7 @@ type DefaultComparisonValidator<'a when 'a /// error message member _.lessThanOrEqualTo (max : 'a) (field : string) (input : 'a) = let msg field = ValidationMessages.lessThanOrEqualTo field max - x.lessThan max msg field input + x.lessThanOrEqualTo max msg field input type DefaultStringValidator(x : StringValidator) = inherit DefaultEqualityValidator(x) @@ -81,7 +81,7 @@ type DefaultStringValidator(x : StringValidator) = /// value with the default error message member _.greaterThanOrEqualToLen (min : int) (field : string) (input : string) = let msg field = ValidationMessages.strGreaterThanOrEqualToLen field min - x.greaterThanLen min msg field input + x.greaterThanOrEqualToLen min msg field input /// Validate string length is less than provided value with the /// default error message @@ -93,7 +93,7 @@ type DefaultStringValidator(x : StringValidator) = /// with the default error message member _.lessThanOrEqualToLen (max : int) (field : string) (input : string) = let msg field = ValidationMessages.strLessThanOrEqualToLen field max - x.lessThanLen max msg field input + x.lessThanOrEqualToLen max msg field input /// Validate string is not null or "" with the default error message member _.notEmpty (field : string) (input : string) = @@ -173,6 +173,11 @@ type DefaultSequenceValidator<'a, 'b when 'a : equality and 'b :> 'a seq>(x : Se let msg field = ValidationMessages.seqExists field x.exists predicate msg field input + /// Validate all elements in a sequence satisfiy the predicate + member _.forAll (predicate : 'a -> bool) (field: string) (input : 'b) = + let msg field = ValidationMessages.seqForAll field + x.forAll predicate msg field input + /// Validate sequence length is greater than provided value with the /// default error message member _.greaterThanLen (min : int) (field : string) (input : 'b) = @@ -183,7 +188,7 @@ type DefaultSequenceValidator<'a, 'b when 'a : equality and 'b :> 'a seq>(x : Se /// value with the default error message member _.greaterThanOrEqualToLen (min : int) (field : string) (input : 'b) = let msg field = ValidationMessages.seqGreaterThanOrEqualToLen field min - x.greaterThanLen min msg field input + x.greaterThanOrEqualToLen min msg field input /// Validate sequence length is less than provided value with the /// default error message @@ -195,7 +200,7 @@ type DefaultSequenceValidator<'a, 'b when 'a : equality and 'b :> 'a seq>(x : Se /// with the default error message member _.lessThanOrEqualToLen (max : int) (field : string) (input : 'b) = let msg field = ValidationMessages.seqLessThanOrEqualToLen field max - x.lessThanLen max msg field input + x.lessThanOrEqualToLen max msg field input /// Validate sequence is not null or "" with the default error message member _.notEmpty (field : string) (input : 'b) = diff --git a/src/Validus/Validators.fs b/src/Validus/Validators.fs index afff644..66d3a16 100644 --- a/src/Validus/Validators.fs +++ b/src/Validus/Validators.fs @@ -273,6 +273,15 @@ type SequenceValidator<'a, 'b when 'a : equality and 'b :> 'a seq>() = : ValidationResult<'b> = Validator.create message (Seq.exists predicate) field input + /// Validate all elements in a sequence satisfiy the predicate + member _.forAll + (predicate : 'a -> bool) + (message : ValidationMessage) + (field : string) + (input : 'b) + : ValidationResult<'b> = + Validator.create message (Seq.forall predicate) field input + /// Validate sequence length is greater than provided value member _.greaterThanLen (min : int) diff --git a/test/Validus.Tests/SequenceValidatorTests.fs b/test/Validus.Tests/SequenceValidatorTests.fs index 73b091b..8d638f1 100644 --- a/test/Validus.Tests/SequenceValidatorTests.fs +++ b/test/Validus.Tests/SequenceValidatorTests.fs @@ -103,3 +103,15 @@ let ``(TestValidator.notEmpty) should produce Error`` () = match TestValidator.notEmpty "Test" empty with | Ok _ -> false | Error _ -> true + +[] +let ``(TestValidator.forAll) should produce Success`` () = + match TestValidator.forAll (fun number -> number <= 10) "Test" testSequence with + | Ok _ -> true + | Error _ -> false + +[] +let ``(TestValidator.forAll) should produce Error`` () = + match TestValidator.forAll (fun number -> number % 2 = 0) "Test" testSequence with + | Ok _ -> false + | Error _ -> true