- Lidy Documentation
- Content
- Glossary Notice
- Lidy schema syntax
- Lidy identifier
- Lidy expression
- Predefined Lidy rules
- Scalar rules
- Predefined string checker rules
- Special checkers - any
- Lidy checker forms
_regex: ...
, define your own string checker- Hashmap, Dict, Object, !!map, Map-related checkers - mapChecker
- Array, Sequence, Slice, Tuple, !!seq, List-related checkers - listChecker - _list - _listFacultative - _listOf
- OneOf, choose, select, alternaives, options, pick, OR - _oneOf
- In, exact scalar match in a list of scalars - _in
_nb
,_min
,_max
, specify the number of entries in a container - container sizing - _nb - _min - _max
- Go API
You might want to have a look at the glossary.
A lidy document is a YAML map of rule identifiers to lidy expressions. The identifier main
is special: it is the default rule used to parse the YAML content document.
A valid lidy identifier is a dot-separated list of lidy names. A lidy name is a sequence of the characters beginning with one of [a-zA-Z
], followed by any number of character among [a-zA-Z0-9_
].
A Lidy expression can be a string or a YAML map.
- If it is a string, it must be a valid Lidy identifier. The identifier shall either be one of the default-lidy-rules.
- If it is a map, it must be of one of the available checker forms.
The predefined lidy rules are the scalars, the predefined string checkers and the special checkers.
Scalars, as defined in the YAML specification
string
, a YAML stringbool
, a YAML booleanint
, a YAML integerfloat
, a YAML floating-point valuenull
, the YAML null value
These Lidy checkers match string
values, and perform extra checks
timestamp
, an ISO 8601 datetimebinary
, a string consisting only of base64 characters, as defined by tag:yaml.org,2002:binary
Also see the _regex
keyword.
There's only one: any
. It matches any YAML content. It can be defined in Lidy schema as follow:
any:
_oneOf:
- string
- boolean
- int
- float
- null
- { _mapOf: { any: any } }
- { _listOf: any }
Please note that any
will store YAML map contents in the mapOf
field of MapResult
instances.
Lidy has 5 checker forms.
The scalar checker forms are:
- the regex checker, matching a string
- the in checker, matching an exact scalar
/!\ Scalar checker forms are not to be confused with lidy expression.
The container checker forms are:
- the map checker, matching a YAML map
- the seq checker, matching a YAML sequence
Finally, there's also one logical checker form:
- the one-of, selecting the first matching lidy expression
The _regex
keyword allows you to accept only strings that match the given regex. The regex engine is re2; find the accepted syntax here. Non-strings values are rejected.
Example:
url:
_regex: 'https?://[^/]+\.[a-zA-Z0-9()]{1,6}(/.*)?'
phoneNumber:
_regex: '\+?[0-9]+( [0-9]+)*'
Note: In single quoted strings the backslashes \
are not interpreted. This makes them a good choice of delimiter for regexes.
The _min
, _max
and _nb
keywords apply to the number of entries in the YAML map. See container sizing.
Usage:
_map: <map of strings to lidy expressions>
_mapFacultative?: <map of strings to lidy expressions>
_min?: <int>
_max?: <int>
_nb?: <int>
Example:
_map:
exactPropertyNameA: string
exactPropertyNameB: int
_mapFacultative:
exactPropertyNameCforAnOptionalProperty: bool
_map
, defines an association of properties. The keys used in the schema specify are to be exactly matched in the content. The value-side lidy expressions are each used to match the value in the content.
All keys defined in the map will be required in the YAML content.
The _mapFacultative
keyword allows to define optional properties.
_map: {}
_mapFacultative:
name: string
birthYear: int
_mapOf
defines a map of the given key and value types. The _mapOf
keyword accepts a map which must contain a single key-value pair. The key and the value of this pair must each be valid checkers. They will each be used to validate all entries of the map.
Usage:
_mapOf: <a map with a single entry>
_min?: <int>
_max?: <int>
_nb?: <int>
Example:
fullname:
_mapOf:
string: string
conversionTable:
_mapOf:
float: float
sparseArray:
_mapOf:
int: any
_min: 1
Using the _merge
keyword allows to extend a previously defined map checker.
The extended map checker may itself extend another map checker, but it may not contain a _mapOf
keyword.
When _map
and _mapOf
are used together, the checker first check keys against
the _map
. If they are found in the _map
, the checker specified in the _map
is used for the value. If they are not found in the _map
, then
the two checkers specified in the _mapOf
are applied, one to the key and one to the value.
Note:
_mapOf
can be used together with _map
to produce a _map
which accepts extra keys. Here's one way to do it:
house:
_map:
kitchen: room
bedroom: room
_mapOf:
any: any
# The above house is defined as *requering* a kitchen and a bedroom entries,
# both of which must be rooms. However, it may contain any other key, of any
# othe value
_map
and _mapOf
both produce a MapResult
as result output. A MapResult
is defined in Go as follows:
type MapResult struct {
Map map[string]Result
MapOf []KeyValueResult
}
type KeyValueResult struct {
Key Result
Value Result
}
The MapResult type comes with the helper method Hashed()
:
func (MapResult) Hashed() (map[string]Result, error)
Assuming all keys are strings, Hashed()
converts the KeyValueResult list into a map of string
-s to Result
-s. It errors if any key is not a string.
The _min
, _max
and _nb
keywords apply to the number of entries in the YAML sequence. See container sizing. They can only be used if the _listOf
keyword is used in the definition of the list checker.
A list checker is defined by the use at least one of the lidy keywords _list
, _listFacultative
or _listOf
. List checkers validate that the yaml node is a
sequence, then map the nodes one by one to the checkers specified by _list
, then those specified by _listFacultative
, and all remaining nodes are validated by the single checker specified by _listOf
.
The validated sequence must contain at least one element for each checker of _list
. All element of the sequence being validated must have a corresponding checker for lidy to accept it. Definition of sequences which can have any number of element require the use of the _listOf
keyword.
Usage:
_list?: <sequence of lidy expressions>
_listFacultative?: <sequence of lidy expressions>
_listOf?: <lidy expression>
_min?: <int>
_max?: <int>
_nb?: <int>
Example:
_list:
- cat
- cat
_listFacultative:
- dog
- dog
_listOf:
- animal
_oneOf
specifies a list of checkers to choose from. The first checker that
matches will be picked and the node will be accepted. If no checker matches, _oneOf will reject the node.
Usage:
_oneOf?: <sequence of lidy expressions>
Example:
_oneOf:
- cat
- dog
- kangaroo
_in
specifies a list of exact scalar value that the node may take.
Usage:
_oneOf?: <sequence of YAML scalars>
Example:
_oneOf: [int, float, nullType]
The _nb
keyword allows to specify the exact number of entries that the container must have.
Example (with _mapOf
):
main:
_mapOf: { string: string }
_nb: 1
In the above example, the yaml map matched by main
must have a single entry.
Example (with _map
and _mapFacultative
):
main: person
person:
_map:
name: string
_mapFacultative:
age: int
birthYear: int
wealth: float
_min: 2
In the above example, in the yaml map matched by person
, at least one of the three facultative entries must be provided.
The _max
keyword allows to specify the maximum number of entries that the container must have.
Example (with _seq
):
main:
_seq: string
_max: 1
In the above example, the yaml seq matched by main
must have 0 or 1 entry.
TODO: add descriptions for each possible action
lidy.NewParser("<indicative filename or empty string>", <[]byte YAML schema>))
file := lidy.NewFile("<indicative filename or empty string>", <[]byte YAML content>)
result, err := parser.Parse(<lidy File>)
builderMap := make(map[string]lidy.Builder)
chainable := parser.With(builderMap)
Expect(chainable).To(Equal(parser))
chainable := parser.Option(lidy.Option{
WarnUnusedRule: true,
})
Expect(chainable).To(Equal(parser))
err := file.Yaml()
err := parser.Schema()
Expect(chainable).To(Equal(parser))
The default target it main
.
chainable := parser.Target("tree")
Expect(chainable).To(Equal(parser))
type Result interface {}
type Builder interface {
build(input interface{}) (Result, []error)
}
The input of the builders can be Lidy Results or other builder's results. The builder can produce any result.
Example:
main: animal
animal:: dog
dog:: string