Tutorial: Validate and convert data
Json and query data is limited to a few basic types: strings, numbers, and booleans. Saon provides functions to convert from these types to richer F# types.
All conversion functions have the same signature:
1:
|
|
The first parameter is the property or parameter name, the second parameter is the value being converted, and
the result is the discriminated union ParserResult<'U>
that will contain the new value or an error.
Saon calls transformers where the type of the data does no change validators, since the most common use case is to validate their inputs.
You can find a list of conversion functions in the Convert
module reference, and
a list of validation functions in the Validate
module reference.
Converting between types
As an example, let's take a look at the Convert.stringToDecimal
function.
1:
|
|
Since the value "123.4567890123456789" is a properly formatted decimal number, the function will return
Success 123.4567890123456789M`.
If the value is not a valid number, the function will return a ValidationFailed
that contains an helpful error
message.
1: 2: 3: 4: |
|
Validation
Validators are similar to converters, but they return the original input if the validation was successful, otherwise
they return a ValidationFailed
with more information.
Saon includes a good amount of validators, you can find an up-to-date list in the reference.
1: 2: 3: 4: 5: |
|
Composing existing transformation functions
Composing transformers is awkward because of the property name parameter. Saon includes a Parser.pipe
function
that given a function f
and a function g
, will pass the result of f
into g
only if f
is successful.
1:
|
|
Composing transformers is such an important function that Saon includes an operator that can help make it easier.
1: 2: 3: 4: |
|
Defining new transformations
Transformers are just functions so you can easily define your own. As you use Saon in your project, you will grow a
collection of validators tailored to your domain, such as the parseSize
and parsePrice
functions above.
1: 2: 3: 4: 5: 6: 7: |
|
val string : value:'T -> string
--------------------
type string = System.String
from Saon
from Saon
module Parser
from Saon
--------------------
type Parser<'T,'E> = 'E -> ParserResult<'T> * 'E
from Saon
module ParserResult
from Saon
--------------------
type ParserResult<'T> =
| ParsingFailed of field: string option * message: string
| ValidationFailed of ValidationFailedMap
| Success of 'T