Skip to content

Instantly share code, notes, and snippets.

@lagenorhynque
Created March 29, 2019 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lagenorhynque/5177baf4e0558bbce43c234a86280f3d to your computer and use it in GitHub Desktop.
Save lagenorhynque/5177baf4e0558bbce43c234a86280f3d to your computer and use it in GitHub Desktop.
user> (require '[clojure.spec.alpha :as s]
'[clojure.spec.test.alpha :as stest])
nil
user> (s/def :contact/name string?)
:contact/name
user> (s/def :contact-info/type keyword?)
:contact-info/type
user> (s/def :contact-info/email-contact-info string?)
:contact-info/email-contact-info
user> (s/def :contact-info/postal-contact-info string?)
:contact-info/postal-contact-info
user> (defmulti contact-info-type :contact-info/type)
#'user/contact-info-type
user> (defmethod contact-info-type :email-only [_] (s/keys :req [:contact-info/email-contact-info]))
#multifn[contact-info-type 0x4d0b355a]
user> (defmethod contact-info-type :post-only [_] (s/keys :req [:contact-info/postal-contact-info]))
#multifn[contact-info-type 0x4d0b355a]
user> (defmethod contact-info-type :email-and-post [_] (s/keys :req [:contact-info/email-contact-info
:contact-info/postal-contact-info]))
#multifn[contact-info-type 0x4d0b355a]
user> (s/def :contact/info (s/multi-spec contact-info-type :contact-info/type))
:contact/info
user> (s/def ::contact (s/keys :req [:contact/name
:contact/info]))
:user/contact
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :email-only
:email-contact-info "bar"}})
Success!
nil
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :email-only}})
#:contact-info{:type :email-only} - failed: (contains? % :contact-info/email-contact-info) in: [:contact/info] at: [:contact/info :email-only] spec: :contact/info
nil
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :post-only
:postal-contact-info "bar"}})
Success!
nil
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :post-only}})
#:contact-info{:type :post-only} - failed: (contains? % :contact-info/postal-contact-info) in: [:contact/info] at: [:contact/info :post-only] spec: :contact/info
nil
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :email-and-post
:email-contact-info "bar"
:postal-contact-info "baz"}})
Success!
nil
user> (s/explain ::contact
#:contact{:name "foo"
:info #:contact-info{:type :email-and-post}})
#:contact-info{:type :email-and-post} - failed: (contains? % :contact-info/email-contact-info) in: [:contact/info] at: [:contact/info :email-and-post] spec: :contact/info
#:contact-info{:type :email-and-post} - failed: (contains? % :contact-info/postal-contact-info) in: [:contact/info] at: [:contact/info :email-and-post] spec: :contact/info
nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment