-
Notifications
You must be signed in to change notification settings - Fork 253
Schema Quick Reference
Please search the test examples for details on how to use anything mentioned in this reference.
(require '[schema.core :as s]])Any code example below using <S> (or any capitalized word) means you can
replace it with any Schema. Any lower-case <foo> means it’s not a schema,
but a different kind of value whose type is explained inline by the name or
adjoining comment.
Schemas are used as annotations inside special “schematized” versions of Clojure’s core def functions.
(s/def foo :- <S>)
;; or
(s/def ^<S> foo)s/def-
s/defns/fns/letfn s/defmethods/defrecord
All values below listed as “Schemas“ can be used as annotations in the forms above.
-
(s/eq <foo>)must be equal to the given literal value foo -
(s/enum <a> <b> <c> ...)must be equal to any of the given literal values
-
(s/pred <f>)must satisfy the given predicate function f
s/Anys/Bools/Int-
s/Inst(#instdate type) s/Keywords/Nums/Regexs/Strs/Symbol-
s/Uuid(#uuidtype)
-
(s/maybe <S>)a non-nil value must satisfy this schema
-
#"..."satisfies a regular expression -
java.lang.String,java.lang.Number(etc) Java classes -
long,double, (etc) Java primitive casts -
js/Element(etc) JavaScript prototypes
-
[<S>]a sequence of values, each satisfying the same schema -
{<K> <V>}a map of values, each satisfying the same key and value schema -
#{<S>}a set of values, each satisfying the same schema -
(s/queue <S>)a queue of values, each satisfying the same schema -
(s/pair <A> <B>)a sequence of two values matching the two schemas
-
(s/one <S>)a single, required position in a sequence -
(s/optional <S>)a single, optional position in a sequence
-
(s/required-key <literal>)or just:fooif literal is a keyword (s/optional-key <literal>)
-
(s/recursive #'foo)where foo is the name of the outer schema
-
(s/isa ...)is a child of a given parent in a hierarchy -
(s/protocol Foo)satisfies a protocol Foo -
(s/record Foo {...})is a record Foo satisfying the map schema -
(s/atom <S>)is an atom with a value satisfying this schema
-
(s/either <A> <B> <C> ...)satisfy any of the given schemas (deprecated) -
(s/conditional <fA> <A> <fB> <B> ...)satisfy the first schema whose preceding predicate function returns true -
(s/if <f> <A> <B>)satisfy schema A if the predicate function returns true, otherwise satisfy schema B -
(s/cond-pre <A> <B> <C> ...)satisfy the first schema that passes its pre-check (not its full validation likes/either)
-
(s/both <A> <B> <C> ...)satisfy both/all the given schemas (deprecated) -
(s/constrained <S> <f>)satisfies schema S and a post-condition f
-
(s/named <S> <name>)creates a named schema where the name (rather than definition) is displayed when printing errors (name can be any type) -
(s/defschema <name> <S>)same as(def <name> <S>)but records the name in the schema’s metadata
These are purely descriptive and only checks for ifn?.
-
(s/=> <Return> <Arg1> <Arg2> ...)single-arity function with explicit args -
(s/=> <Return> <Arg1> <Arg2> ... & [<ArgRest>])single-arity function with rest args -
(s/=>* <Return> [...] [...] ...)multi-arity function
For understanding s/cond-pre
Internally, there are hidden “preconditions” for all core schemas, which allows Schema to quickly “pre-check” a value before running a more expensive, full validation:
-
Composite schemas (maps, vectors, sets, queues) only check the collection type in their precondition.
-
Primitive schemas (leafs) perform their full validation in their precondition.
-
(s/maybe <S>)precondition is true ifnil?, otherwise uses S’s precondition -
(s/conditional <fA> <A> <fB> <B> ...)precondition is true if any predicate function is true -
(s/cond-pre <A> <B> <C> ...)precondition is true if any of the given schema’s predicates are true -
(s/constrained <S> <f>)precondition same as S’s