Ниже Clojure спецификации ::my
разрешения карты, имеющие либо ключ: ширину или ключа: высота, однако он не допускает имеющие обе из них:Clojure спецификации: карта, содержащая либо: с или: высота (исключающее ИЛИ)
(s/def ::width int?)
(s/def ::height int?)
(defn one-of-both? [a b]
(or (and a (not b))
(and b (not a))))
(s/def ::my (s/and (s/keys :opt-un [::width ::height])
#(one-of-both? (% :width) (% :height))))
Даже если он делает работу:
(s/valid? ::my {})
false
(s/valid? ::my {:width 5})
true
(s/valid? ::my {:height 2})
true
(s/valid? ::my {:width 5 :height 2})
false
код не кажется, что лаконичный мне. Сначала ключи определяются как необязательные, а затем по необходимости. У кого-нибудь есть более читаемое решение?
Просто хотелось бы отметить, что вышеуказанная логика терпит неудачу, если значение принадлежит каким-либо из клавиш false, т.е. 'false' или' nil': '(spec/valid? :: my {: width nil})' => 'false'. – Rovanion