Skip to content

Commit

Permalink
refactor(validations): Use functor pattern to clean the validations
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin COMBRIAT committed Jan 14, 2021
1 parent 7f5e2bb commit 7b2d000
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 32 deletions.
2 changes: 2 additions & 0 deletions example/App.res
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ let makeForm = Formidable.make(~values=module(Values), ~error=module(I18n.Error)
// In many cases, it's not needed, especially thanks to the Consumer component
module Form = unpack(makeForm(~onSubmit=_values => (), ~onSubmitError=(_values, _errors) => (), ()))

module Validations = Validations.Make(Values)

open Validations

// Validations can be defined in an other module, and re-used easily
Expand Down
60 changes: 33 additions & 27 deletions example/Validations.res
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
include Formidable.Validations

let required = {
Description.names: list{"required"},
validator: ({label, value}) =>
switch value {
| "" => #error(#error(("required", label)))
| _ => #ok(value)
},
module type Values = {
type t
}

let emailRegEx = %re("/.+@.+/")
module Make = (Values: Values) => {
include Formidable.Validations

let email = {
Description.names: list{"email"},
validator: ({label, value}) =>
if emailRegEx->Js.Re.test_(value) {
#ok(value)
} else {
#error(#error(("email", label)))
},
}
let required: Description.t<Values.t, _, _> = {
names: ["required"],
validator: ({label, value}) =>
switch value {
| "" => #error(#error(("required", label)))
| _ => #ok(value)
},
}

let emailRegEx = %re("/.+@.+/")

let email: Description.t<Values.t, _, _> = {
names: ["email"],
validator: ({label, value}) =>
if emailRegEx->Js.Re.test_(value) {
#ok(value)
} else {
#error(#error(("email", label)))
},
}

let equals = lens => {
Description.names: list{"equals"},
validator: ({label, value, values}) =>
if lens.Optic.Lens.get(values) == value {
#ok(value)
} else {
#error(#error(("equals", label)))
},
let equals = lens => {
Description.names: ["equals"],
validator: ({label, value, values}) =>
if lens.Optic.Lens.get(values) == value {
#ok(value)
} else {
#error(#error(("equals", label)))
},
}
}
4 changes: 1 addition & 3 deletions src/Formidable.res
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,7 @@ module Make = (

let validationNames =
props["validations"]->Option.mapWithDefault([], validations =>
validations->ArrayExtra.flatMap(validation =>
validation->Validations.getNames->List.toArray
)
validations->ArrayExtra.flatMap(Validations.getNames)
)

let hasValidation = name => validationNames->Js.Array2.includes(name)
Expand Down
4 changes: 2 additions & 2 deletions src/FormidableValidations.res
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module Validator = {

module Description = {
type t<'values, 'value, 'error> = {
names: list<string>,
names: array<string>,
validator: Validator.t<'values, 'value, 'error>,
}
}
Expand All @@ -43,7 +43,7 @@ let compose = (
{Description.names: names, validator},
{Description.names: names', validator: validator'},
) => {
Description.names: names->List.concat(names'),
Description.names: names->Js.Array2.concat(names'),
validator: field =>
switch validator(field) {
| #ok(_) => validator'(field)
Expand Down

0 comments on commit 7b2d000

Please sign in to comment.