Skip to content

Add :decimal schema#1285

Draft
josephinoo wants to merge 2 commits into
metosin:masterfrom
josephinoo:master
Draft

Add :decimal schema#1285
josephinoo wants to merge 2 commits into
metosin:masterfrom
josephinoo:master

Conversation

@josephinoo

@josephinoo josephinoo commented May 3, 2026

Copy link
Copy Markdown

Introduce support for a :decimal primitive type across the library.

  • Adds -decimal-schema (predicate: decimal? on CLJ, false on CLJS) and registers :decimal in the builtin type map.
  • Implements a CLJ-only generator mapping double values to BigDecimal via gen-fmap + bigdec.
  • Adds CLJ-only transformer entries for string↔decimal and any→string conversion.
  • Expands core tests with validation/encode/decode/ast expectations for :decimal.
  • Adds a CLJ-only generator test asserting produced values are decimals within bounds.
  • Uses reader conditionals to keep CLJS behavior safe throughout.

Closes #1272

Introduce support for a :decimal primitive type across the library. Adds -decimal-schema (predicate uses decimal? on clj, false on cljs) and registers :decimal in the builtin type map. Implements a CLJ-only generator that maps double values to BigDecimal via gen-fmap + bigdec. Adds CLJ-only transformer entries for string<->decimal and any->string conversion. Updates tests: expands core tests to include validation/encode/decode/ast expectations for :decimal and adds a CLJ-only generator test to ensure produced values are decimals within bounds. Uses reader conditionals to keep CLJS-safe behavior.
@josephinoo josephinoo marked this pull request as ready for review May 3, 2026 18:21
@josephinoo josephinoo changed the title WIP: Add :decimal schema Add :decimal schema May 3, 2026
Comment thread src/malli/core.cljc Outdated
(defn -int-schema [] (-simple-schema {:type :int, :pred int?, :property-pred (-min-max-pred nil)}))
(defn -float-schema [] (-simple-schema {:type :float, :pred float?, :property-pred (-min-max-pred nil)}))
(defn -double-schema [] (-simple-schema {:type :double, :pred double?, :property-pred (-min-max-pred nil)}))
(defn -decimal-schema [] (-simple-schema {:type :decimal, :pred #?(:clj decimal? :cljs (constantly false)), :property-pred (-min-max-pred nil)}))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the schema is meaningless in cljs then I propose :decimal not exist on that platform.

Comment thread src/malli/generator.cljc Outdated
(defmethod -schema-generator :int [schema options] (gen/large-integer* (-min-max schema options)))
(defmethod -schema-generator :double [schema options] (double-gen schema options))
(defmethod -schema-generator :float [schema options] (double-gen schema options))
#?(:clj (defmethod -schema-generator :decimal [schema options] (gen-fmap bigdec (double-gen schema options))))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the current implementation works with :gen/infinite true and :gen/NaN? true.

It might make sense to never generate those values as in spec's generator:

https://github.com/clojure/spec.alpha/blob/6b698eed1787c14907082c86de3410dd51e816b4/src/main/clojure/clojure/spec/gen/alpha.clj#L158-L159

Comment thread test/malli/generator_test.cljc Outdated
#?(:clj
(deftest decimal-generator-test
(is (every? decimal? (mg/sample [:decimal {:min 0.0M, :max 1.0M}] {:size 100})))
(is (every? #(<= 0.0M % 1.0M) (mg/sample [:decimal {:min 0.0M, :max 1.0M}] {:size 100})))))

@frenchy64 frenchy64 May 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some tests for :gen/min and :gen/max (see existing for other schemas), and some tests providing :min/:max as longs/doubles as in malli.generator-test/double-with-long-min-test.

Also tests that provide bounds outside the range of Double, for example {:min (inc (bigdec Double/MAX_VALUE))} should generate numbers greater than (bigdec Double/MAX_VALUE).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm not sure if anyone has released a BigDecimal generator that supports arbitrary bounds.

This is the closest I could find:

https://github.com/clojure/test.check/blob/5ba3a25b60cf66ff531db8f44d89145abfacfa5c/src/main/clojure/clojure/test/check/generators.cljc#L1389

I think at minimum we need a test to show that it throws rather than violating the expected bounds.

@josephinoo josephinoo marked this pull request as draft May 3, 2026 23:44
@opqdonut opqdonut moved this to ⌛Waiting in Metosin Open Source Backlog May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ⌛Waiting

Development

Successfully merging this pull request may close these issues.

Full support for decimal

3 participants