Es gibt zwei getrennte Konzepte in Schema: Validierung und Zwang.
Für die erste müssen Sie Ihr Schema definieren. Klassen werden als Schemas behandelt, sodass Sie keine benutzerdefinierte für java.math.BigDecimal
erstellen müssen. Ihr Schema könnte wie folgt aussehen:
(require '[schema.core :as s])
(require '[schema.coerce :as c])
(s/defschema Loan {:loan/amount java.math.BigDecimal})
Jetzt können Sie Ihre Daten gegen das Schema validieren:
(s/validate Loan {:loan/amount 10M})
;; => {:loan/amount 10M}
Nun, wenn Sie einige Daten haben, die Sie möchten Sie zwingen, müssen eine Zwangsfunktion definieren, die ist ein Matcher von einem gewünschten Zielschema (java.math.BigDecimal
in Ihrem Fall) zu einer Funktion, die den tatsächlichen Wert in den gewünschten bigdec
Wert konvertiert.
(def safe-bigdec (c/safe bigdec)
schema.coerce/safe
ist eine Hilfsfunktion, die die ursprüngliche Funktion wickelt, und wenn das Original eine Ausnahme auslöst, wenn sie aufgerufen wird safe
ursprünglichen Eingangswert zurück, anstatt die Ausnahme zu werfen.
wird unsere Matcher-Funktion überprüfen, ob das aktuelle Schema Element BigDecimal
und zurück ist Funktion oder nil
sonst Umwandlung (dh kein Zwang für andere Arten gibt es):
(defn big-decimal-matcher [schema]
(when (= java.math.BigDecimal schema)
safe-bigdec))
Und wir brauchen endlich eine coercer für die tatsächliche Durchführung Zwang:
(def loan-coercer (c/coercer Loan big-decimal-matcher))
Mit all Setup können wir nun unsere coercer verwenden:
(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"))}}
Wow, vielen Dank @ piotrek-bzdyl! Das war genau das, was ich brauchte (und ich hoffe, dass andere es auch brauchen). – claj