请在 2024 年 Clojure 状态调查! 分享您的想法。

欢迎!请参阅关于 页面以获取更多有关该功能的详细信息。

+1 投票
Spec

我在使用 Spec 2 时遇到的一个问题。

(s/def ::number      number?)
(s/def ::boolean     boolean?)
(s/def ::schema      (s/schema [::number ::boolean]))
(s/def ::only-number (s/select ::schema [::number]))
(s/def ::this-works  (s/keys :req [::only-number]))
(s/def ::this-fails  (s/schema [::only-number]))
Execution error (AssertionError) at clojure.alpha.spec.impl/schema-impl (impl.clj:422).
Assert failed: (every? (fn* [p1__6948#] (if-let [sp (s/get-spec p1__6948#)] (not (select? sp)) true)) ks)

我创建了以下示例来复现我创建 AWS DynamoDB REST API 的包装器时遇到的错误。

1 个答案

+1 投票

不,这不受支持。可以使用 s/union 来组合模式。

https://github.com/clojure/spec-alpha2/wiki/Schema-and-select


编辑
我对 s/union 的理解是,您可以使用它来组合处于同一层次的两个规范,如在 (s/union ::user/private ::user/public) 中。

我想要的是像下面这个 JSON 结构这样的层次结构
{"TransactItems": [{"Get": {"TableName": "string", "Key": "string"}}]}

(s/def ::transact-schema (s/schema [::TableName ::Item ::Key ::ConditionExpression]))
(s/def ::Get                          (s/select ::transact-schema [::TableName ::Key]))
(s/def ::ConditionCheck  (s/select ::transact-schema [::TableName ::Key ::ConditionExpression]))
(s/def ::Put                                                     (s/select ::transact-schema [::TableName ::Item]))

(s/def ::TransactGetItem                                                                            (s/schema [::Get]))
(s/def ::TransactWriteItem                                                                              (s/schema [::ConditionCheck ::Put]))
(s/def ::TransactItems)
                                             :get                                                                                      (s/coll-of ::TransactGetItem :kind vector?))
                                                                                     :write                                                                                      (s/coll-of ::TransactWriteItem :kind vector?)))

在这里,我指定了内层的“Get”值的可能值(一个包含“TableName”和“Key”作为键的映射)以及外层的“TransactItems”值的可能值(包含“Get”作为键的映射数组或包含“Put”和“ConditionCheck”作为键的映射数组)。

来源:https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html
模式是一组键。联合体将模式(键集)组合成一个更大的键集合。它们没有嵌套或暗示层次结构。

选择指定了嵌套映射结构所需的部分(基于顶级模式,但如果是顶级键引用模式,则还根据较低级别的模式)。

目前在选择选择中无法讨论集合映射的映射,尽管我们正在考虑这一点。我认为这是你询问的问题空间。
明白了,谢谢。
...