(require '[clojure.spec :as s])
次のデータを検討してください。
(def data {:names [["Anna" :lucky]
["Peter"]
["Jon" :lucky]
["Andre" :lucky]]})
これは、ベクトルのベクトルの値を持つ :names という 1 つのキーを持つハッシュマップです。内部ベクトルには、最初の要素として文字列を含める必要があり、オプションでキーワード :lucky を 2 番目の要素として含めることができます。
前の 2 つの文は次のように説明する必要がありますclojure.spec
。ベクター内の項目から始めましょう。
(s/def ::item (s/cat :name string? :lucky (s/? #(= :lucky %))))
(s/conform ::item ["Tom"])
;; {:name "Tom"}
(s/conform ::item ["Tom" :lucky])
;; {:name "Tom", :lucky :lucky}
(s/conform ::item ["Tom" :sad])
;; :clojure.spec/invalid
これは機能します。ただし、オプションが1つしかない場合。解析された結果は次のように良くなりませんか?
`{:name "Tom", :lucky true}` or `{:name "Tom", :lucky false}`
これは clojure.spec で実行できますか?
これにより、次のことができます。
(s/def ::items (s/coll-of ::item '()))
(s/conform ::items [["Tom" :lucky] ["Tim"]])
[["Tom" :lucky] ["Tim"]]
ただし、テストに合格したように見えますが、アイテムが解析されなくなったのはなぜですか?
編集: これは、alpha7 から alpha10 リリースに切り替えることで解決できます。coll-of は引数を 1 つしか取りません。
最後に、私の仕様は次のようになり、前述の警告があります。
(s/def ::my-spec (s/keys req-un [::items]))