2017-12-14 3 views
2

私はclojure.specとmetosin/spec-toolsを使用してアプリケーションのデータを検証し、適合させようとしています。 spec-toolsのドキュメントを読んだら、準拠したデータに余分なキーがないように(つまり、内部構造のマップではなくトップレベルのマップ上で動作するように)、仕様をどのようにラップするべきかはわかりませんでした。spec-toolsを使用して内部マップから余分なキーを削除する方法

問題を明確にするのに役立ついくつかのコードは:

(ns prodimg.spec 
    (:require [clojure.spec.alpha :as s] 
      [spec-tools.core :as st] 
      [spec-tools.spec :as st.spec])) 

(def ^:private not-blank? #(and (string? %) 
           (not (clojure.string/blank? %)))) 

(s/def :db/id integer?) 

(s/def :model.image/id :db/id) 
(s/def :model.image/type not-blank?) 
(s/def :model.image/product-id :db/id) 

(s/def :model.product/id :db/id) 
(s/def :model.product/parent-id (s/nilable :db/id)) 
(s/def :model.product/name not-blank?) 
(s/def :model.product/description string?) 
(s/def :model.product/price (s/nilable decimal?)) 

; ----- request specs ----- 

; create product 

(s/def :req.product.create/images (s/* (s/keys :req-un [:model.image/type]))) 
(s/def :req.product.create/children 
    (s/* (s/keys :req-un [:model.product/name :model.product/description] 
       :opt-un [:model.product/price]))) 

(s/def :req.product/create 
    (st/spec (s/keys :req-un [:model.product/name :model.product/description] 
        :opt-un [:model.product/price 
          :model.product/parent-id 
          :req.product.create/images 
          :req.product.create/children]))) 

は、今私は私が準拠/検証する次のようなデータがあるとします。

(def data {:name "Product" 
      :description "Product description" 
      :price (bigdec "399.49") 
      :extra-key "something" 
      :images [{:type "PNG" :extra-key "something else"}]) 

(st/conform :req.product/create data st/strip-extra-keys-conforming) 
; below is the result 
; {:name "Product" 
    :description "Product description" 
    :price 399.49M 
    :images [{:type "PNG" :extra-key "something else"}] 

私はst/specを含めるように:req.product.create/images宣言を変更してみましたs/*フォームまたはs/keysフォーム、またはその両方を折り返し呼び出しても、その変更は結果を変更しませんでした。

どのように私はこの問題を解決できますか?

答えて

1

最新のバージョン[metosin/spec-tools "0.5.1"]が2017-10-31(投稿の前に)リリースされていますが、私がしなければならなかった唯一の変更は、Map conformingという文書の例に従うことでした。あなたはすでに試した:st/specs/keysを包む次のように:

変更

(s/def :req.product.create/images (s/* (s/keys :req-un [:model.image/type]))) 

(s/def :req.product.create/images (s/* (st/spec (s/keys :req-un [:model.image/type])))) 

と私は期待される出力を得る:

(st/conform :req.product/create data st/strip-extra-keys-conforming) 
=> 
{:description "Product description", 
:images [{:type "PNG"}], 
:name "Product", 
:price 399.49M} 
関連する問題