vcontext: Validation with context
vcontext is a library supporting validation of config files parsed from yaml or json with support for giving context as
to where errors occur. It is composed of multiple semi-independent packages:
- report: a structure for containing multiple errors, warnings, etc. It also contains context (from the path package)
for determining where in the config the reports came from (e.g.
$.foo.baz.4.quux
)
- validate: a package for composing a report by validating go structs.
- tree: a structure for containing metadata about the location (line/column) of objects in the source of the config
- json, yaml: packages for generating trees from json or yaml
- path: a structure for defining how to find json/yaml elements
Usage:
Validating a config generally involves the following steps:
- Unmarshal the yaml or json to a go struct, handle any syntax/type errors
- Generate a report by running validate.Validate(yourConfigStruct)
- Generate a tree of line/column metadata with [json|yaml].UnmarshalToContext()
- Correlate the report to the metadata tree with report.Correlate(). This fills in line and column information from the tree.
The validate
package does not require the structs came from json or yaml and will generate reports with context for each
error with a path like $.foo.baz.4.quux
. The validate package walks the structs using reflection, aggregating the results
of calling any Validate(c path.ContextPath) report.Report
functions defined on the types it is walking.
To write validation functions for your types, implement this interface:
Validate(path.ContextPath) report.Report
on any types you wish to be validated. The ContextPath passed to that function respresents the path to the type being
validated. ContextPath is a []interface{}
under the hood. You can append strings or ints to it to be more precise about
where problems occur.
Example:
type MyStruct struct {
MustBePositive int `json:"mustBePositive"`
}
func (m MyStruct) Validate(c path.ContextPath) (r report.Report) {
if m.MustBePositive <= 0 {
// append the json tag so the report specifies that field is invalid, not the whole struct
r.AddOnError(c.Append("mustBePositive"), errors.New("mustBePositive was not positive"))
}
return
}
Notes:
- This project under development and may undergo breaking changes