Clojure.spec или эквивалент s/and

Мне понравилось работать с clojure.spec; это помогло выявить ошибки данных ближе к причине. В настоящее время я использую его для проверки ответа на запрос веб-сервера, но у меня возникают трудности с синтаксисом операции clojure.spec, которая допускает два разных ответа структуры карты.

В моих данных есть два возможных ответа на запрос веб-сервера:

{:assignment "1232123"} и

{:no-more-assignments true}

Я мог бы использовать multi-spec, но это кажется многословным для чего-то, что может быть таким же простым, как иметь одну спецификацию для каждого случая и определять спецификацию как:

(s/def ::response
  (s/or ::case-1 ::case-2))

Есть ли какой-то синтаксис, который я упускаю из виду, или мне нужно будет использовать multi-spec?


person frank    schedule 06.05.2018    source источник
comment
Почему нельзя использовать or?   -  person Lee    schedule 06.05.2018


Ответы (1)


Вы можете использовать or и and со спецификациями keys:

(s/def ::assignment string?)
(s/def ::no-more-assignments boolean?)
(s/def ::response
  (s/keys :req-un [(or ::assignment ::no-more-assignments)]))

(s/explain ::response {:assignment "123"})
;; Success!
(s/explain ::response {:foo true})
;; val: {:foo true} fails spec: :sandbox.so/response predicate: (or (contains? % :assignment) (contains? % :no-more-assignments))
person Taylor Wood    schedule 06.05.2018
comment
Это работает! Благодарить. Что, если бы ::asignment была картой, а не строкой? Это не удается, когда я определяю: (s/def::assignment (s/keys:req-un [::id::reason])) - person frank; 06.05.2018
comment
@frank Я не уверен, что происходит, но это должно работать независимо от спецификации ::assignment. Можете ли вы подробно рассказать, как это терпит неудачу сейчас? - person Taylor Wood; 07.05.2018