首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spec验证已知和未知键值的映射

使用Spec验证已知和未知键值的映射
EN

Stack Overflow用户
提问于 2019-11-21 01:54:33
回答 1查看 229关注 0票数 2

我想创建一个clojure规范来验证由reitit.ring.middleware.multipart中间件创建的http请求的:multipart参数。

多部分表单数据必须包含可使用s/keys验证的特定参数,以及具有任意参数名称的任意数量的文件。

要验证的映射将如下所示:

代码语言:javascript
复制
           {:visualisation "vis"
            :file-xy       {:filename     "foo.png",
                            :content-type "image/png",
                            :tempfile     "C:\\Temp\\ring-multipart-123.tmp",
                            :size         295281}
            :file-abc      {:filename     "bar.png",
                            :content-type "image/png",
                            :tempfile     "C:\\Temp\\ring-multipart-456.tmp",
                            :size         42}}

我可以使用reitit.ring.middleware.multipart/temp-file-part规范验证文件,如下所示:

代码语言:javascript
复制
    (s/def :multipart/files (s/map-of :multipart/param multipart/temp-file-part))

综合起来,我提出了一个规范,它通过了,但它允许所有未知参数为文件或字符串:

代码语言:javascript
复制
(s/def :multipart/param keyword?)
(s/def :multipart/visualisation string?)
(s/def :multipart/items (s/map-of :multipart/param (s/or :file multipart/temp-file-part :visualisation string?)))
(s/def :visualisation/files (s/and (s/keys :req-un [:multipart/visualisation])
                                   :multipart/items))

如何为具有特定键的映射定义规范,并为其他键定义值验证器?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-21 11:51:37

您可以添加一个谓词函数,以确保映射的值中只有一个是字符串:

代码语言:javascript
复制
(s/def :visualisation/files
  (s/and (s/keys :req-un [:multipart/visualisation])
         #(= 1 (count (filter string? (vals %))))
         :multipart/items))

(s/conform :visualisation/files
  {:visualisation "vis"
   :file-xy       {:filename "" :content-type "" :tempfile "" :size 0}})

(s/conform :visualisation/files
  {:visualisation "vis"
   :file-abc      "not valid"
   :file-xy       {:filename "" :content-type "" :tempfile "" :size 0}})

但是,如果您使用的是conform'd输出,那么通用的s/or规范将会产生冗余的标记。

另一种选择是使用两个规范检查:

代码语言:javascript
复制
(def data
  {:visualisation "vis"
   :file-xy       {:filename "" :content-type "" :tempfile "" :size 0}})

(s/conform (s/keys :req-un [:multipart/visualisation])
           data)

(s/conform (s/map-of :multipart/param :multipart/temp-file-part)
           (dissoc data :visualisation))

如果你可以控制数据的形状,或者可以重新排列它,我会考虑这样更容易规范的东西:

代码语言:javascript
复制
{:visualisation "foo"
 :files {:file-1 {,,,}
         :file-2 {,,,}}}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58960575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档