1

使用 prismatic/schema coerce 可以在强制失败而不是错误消息时使用默认值。

我在 csv 文件中有一个值,它可以是空白(nil)或 s/Int。目前使用下面的代码我得到这个空白:

 #schema.utils.ErrorContainer{:error (not (integer? nil))}

代码:

(def answers (slurp "excel/answers.csv"))
(def answers-field-schemas [s/Int s/Int s/Str s/Str s/Str s/Int s/Str s/Int s/Str s/Int s/Str s/Int s/Str s/Int s/Str])

(def answers-field-coercers
  (mapv coerce/coercer
    answers-field-schemas
    (repeat coerce/string-coercion-matcher)))

(defn answers-coerce-fields [fields]
  (mapv #(%1 %2) answers-field-coercers fields))

(def answers->data (map answers-coerce-fields (csv/parse-csv answers :end-of-line "\r")))
4

1 回答 1

3

1. 您得到的错误不是强制错误,而是验证错误。值必须符合初始模式。

2. 要修复它,您需要为可能是nil. 假设它是第二个字段:

(def answers-field-schemas [s/Int (s/maybe s/Int) ...])

此时您将获得nils 而不是nil字段的错误:

user> (answers-coerce-fields ["1" nil])
[1 nil]

3. 如果您真的想要nil强制之后的默认值而不是 s,您将需要自定义强制匹配器。像这样的东西:

(import 'schema.core.Maybe)

(defn field-matcher-with-default [default]
  (fn [s]
    (let [string-coercion-fn (or (coerce/string-coercion-matcher s)
                                 identity)
          maybe-coercion-fn (if (instance? schema.core.Maybe s)
                              (fnil identity default)
                              identity)]
      (comp
       string-coercion-fn
       maybe-coercion-fn))))

还要修改以前的强制器,如下所示:

(def answers-field-coercers
  (mapv coerce/coercer
        answers-field-schemas
        ;; your default here
        (repeat (field-matcher-with-default -1))))

接着:

user> (answers-coerce-fields ["1" nil])
[1 -1]

请注意,默认值也必须符合模式,因此无法String为模式设置类型的默认值(s/maybe s/Int)

于 2016-04-25T18:02:14.677 回答