【问题标题】:Namespaced keyword makes spec for JSON invalid命名空间关键字使 JSON 的规范无效
【发布时间】:2016-08-26 13:33:24
【问题描述】:

我正在使用 Clojure.spec 来验证 JSON 的结构(然后将其转换为另一种格式):

(s/def ::yes string?)
(s/def ::my-test (s/keys :req [::yes]))

(def my-json (json/read-json "{\"yes\": \"yes\"}")) ; => {:yes "yes"}

(s/valid? ::my-test my-json)       ; => false
(s/valid? ::my-test {::yes "yes"}) ; => true

(s/explain ::my-test {:yes "yes"})
; => val: {:yes "yes"} fails spec: :spec.core/my-test predicate: 
;         (contains? % :spec.core/yes)

(这里s指的是clojure.spec命名空间,json指的是clojure.data.json。)

如上所示,s/valid? 解析 JSON 失败,因为关键字没有命名空间。

如何调整代码以使 JSON 被视为有效?

【问题讨论】:

  • 您可以使用:req-un 代替:req,但除非您将其更改为{:yes "yes"},否则它将破坏第二种情况。
  • @kongeor 谢谢。这是惯用的方法吗?我找到了另一种附加命名空间的方法:使用#(keyword (str "my.namespace/" (clojure.string/replace (str %) ":" ""))) 映射键。我认为那更糟:)。

标签: clojure clojure.spec


【解决方案1】:

您可以执行以下操作:

(def my-json (json/read-str "{\"yes\": \"yes\"}" :key-fn #(keyword (str *ns*) %)))

我不确定这是否是正确/惯用的处理方式 - 我想这取决于具体情况。

【讨论】:

  • 谢谢。使用un-req 似乎忽略了定义的规范(只看我想的关键)。您的解决方案确实使用了之前定义的规范!现在我用它。
猜你喜欢
  • 2022-11-03
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多