clojure的Schema中至少有一个可选键

时间:2014-08-16 23:09:23

标签: validation input clojure schema

说我有以下架构用于我从外界收到的一些输入:

(def my-schema
  {(s/optional-key :foo) Bool
   (s/optional-key :baz) Bool
   (s/optional-key :bar) Bool})

通过上述方法,我可以在地图中出现或遗漏所有或没有任何一个密钥,这是有道理的。但是,如果我想确保其中至少有一个存在,该怎么办?

我可以在Schema验证上述内容之后执行额外的单独检查,并确保密钥计数> = 1,但我很好奇是否有在Schema定义中执行的方法本身

思想?

2 个答案:

答案 0 :(得分:3)

您可以在模式中指定所需的谓词:

(def my-schema
  (s/both
     (s/pred (complement empty) 'not-empty)
     {(s/optional-key :foo) Bool
      (s/optional-key :baz) Bool
      (s/optional-key :bar) Bool}))

如果您正在询问如何使用内置谓词来验证地图,您可以写下:

(def my-schema
  (s/both
     {(s/optional-key :foo) Bool
      (s/optional-key :baz) Bool
      (s/optional-key :bar) Bool}
     (s/either
      {:foo Bool s/Any s/Any}
      {:baz Bool s/Any s/Any}
      {:bar Bool s/Any s/Any})))

这比pred示例

更丑陋,更冗长

答案 1 :(得分:0)

另一种方法(可能更好)是使用受约束的:

(def my-schema
  (s/constrained
    {(s/optional-key :foo) Bool
     (s/optional-key :baz) Bool
     (s/optional-key :bar) Bool}
    (fn [{:keys foo baz bar}]
      (or foo bar bar))
     "At least one of the keys is required")))