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:
nameis the name of the schema (like:intor:list)optionsis an optional map of schema-specific options& argsis 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-valueis 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-valuesis 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
schemais 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
preandpostresolve to arbitrary functionsschemais 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
selectorresolves to an arbitrary functionschemasis 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
schemais 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
:allmapped to the subpath for the subschema
Examples
(mikron/schema [:list :int]
:diff-path {:all true})
:vector
Syntax
[:vector {} schema], where
schemais 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
:allmapped 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
sorterresolves to an arbitrary functionschemais 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
sorterresolves to an arbitrary functionkey-schemaandvalue-schemaare 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
:allmapped 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
schemasis 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
typeis a vector of symbolsschemasis 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})