2014-05-28 19 views
12

Chcę użyć schematu do sprawdzenia poprawności obiektu żądania. Jedna z wartości na mapie określa, które inne pola są prawidłowe.Weryfikacja schematu polimorficznego w Clojure

Na przykład, to byłoby wszystko jest ważne:

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

Niektóre pola są wspólne. Ale inne zależą od wartości :type.

Na przykład ten będzie nieważny:

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

Jak można taki schemat wyrazić?

Jestem zadowolony z użycia schematu clj-schema lub Prismatic.

Odpowiedz

13

Można użyć prismatic.schema na conditional do osiągnięcia tego celu:

(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

To wygląda świetnie, dzięki. Przeczytanie kodu testowego również wydaje się dobrym pomysłem. Mam wiele pól, które są wspólne między typami (np. Jak '' name' w moim przykładzie), więc chciałbym uniknąć powtarzania tych w każdej gałęzi cond. –

+1

Definiuję typ podstawowy z typowymi polami, a następnie "scalam" go z bardziej szczegółowym typem zawierającym wyspecjalizowane pola. pryzmatyczne schematy są po prostu mapami i można nimi manipulować na wszystkie normalne sposoby. –

+0

Czy dokonujesz scalenia w każdym z warunków, czy może to zrobić na najwyższym poziomie? –