2014-05-28 7 views
12

Ich möchte ein Schema verwenden, um ein Anfrageobjekt zu validieren. Einer der Werte in der Map bestimmt, welche anderen Felder gültig sind.Polymorphe Schema-Validierung in Clojure

Zum Beispiel würde diese alle gültig:

{ :name "jane" :type :dog :barking true } 
{ :name "alan" :type :bird :cheeping true } 
{ :name "bert" :type :fish :swimming true } 

Einige Felder gemeinsam sind. Andere hängen jedoch vom Wert :type ab.

Zum Beispiel würde dies ungültig sein:

{ :name "phil" :type :bird :barking false } 

Wie kann ein solches Schema ausgedrückt werden?

Ich bin glücklich, entweder Clj-Schema oder Prismatic Schema zu verwenden.

Antwort

13

Sie prismatic.schema die verwenden können conditional dies zu erreichen:

(s/conditional #(= (:type %) :bird) {:type (s/eq :bird) :chirping s/Bool} 
       #(= (:type %) :fish) {:type (s/eq :fish) :swimming s/Bool} 
       ... 
       :default {:type (s/eq :animal) :existing s/Bool}) 
+0

Das sieht gut aus, danke. Das Lesen des Testcodes scheint ebenfalls eine gute Idee zu sein. Ich habe viele Felder, die zwischen Typen üblich sind (d. H. Wie ': name' in meinem Beispiel), also möchte ich vermeiden, diese in jedem cond-Zweig zu wiederholen. –

+1

Ich definiere einen Basistyp mit den allgemeinen Feldern, dann füge ich ihn mit dem spezifischeren Typ zusammen, der die speziellen Felder enthält. Prismatische Schemata sind nur Karten und Sie können sie auf alle üblichen Arten manipulieren. –

+0

Führen Sie die Zusammenführung in jeder der Bedingungen durch, oder kann dies auf oberster Ebene geschehen? –