3

少し前に単純なポリモーフィック スキーマについて尋ねたところ、しばらくの間はうまくいきました。

検証したいマップには、別のキーの値に依存する追加の値があります。

オブジェクトの不自然な例:

{:type      :foo         {:type      :bert        {:type      :foo
 :foo-param :bar          :bert-size :medium       :foo-param :bar
 :method    :baz          :method    :baz          :method    :bang
 :baz-rate  :max}         :baz-rate  :max}         :bangness  :considerable}

ここでの識別子は:type:methodで、それぞれに有効な兄弟キーと値の独自のセットがあります。

以前は:type存在するだけで、次のものが機能しました。

(def ^:private test-base-schema {:type (s/enum :foo :abc :banana)})

(def test-schema
  (s/conditional #(= (:type %) :foo)
                 (merge test-base-schema {:foo-param s/Keyword})
                 ; other conditions here
                 ))

ただし、複数の弁別子があるため、条件分岐の数は組み合わせになります。

1 つのオプションは{s/Any s/Any}、マップと使用をs/both許可することですが、予期しないキー/値が無効と見なされるため、スキーマが「緩い」ことを許可できません。

また、このライブラリを使用して検証を機能させるためだけに、検証中のマップの構造を変更したくありません。

複数の条件付きサブスキーマを持つマップの厳密な検証を実現する適切な方法はありますか?

4

1 に答える 1

6

卑劣な答えは、これはあなたのデータモデルが理想的ではないという匂いかもしれないということです.

{:type-info {:type :foo :foo-param :bar}
 :method-info {:method :baz :baz-rate :max}}

(おそらく)より役立つ答えは、検証用のカスタム述語を書くだけでなく、すぐに使える一連のスキーマではこれが簡単ではないと思うということです。

これが望ましくない場合は、新しいスキーマ タイプを導入する必要があると思います。幸いなことに、これはユーザー コード (またはサードパーティ ライブラリ) で簡単に実行できます。残念ながら、これら 2 つの概念 (厳密な共用体と条件付きマップ構造) を明確かつ直交する方法で (単一の条件付き共用体スキーマに結合したり、共用体を条件付きにすることなく) 表現する簡単な方法はわかりません。方法はあると思いますが、一見しただけではわかりません。

于 2014-06-24T15:04:45.683 に答える