Clojure 规范:如何验证一个或另一个地图
Clojure spec: how to validate either one or another map
我有这个 Clojure 代码来定义我的回复对象模式,可以是
{:message {:text "Hello"} :delay 3000}
或
{:action "typing_on" :duration 5000}
reply
映射可以有 :message
或 :action
以及可选键 :delay
和 :duration
。
我想用clojure.spec
这样表达:
(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))
但是,这些规范将使用 true
验证它们在 or
子句中找到的第一个模式,在本例中为 ::action-reply
。
我想要实现的是 ::action-reply
或 ::message-reply
是 ::reply
.
的有效模式
我猜你是想使用 s/or
,而不是 or
(这在这种情况下没有意义)?
(s/def ::reply (s/or :action-reply ::action-reply
:message-reply ::message-reply))
也许尝试 s/conform
您的其中一个值,看看如何使用符合规范的(‘spec-destructured’)值:
(s/conform ::reply {:message {:text "Hello"} :delay 3000})
; => [:message-reply {:message {:text "Hello"}, :delay 3000}]
我有这个 Clojure 代码来定义我的回复对象模式,可以是
{:message {:text "Hello"} :delay 3000}
或
{:action "typing_on" :duration 5000}
reply
映射可以有 :message
或 :action
以及可选键 :delay
和 :duration
。
我想用clojure.spec
这样表达:
(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))
但是,这些规范将使用 true
验证它们在 or
子句中找到的第一个模式,在本例中为 ::action-reply
。
我想要实现的是 ::action-reply
或 ::message-reply
是 ::reply
.
我猜你是想使用 s/or
,而不是 or
(这在这种情况下没有意义)?
(s/def ::reply (s/or :action-reply ::action-reply
:message-reply ::message-reply))
也许尝试 s/conform
您的其中一个值,看看如何使用符合规范的(‘spec-destructured’)值:
(s/conform ::reply {:message {:text "Hello"} :delay 3000})
; => [:message-reply {:message {:text "Hello"}, :delay 3000}]