Clojure(Script) tools for Plumatic Schema
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
scripts
src/schema_tools
test
.gitignore
.travis.yml
CHANGES.md
CONTRIBUTING.md
LICENSE
README.md
package-lock.json
package.json
project.clj

README.md

Schema-tools Build Status cljdoc badge

Common utilities for Prismatic Schema for Clojure/Script.

  • common Schema definitions: any-keys, any-keyword-keys, open-schema, optional-keys-schema
  • schema-aware selectors: get-in, select-keys, select-schema
  • schema-aware transformers: assoc, dissoc, assoc-in, update-in, update, dissoc-in, merge, optional-keys, required-keys
    • removes the schema name and ns if the schema (value) has changed.
  • handle schema default values via default & default-coercion-matcher
  • meta-data helpers: schema-with-description schema-description, resolve-schema (clj only), resolve-schema-description (clj only)
  • coercion tools: or-matcher, map-filter-matcher, multi-matcher, coercer, coerce
  • Protocol-based walker for manipulating Schemas in schema-tools.walk: walk, prewalk and postwalk.
  • Swagger2 generation
  • Coercion tools

API Docs.

Latest version

Clojars Project

Requires Java 1.8.

Examples

Normal clojure.core functions don't work well with Schemas:

(require '[schema.core :as s])

(s/defschema Address {:street s/Str
                      (s/optional-key :city) s/Str
                      (s/required-key :country) {:name s/Str}})

;; where's my city?
(select-keys Address [:street :city])
; {:street java.lang.String}

; this should not return the original Schema name...
(s/schema-name (select-keys Address [:street :city]))
; Address

With schema-tools:

(require '[schema-tools.core :as st])

(st/select-keys Address [:street :city])
; {:street java.lang.String, #schema.core.OptionalKey{:k :city} java.lang.String}

(s/schema-name (st/select-keys Address [:street :city]))
; nil

Coercion

If a given value can't be coerced to match a schema, ex-info is thrown (like schema.core/validate):

(require '[schema-tools.coerce :as stc])

(def matcher (constantly nil))
(def coercer (stc/coercer String matcher))

(coercer 123)
; clojure.lang.ExceptionInfo: Could not coerce value to schema: (not (instance? java.lang.String 123))
;      error: (not (instance? java.lang.String 123))
;     schema: java.lang.String
;       type: :schema-tools.coerce/error
;      value: 123

(coercer "123")
; "123"

; same behavior with coerce (creates coercer on each invocation, slower)
(stc/coerce 123 String matcher)
(stc/coerce "123" String matcher)

Coercion error :type can be overridden in both cases with an extra argument.

(stc/coerce 123 String matcher :domain/horror)
; clojure.lang.ExceptionInfo: Could not coerce value to schema: (not (instance? java.lang.String 123))
;      error: (not (instance? java.lang.String 123))
;     schema: java.lang.String
;       type: :domain/horror
;      value: 123

Select Schema

Filtering out illegal schema keys (using coercion):

(st/select-schema {:street "Keskustori 8"
                   :city "Tampere"
                   :description "Metosin HQ" ; disallowed-key
                   :country {:weather "-18" ; disallowed-key
                             :name "Finland"}}
                  Address)
; {:city "Tampere", :street "Keskustori 8", :country {:name "Finland"}}

Filtering out illegal schema map keys using coercion with additional Json-coercion - in a single sweep:

(s/defschema Beer {:beer (s/enum :ipa :apa)})

(def ipa {:beer "ipa" :taste "good"})

(st/select-schema ipa Beer)
; clojure.lang.ExceptionInfo: Could not coerce value to schema: {:beer (not (#{:ipa :apa} "ipa"))}
;     data: {:type :schema.core/error,
;            :schema {:beer {:vs #{:ipa :apa}}},
;            :value {:beer "ipa", :taste "good"},
;            :error {:beer (not (#{:ipa :apa} "ipa"))}}

(require '[schema.coerce :as sc])

(st/select-schema ipa Beer sc/json-coercion-matcher)
; {:beer :ipa}

Usage

See the tests.

License

Copyright © 2014-2018 Metosin Oy

Distributed under the Eclipse Public License 2.0.