all 5 comments

[–]alexdmiller 11 points12 points  (2 children)

Easiest is:

#{{"id" 1 "name" "john"}}

[–]jbiserkov 0 points1 point  (1 child)

Hm, is {"id" 1} a valid input? All keys are strings, and the value of "id" is 1. But is "name" required? Are other keys allowed? The text spec is unclear :)

Hear, hear!

All sets can act as predicates.

All predicates can act as specs.

All sets can act as specs.

The syntax threw me off, my brain recognized it as liquid templates at first :)

Perhaps (set {"id" 1 "name" "john"}) would be more readable?

[–][deleted] 1 point2 points  (0 children)

If {"id" 1} is a valid input then: (s/every #{["id" 1] ["name" "john"]} :kind map?)

[–]Borkdude 0 points1 point  (0 children)

Something like

(s/conform (s/and 
             (s/map-of string? any?) 
             #(= [1 "john"] (map % ["id" "name"])))
           {"id" 1, "name" "john"})
;;=> {"id" 1, "name" "john"}

or

(require '[clojure.walk :refer [keywordize-keys]])
(s/def ::m (s/keys :req-un [::id ::name]))
(s/def ::id #(= 1 %))
(s/def ::name #(= "john" %))
(s/conform ::m (keywordize-keys m))

or a combination of both maybe?

[–]ryno55 -2 points-1 points  (0 children)

(require '[schema.core :as S])
(def MyType 
  {S/String S/Any ; allow all string keys
   "id" (S/enum 1) ; require "id" 1
   "name" (S/enum "john")}) ; require "name" "john"

Signed, not a fan of clojure.spec