Объединение с / с и / или в спецификации Clojure - PullRequest
1 голос
/ 11 ноября 2019

Я хочу написать спецификацию для карты, которая либо имеет ключ :rule/children, либо имеет два ключа - :condition/field и :condition/predicate. Вот что я пробовал:

(s/keys :req [(s/or :children :rule/children :condition (s/and :condition/field :condition/predicate))])

Это приводит к сообщению об ошибке:

Caused by: java.lang.AssertionError: Assert failed: all keys must be namespace-qualified keywords
(every? (fn* [p1__1917#] (c/and (keyword? p1__1917#) (namespace p1__1917#))) (concat req-keys req-un-specs opt opt-un))

Я знаю, что для s/or каждый путь должен быть назван. Здесь есть два пути - эта карта может иметь :children или :condition. Это условие, только если оно имеет две клавиши :condition/field и :condition/predicate.

1 Ответ

2 голосов
/ 11 ноября 2019

В keys спецификациях вы можете использовать обычные or и and, чтобы сделать это:

(s/def ::map-spec
  (s/keys :req [(or :rule/children (and :condition/field :condition/predicate))]))

(s/conform ::map-spec {:rule/children 1}) ;; valid
(s/conform ::map-spec {:condition/field 1}) ;; invalid
(s/conform ::map-spec {:condition/field 1 :condition/predicate 2}) ;; valid
...