使用 Plumatic Schema 强制转换为 bigdec
Using Plumatic Schema to coerce to bigdec
我有 {:loan/amount 1200}
类型的传入数据。
是否可以使用 plumatic Schema 将其强制转换为 {:loan/amount 1200M}
,即将数字(甚至数字串)强制转换为 bigdecimals?
我不知道如何定义新数据类型(如 s/Bigdec
),然后确保它使用 clojure.core/bigdec
将某个值强制转换为 java.math.BigDecimal
。
Schema 中有两个独立的概念:验证和强制。
对于第一个,您需要定义架构。 类 被视为架构,因此您无需为 java.math.BigDecimal
创建自定义架构。您的架构可能如下所示:
(require '[schema.core :as s])
(require '[schema.coerce :as c])
(s/defschema Loan {:loan/amount java.math.BigDecimal})
现在您可以根据架构验证您的数据:
(s/validate Loan {:loan/amount 10M})
;; => {:loan/amount 10M}
现在,如果您有一些想要强制转换的数据,您需要定义一个强制转换函数,它是一个来自所需目标模式(java.math.BigDecimal
在您的情况下)的匹配器,将转换为一个函数实际值到所需的 bigdec
值。
(def safe-bigdec (c/safe bigdec)
schema.coerce/safe
是一个实用函数,它包装了原始函数,如果原始函数在调用时抛出异常,safe
将 return 原始输入值而不是抛出异常。
我们的匹配器函数将检查当前模式元素是否为 BigDecimal
和 return 转换函数或 nil
否则(意味着没有对其他类型的强制转换):
(defn big-decimal-matcher [schema]
(when (= java.math.BigDecimal schema)
safe-bigdec))
最后我们需要一个强制器来执行实际的强制转换:
(def loan-coercer (c/coercer Loan big-decimal-matcher))
完成所有设置后,我们现在可以使用强制器了:
(loan-coercer {:loan/amount "12.34"})
;; => {:loan/amount 12.34M}
(loan-coercer {:loan/amount 1234})
;; => {:loan/amount 1234M}
(loan-coercer {:loan/amount "abc"})
;; => #schema.utils.ErrorContainer{:error {:loan/amount (not (instance? java.math.BigDecimal "abc"))}}
我有 {:loan/amount 1200}
类型的传入数据。
是否可以使用 plumatic Schema 将其强制转换为 {:loan/amount 1200M}
,即将数字(甚至数字串)强制转换为 bigdecimals?
我不知道如何定义新数据类型(如 s/Bigdec
),然后确保它使用 clojure.core/bigdec
将某个值强制转换为 java.math.BigDecimal
。
Schema 中有两个独立的概念:验证和强制。
对于第一个,您需要定义架构。 类 被视为架构,因此您无需为 java.math.BigDecimal
创建自定义架构。您的架构可能如下所示:
(require '[schema.core :as s])
(require '[schema.coerce :as c])
(s/defschema Loan {:loan/amount java.math.BigDecimal})
现在您可以根据架构验证您的数据:
(s/validate Loan {:loan/amount 10M})
;; => {:loan/amount 10M}
现在,如果您有一些想要强制转换的数据,您需要定义一个强制转换函数,它是一个来自所需目标模式(java.math.BigDecimal
在您的情况下)的匹配器,将转换为一个函数实际值到所需的 bigdec
值。
(def safe-bigdec (c/safe bigdec)
schema.coerce/safe
是一个实用函数,它包装了原始函数,如果原始函数在调用时抛出异常,safe
将 return 原始输入值而不是抛出异常。
我们的匹配器函数将检查当前模式元素是否为 BigDecimal
和 return 转换函数或 nil
否则(意味着没有对其他类型的强制转换):
(defn big-decimal-matcher [schema]
(when (= java.math.BigDecimal schema)
safe-bigdec))
最后我们需要一个强制器来执行实际的强制转换:
(def loan-coercer (c/coercer Loan big-decimal-matcher))
完成所有设置后,我们现在可以使用强制器了:
(loan-coercer {:loan/amount "12.34"})
;; => {:loan/amount 12.34M}
(loan-coercer {:loan/amount 1234})
;; => {:loan/amount 1234M}
(loan-coercer {:loan/amount "abc"})
;; => #schema.utils.ErrorContainer{:error {:loan/amount (not (instance? java.math.BigDecimal "abc"))}}