Verify allows you to validate a model into a structure that makes forbidden states impossible.
input -> Result ( error
, List error ) verifie
}
This is just an alias for a function from an input to a result. The result is either:
ok : finally -> input -> Result ( error, List error ) finally
This allows you to lift any value into a validator. This is particularly useful to initialize a pipeline.
ok "always ok" Nothing
--> Ok "always ok"
fail : error -> input -> Result ( error, List error ) verified
Allows you to create a failing Validator.
fail "always fail" Nothing
--> Err ( "always fail" , [])
validate : finally -> Validator error input finally
Allows you to start a validation pipeline. It is a synonym for Verify.ok
, intended to make
things clearer to read.
import Maybe.Verify
type alias User =
{ id : Int
, firstName : String
}
validator : Verify.Validator String { a | id : Int, firstName : Maybe String } User
validator =
Verify.validate User
|> Verify.keep .id
|> Verify.verify .firstName (Maybe.Verify.isJust "You need to provide a first name.")
validator { id = 1, firstName = Nothing }
--> Err ( "You need to provide a first name." , [])
validator { id = 1, firstName = Just "Stöffel" }
--> Ok { id = 1, firstName = "Stöffel" }
verify : (bigger -> smaller) -> Validator error smaller verified -> Validator error bigger (verified -> finally) -> Validator error bigger finally
Allows you to verify a part of a structure.
import Maybe.Verify
validator : Verify.Validator String { a | firstName : Maybe String } String
validator =
Verify.validate identity
|> Verify.verify .firstName (Maybe.Verify.isJust "You need to provide a first name.")
validator { firstName = Nothing }
--> Err ( "You need to provide a first name." , [])
validator { firstName = Just "Stöffel" }
--> Ok "Stöffel"
keep : (bigger -> smaller) -> Validator error bigger (smaller -> finally) -> Validator error bigger finally
You can use keep
if you want a value to be in the verified structure without any verification.
import Maybe.Verify
validator : Validator String { a | id : Int, firstName : Maybe String } (Int, String)
validator =
Verify.validate (,)
|> Verify.keep .id
|> Verify.verify .firstName (Maybe.Verify.isJust "You need to provide a first name.")
validator { id = 1, firstName = Nothing }
--> Err ( "You need to provide a first name." , [])
validator { id = 1, firstName = Just "Stöffel" }
--> Ok (1, "Stöffel")
custom : Validator error input verified -> Validator error input (verified -> finally) -> input -> Result ( error, List error ) finally
Sometimes the verification of a part only makes sense in a bigger context. This means your Validator needs access to the whole structure.
import Maybe.Verify
validator : Verify.Validator String { a | username : Maybe String, level: Int, strength: Int } (String, Int)
validator =
Verify.validate (,)
|> Verify.verify .username (Maybe.Verify.isJust "You need to provide a username.")
|> Verify.custom (\{level, strength} ->
if strength > level then
Err ( "Your strength can exceed your level." , [])
else
Ok strength
)
validator { username = Just "Ork1", level = 3, strength = 5 }
--> Err ( "Your strength can exceed your level." , [])
validator { username = Just "Ork1", level = 6, strength = 5 }
--> Ok ("Ork1", 5)
validator { username = Nothing, level = 3, strength = 5 }
--> Err ( "You need to provide a username."
--> , [ "Your strength can exceed your level."]
--> )
compose : Validator error verified finally -> Validator error input verified -> Validator error input finally
This allows you to compose multiple Validators.
import Maybe.Verify
import String.Verify
validator { firstName = Nothing }
--> Err ( "You need to provide a first name." , [])
validator { firstName = Just " " }
--> Err ( "You need to provide a none empty first name." , [])
validator { firstName = Just "Stöffel" }
--> Ok "Stöffel"
validator : Verify.Validator String { a | firstName : Maybe String } String
validator =
Verify.validate identity
|> Verify.verify .firstName verifyName
verifyName : Verify.Validator String (Maybe String) String
verifyName =
Maybe.Verify.isJust "You need to provide a first name."
|> Verify.compose (String.Verify.notBlank "You need to provide a none empty first name.")
andThen : (a -> Validator error input b) -> Validator error input a -> Validator error input b
This allows you to chain multiple Validators.
import Maybe.Verify
validator { firstName = Nothing }
--> Err ( "You need to provide a first name." , [])
validator { firstName = Just " " }
--> Err ( "Name is too short" , [])
validator { firstName = Just "Stöffel" }
--> Ok "Stöffel"
validator : Verify.Validator String { a | firstName : Maybe String } String
validator =
Verify.validate identity
|> Verify.verify .firstName verifyName
verifyName : Verify.Validator String (Maybe String) String
verifyName =
Maybe.Verify.isJust "You need to provide a first name."
|> Verify.andThen (\name ->
if String.length name > 5 then
Verify.ok name
else
Verify.fail "Name is too short"
)
fromMaybe : (input -> Maybe verified) -> error -> Validator error input verified
This is a convenient function to create a Validator
from a function that returns a maybe instead of a Result
.
It fails if the function returns a Nothing.
This allows you to verify a input and return a verified result of a different type.
fromMaybe hasInitial "error" ""
--> Err ( "error" , [])
fromMaybe hasInitial "error" "Christoph"
--> Ok 'C'
hasInitial : String -> Maybe Char
hasInitial str =
case String.uncons str of
Just (initial, _) -> Just initial
Nothing -> Nothing