Skip to content

Latest commit

 

History

History
executable file
·
531 lines (373 loc) · 13.5 KB

DOCUMENTATION.md

File metadata and controls

executable file
·
531 lines (373 loc) · 13.5 KB

Lidy Documentation

Content

Glossary Notice

You might want to have a look at the glossary.

Lidy schema syntax

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.

Lidy identifier

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_].

Lidy expression

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.

Predefined Lidy rules

The predefined lidy rules are the scalars, the predefined string checkers and the special checkers.

Scalar rules

Scalars, as defined in the YAML specification

  • string, a YAML string
  • bool, a YAML boolean
  • int, a YAML integer
  • float, a YAML floating-point value
  • null, the YAML null value

Predefined string checker rules

These Lidy checkers match string values, and perform extra checks

  • timestamp, an ISO 8601 datetime
  • binary, a string consisting only of base64 characters, as defined by tag:yaml.org,2002:binary

Also see the _regex keyword.

Special checkers

any

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 checker forms

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

_regex: ..., define your own string checker

_regex

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.

Hashmap, Dict, Object, !!map, Map-related checkers

mapChecker

The _min, _max and _nb keywords apply to the number of entries in the YAML map. See container sizing.

_map, the structured type

_map

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, the associative container

_mapOf

_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
_merge

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.

Using _map and _mapOf together: Specify a fallback rule

_map and _mapOf together

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

MapResult, the common output type for map-related checkers

MapResult

_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.

Array, Sequence, Slice, Tuple, !!seq, List-related checkers

listChecker

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
_list
_listFacultative
_listOf

OneOf, choose, select, alternaives, options, pick, OR

_oneOf

_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, exact scalar match in a list of scalars

_in

_in specifies a list of exact scalar value that the node may take.

Usage:

_oneOf?: <sequence of YAML scalars>

Example:

_oneOf: [int, float, nullType]

_nb, _min, _max, specify the number of entries in a container

container sizing
_nb

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.

_min

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.

_max

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.

Go API

TODO: add descriptions for each possible action

Invocation in Go, simple use case

Create a parser

NewParser
lidy.NewParser("<indicative filename or empty string>", <[]byte YAML schema>))

Create a file

NewFile
file := lidy.NewFile("<indicative filename or empty string>", <[]byte YAML content>)

Parse the file

Parse
result, err := parser.Parse(<lidy File>)

Set the Builder Map

With
builderMap := make(map[string]lidy.Builder)
chainable := parser.With(builderMap)
Expect(chainable).To(Equal(parser))

Set the parse options

Option
chainable := parser.Option(lidy.Option{
  WarnUnusedRule: true,
})
Expect(chainable).To(Equal(parser))

Invocation in Go, advanced use case

Check that a file is Yaml

Yaml
err := file.Yaml()

Check that a file is a Lidy schema

Schema
err := parser.Schema()
Expect(chainable).To(Equal(parser))

Set the schema target

Target

The default target it main.

chainable := parser.Target("tree")
Expect(chainable).To(Equal(parser))

Builder Map | TODO

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

Errors | TODO