3

タイプの着信データがあり{:loan/amount 1200}ます。

plumatic Sc​​hema を使用しこれを に強制すること{:loan/amount 1200M}、つまり、数値 (または数字の文字列) を bigdecimals に強制することは可能でしょうか?

新しいデータ型 ( などs/Bigdec) を定義し、それを使用clojure.core/bigdecして特定の値をjava.math.BigDecimal.

4

1 に答える 1

5

スキーマには、検証と強制という 2 つの別個の概念があります。

最初のものでは、スキーマを定義する必要があります。クラスはスキーマとして扱われるため、カスタムのクラスを作成する必要はありません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代わりに元の入力値を返します。

私たちのマッチャー関数は、現在のスキーマ要素がそうであるかどうかをチェックし、BigDecimal変換関数またはnilそれ以外を返します (つまり、他のタイプの強制はありません)。

(defn big-decimal-matcher [schema]
  (when (= java.math.BigDecimal schema)
    safe-bigdec))

そして最後に、実際の強制を実行するための coercer が必要です:

(def loan-coercer (c/coercer Loan big-decimal-matcher))

すべてのセットアップで、coercer を使用できるようになりました。

(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"))}}
于 2016-05-30T20:01:28.763 に答える