title: Clojure spec: how to validate either one or another map
body: <p>I have this Clojure code to define my schema for reply objects, which can be either</p>
  
  <p><code>{:message {:text "Hello"} :delay 3000}</code></p>
  
  <p>or</p>
  
  <p><code>{:action "typing_on" :duration 5000}</code></p>
  
  <p>The <code>reply</code> map can either have <code>:message</code> or <code>:action</code> and respectively optional keys <code>:delay</code> and <code>:duration</code>.</p>
  
  <p>I am trying to express it this way with <code>clojure.spec</code>:</p>
  
  <pre><code>(s/def ::action #{"typing_on" "typing_off" "mark_seen"})
  (s/def ::duration int?)
  (s/def ::delay int?)
  (s/def ::message map?)
  
  (s/def ::message-reply (s/keys :req-un [::message]
                                 :opt-un [::delay]))
  
  (s/def ::action-reply (s/keys :req-un [::action]
                                :opt-un [::duration]))
  
  (s/def ::reply (or ::action-reply ::message-reply))
  </code></pre>
  
  <p>However, these specs will validate with <code>true</code> just the first schema they find within the <code>or</code> clause, in this case <code>::action-reply</code>.
  What I am trying to achieve instead is that either <code>::action-reply</code> or <code>::message-reply</code> are valid schemas for <code>::reply</code>.</p>