Parsing
What is parsing?
To validate and parse your data into a destination pointer you can use the schema.Parse()
function. The function signature looks like this:
schema.Parse(data, &dest, options...)
This works with any Zog Schema:
// string
var dest string
z.String().Min(3).Parse("test", &dest)
// structs
var dest User
z.Struct(z.Schema{"name": z.String().Min(3)}).Parse(map[string]any{"name": "test"}, &dest)
Under the hood Zog follows the Parsing Execution Structure and does a bunch of things under the hood to make sure your data is parsed correctly. Such as checking for zero values, coercing types, etc...
Some of this might not be obvious so here is a table that breaksdown expected results of calling schema.Parse() on various inputs:
Schema Type | Data | Dest | Required Error (Zero Value) | Coercion Error |
---|---|---|---|---|
Bool() | true | true | no | no |
Bool() | false | false | no | no |
Bool() | nil | false | yes | yes |
Bool() | "" | false | yes | yes |
Bool() | " " | false | yes | yes |
Bool() | on | true | no | no |
Bool() | off | false | no | no |
Bool() | ["true", "t", "T", "True", "TRUE"] | true | no | no |
Bool() | ["false", "f", "F", "FALSE", "False"] | false | no | no |
Bool() | test | false | no | yes |
Bool() | 1 | true | no | no |
Bool() | 0 | false | no | no |
Bool() | 123 | false | no | yes |
String() | "" | "" | yes | no |
String() | " " | "" | yes | no |
String() | nil | "" | yes | yes |
String() | any value | fmt.Sprintf("%v", value) | no | no |
Int() | 0 | 0 | no | no |
Int() | 10 | 10 | no | no |
Int() | nil | 0 | yes | yes |
Int() | "" | 0 | yes | yes |
Int() | " " | 0 | yes | yes |
Int() | any string | strconv.Atoi(str) | no | depends |
Int() | 6.29 | 6 | no | no |
Int() | true | 1 | no | no |
Int() | false | 0 | no | no |
Float() | 1.21 | 1.21 | no | no |
Float() | 0 | 0 | no | no |
Float() | nil | 0 | yes | yes |
Float() | "" | 0 | yes | yes |
Float() | " " | 0 | yes | yes |
Float() | any string | strconv.ParseFloat(str) | no | depends |
Float() | 1 | 1 | no | no |
Time() | time.Time{} | time.Time{} | no | no |
Time() | time.Now() | time.Now() | no | no |
Time() | nil | time.Time{} | yes | yes |
Time() | "" | time.Time{} | yes | yes |
Time() | " " | time.Time{} | yes | yes |
Time() | unix_timestamp_ms | time.Unix(unix, 0) | no | no |
Time() | any string | time.Parse(format, str) | no | depends |
Slice() | [1] | [1] | no | no |
Slice() | [] | [] | no | no |
Slice() | nil | [null] | yes | no (error will show in the appropriate schema if any) |
Slice() | "" | [""] | yes | no (error will show in the appropriate schema if any) |
Slice() | " " | [" "] | yes | no (error will show in the appropriate schema if any) |
Slice() | any_value | [value] | depends | no (error will show in the appropriate schema if any) |
Parsing Context
Zog uses a ParseCtx
to pass around information related to a specific schema.Parse()
call. Currently use of the parse context is quite limited but it will be expanded upon in the future. It can be used for the following:
Pass custom data to functions
Here is an example with a pretransform
nameSchema := z.String().Min(3).PreTransform(func(data any, ctx z.ParseCtx) (any, error) {
char := ctx.Get("split_by")
return strings.Split(data.(string), char), nil
})
nameSchema.Parse("Michael Jackson", &dest, z.WithCtxValue("split_by", " "))
Change the error formatter for this execution
This might be useful for localization, or for changing the error messages for one specific execution.
nameSchema := z.String().Min(3)
nameSchema.Parse(data, &dest, z.WithErrFormatter(MyCustomErrorMessageFormatter))
Parsing Execution Structure
- Pretransforms
- On error all parsing and validation stops and error is returned.
- Can be caught by catch
- Default Check -> Assigns default value if the value is nil value
- Optional Check -> Stops validation if the value is nil value
- Casting -> Attempts to cast the value to the correct type
- On error all parsing and validation stops and error is returned
- Can be caught by catch
- Required check ->
- On error: aborts if the value is its nil value and returns required error.
- Can be caught by catch
- Tests -> Run all tests on the value (including required)
- On error: validation errors are added to the errors. All validation functions are run even if one of them fails.
- Can be caught by catch
- PostTransforms -> Run all postTransforms on the value.
- On error you return: aborts and adds your error to the list of errors
- Only run on valid values. Won't run if an error was created before the postTransforms