首页 > 解决方案 > 使用 plumatic 模式验证具有键和值的模式

问题描述

我正在尝试使用 plumatic-schema 对向量中的键值进行验证,但错误消息对我来说并不清楚,这就是我想要做的:

;validating array with maps, it works
(s/validate [{}] [{} {}])
=> [{} {}]

;validating array with key and map (any lenght), not work
(s/validate [s/Int {}] [0 {} 1 {}])
[Int {}] is not a valid sequence schema; 
a valid sequence schema consists of zero or more `one` elements, followed by zero or more
`optional` elements, followed by an optional schema that will match the remaining elements.

我的问题是,你知道我做错了什么吗?而这个错误的真正含义是什么?

目标实际上是将此验证用于函数调用,

例如:

  (s/defn example [items :- [(s/one s/Int "i") (s/one {} "v")]] ...)
  
  ;the call should be valid for cases like this 
  (example [0 {} 1 {} 2 {} 3 {}])
  (example [0 {}])

标签: clojureplumatic-schema

解决方案


请参阅这些文档:

这是显示其工作原理的代码:

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [schema.core :as s]))

(dotest
  (is= [{} {}]
       (spyx (s/validate
               [{}]
               [{} {}])))

  (is= [0 {}]
       (s/validate
         [(s/one s/Int "int-1")
          (s/one {} "map-2")]
         [0 {}]))

  (is= [0 {} 1 {}]
       (s/validate
         [(s/one s/Int "int-1")
          (s/one {} "map-2")
          (s/one s/Int "int-3")
          (s/one {} "map-4")]
         [0 {} 1 {}]))  )

如果你想验证任意长度的交替 int & map,你可能需要做一些准备工作:

(defn validate-alternate-int-and-map
      [some-seq]
      (let [pairs   (partition 2 some-seq)
            all-int (mapv first pairs)
            all-map (mapv second pairs)]
        (assert (= (count all-map)
                   (count all-int)))
        (s/validate [s/Int] all-int)
        (s/validate [{}] all-map)
        some-seq))

(dotest
  (is= [0 {}]            (validate-alternate-int-and-map [0 {}]))
  (is= [0 {} 1 {}]       (validate-alternate-int-and-map [0 {} 1 {}]))
  (is= [0 {} 1 {} 2 {}]  (validate-alternate-int-and-map [0 {} 1 {} 2 {}]))
  )

附言

我在tupelo.schema命名空间中也有一些我发现非常方便的预定义模式(例如KeyMap、等) 。Pair


推荐阅读