Schema DSL - moxaj/mikron GitHub Wiki
This page describes the building blocks from which you can assemble your schemas. In the scope of this document, consider mikron.runtime.core
implicitly loaded and aliased to mikron
.
Each built-in schema has syntax of [name options & args]
(you may recognize this from Hiccup), where:
name
is the name of the schema (like:int
or:list
)options
is an optional map of schema-specific options& args
is list of schema-specific positional parameters
Furthermore, if a schema has no positional parameters and you wish to omit the options
parameter, you may represent the schema solely with its name
. Therefore, as the :int
schema has no positional parameters, all of the following have the same semantics:
[:int {}]
[:int]
:int
Schemas can be nested arbitrarily. Circular references are allowed, though be aware that the generator can overflow the stack if no nested schemas can 'terminate':
(mikron/gen (mikron/schema ::foo [:tuple [:byte ::foo]]))
;; => stack overflow
(defschema ::foo-1 [:tuple [:byte ::foo-2]])
(defschema ::foo-2 [:tuple [:byte ::foo-1]])
(mikron/gen ::foo-1)
;; => stack overflow
In this document, valid schema can stand for either:
- a symbol which refers to a reified schema
- an inline schema definition (like
[:tuple [...]]
) - a qualified keyword.
Built-in schemas
:byte
Syntax
[:byte {}]
Semantics
8-bit signed integer
Diff paths
true
to process, false
to ignore
:ubyte
Syntax
[:ubyte {}]
Semantics
8-bit unsigned integer
Diff paths
true
to process, false
to ignore
:short
Syntax
[:short {}]
Semantics
16-bit signed integer
Diff paths
true
to process, false
to ignore
:ushort
Syntax
[:ushort {}]
Semantics
16-bit unsigned integer
Diff paths
true
to process, false
to ignore
:int
Syntax
[:int {}]
Semantics
32-bit signed integer
Diff paths
true
to process, false
to ignore
:uint
Syntax
[:uint {}]
Semantics
32-bit unsigned integer
Diff paths
true
to process, false
to ignore
:long
Syntax
[:long {}]
Semantics
64-bit signed integer
Diff paths
true
to process, false
to ignore
:varint
Syntax
[:varint {}]
Semantics
variable length encoded integer
Diff paths
true
to process, false
to ignore
:float
Syntax
[:float {}]
Semantics
32-bit floating point number
Diff paths
true
to process, false
to ignore
:double
Syntax
[:double {}]
Semantics
64-bit floating point number
Diff paths
true
to process, false
to ignore
:char
Syntax
[:char {}]
Semantics
unicode character
Diff paths
true
to process, false
to ignore
:boolean
Syntax
[:boolean {}]
Semantics
either true
or false
Diff paths
true
to process, false
to ignore
:nil
Syntax
[:nil {}]
Semantics
the literal nil
Diff paths
always ignored
:binary
Syntax
[:binary {}]
Semantics
binary blob, byte[]
(Clojure) or ArrayBuffer
(ClojureScript)
Diff paths
always ignored
:string
Syntax
[:string {}]
Semantics
a regular Clojure(Script) string
Diff paths
true
to process, false
to ignore
:keyword
Syntax
[:keyword {}]
Semantics
a regular Clojure(Script) keyword, can be namespaced
Diff paths
true
to process, false
to ignore
:symbol
Syntax
[:symbol {}]
Semantics
a regular Clojure(Script) symbol, can be namespaced
Diff paths
true
to process, false
to ignore
:any
Syntax
[:any {}]
Semantics
any value, ignored by the processors
Diff paths
always ignored
:constant
Syntax
[:constant {} constant-value]
, where
constant-value
is any value
Semantics
a constant value
Diff paths
true
to process, false
to ignore
Examples
(mikron/schema [:constant [42 {:foo "bar"}]])
:enum
Syntax
[:enum {} enum-values]
, where
enum-values
is a set of keywords
Semantics
a keyword from a predefined set
Diff paths
true
to process, false
to ignore
Examples
(mikron/schema [:enum #{:a :b :c :d}])
:optional
Syntax
[:optional {} schema]
, where
schema
is a valid schema
Semantics
the literal nil
or any value which conforms to schema
Diff paths
the paths are interpreted for the subschema
Examples
(mikron/schema [:optional :string])
:wrapped
Syntax
[:wrapped {} pre post schema]
, where
pre
andpost
resolve to arbitrary functionsschema
is a valid schema
Semantics
any value which, with functions pre
and post
, can be mapped to and from another value (respectively) which conforms to schema
Diff paths
the paths are interpreted for the subschema
Examples
;; Date values don't travel directly on the wire, convert them to and from longs instead
(defn date->long ^long [^java.util.Date date]
(.getTime date))
(defn long->date ^java.util.Date [^long time]
(java.util.Date. time))
(mikron/schema [:wrapped date->long long->date :long])
:multi
Syntax
[:multi {} selector schemas]
, where
selector
resolves to an arbitrary functionschemas
is a map from arbitrary values to valid schemas
Semantics
a value whose actual schema will be selected at runtime by the selector
function
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: keys are from the values returned by
selector
, values are subpaths for the appropriate subschemas
Examples
(defn selector [value]
(cond
(string? value) :a-string
(integer? value) :an-integer
:else :something-else))
(mikron/schema [:multi selector {:a-string :string
:an-integer :varint
:something-else :any}]
:diff-paths {:a-string true
:an-integer false})
;; something else is implicitly :false
:list
Syntax
[:list {} schema]
, where
schema
is a valid schema
Semantics
a list of values, where each conforms to schema
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: the singular key
:all
mapped to the subpath for the subschema
Examples
(mikron/schema [:list :int]
:diff-path {:all true})
:vector
Syntax
[:vector {} schema]
, where
schema
is a valid schema
Semantics
a vector of values, where each conforms to schema
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: the single key
:all
mapped to the subpath for the subschema
Examples
(mikron/schema [:vector :long]
:diff-path true) ;; equivalent to {:all true} in this case
:set
Syntax
[:set {:sorted-by sorter} schema]
, where
sorter
resolves to an arbitrary functionschema
is a valid schema
Semantics
a set of values, where each conforms to schema
, optionally sorted by sorter
a vector of values, where each conforms to schema
Diff paths
always ignored
Examples
(mikron/schema [:set :keyword])
(mikron/schema [:set {:sorted-by >} :ubyte])
:map
Syntax
[:map {:sorted-by sorter} key-schema value-schema]
, where
sorter
resolves to an arbitrary functionkey-schema
andvalue-schema
are valid schemas
Semantics
a map from keys, each conforming to key-schema
, to values, each conforming to value-schema
, optionally sorted by sorter
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: the single key
:all
mapped to the subpath for the value subschema
Examples
(mikron/schema [:map :keyword :short]
:diff-paths {:all true})
(mikron/schema [:map {:sorted-by <} :byte :string])
:tuple
Syntax
[:tuple {} schemas]
, where
schemas
is a vector of valid schemas
Semantics
a tuple with schemas schemas
, in order.
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: keys are tuple indices, values are subpaths for the appropriate subschemas
Examples
(mikron/schema [:tuple [:byte :keyword :keyword]]
:diff-paths {0 true
1 true
2 false})
:record
Syntax
[:record {:type type} schemas]
, where
type
is a vector of symbolsschemas
is a map from keywords to valid schemas
Semantics
a record with fields as specified in schemas
. If type
is specified, it must be a vector of symbols where the first symbol is the name of the type (defined with either defrecord
or deftype
) and the rest are the symbols used to represent its fields (in the exact same order, none omitted).
Diff paths
true
: process, including all subvaluesfalse
: ignore- map: keys are record keys, values are subpaths for the appropriate subschemas
Examples
[:record {:a :int
:b :string}]
(defrecord Foo [a b c])
(mikron/schema [:record {:type [Foo a b c]}
{:a :int
:b :byte
:c :long}]
:diff-paths {:a false
:b true
:c false})