Repository navigation
A number attribute matches a rule's "is one of" set, so a reading stored as 3.0 is one of {3} - #1403
Open
rudycelekli wants to merge 2 commits into
Open
rudycelekli wants to merge 2 commits into
rudycelekli wants to merge 2 commits into
Conversation
WaylandYang
requested changes
Oct 24, 2026
WaylandYang
left a comment
Contributor
There was a problem hiding this comment.
Thanks, the bug is real, but this breaks sets written as [3.0]: parse_operand stores them as "3.0", which matches a 3.0 reading today and no longer would. Please compare numerically when both the reading and the set item parse as numbers, and add a line to ADR 0029, which says set membership compares strings exactly.
…red as 3.0 is one of {3}
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
…a set written [3.0] still holds a reading of 3, and ADR 0029 says so Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
rudycelekli
force-pushed
the
fix/rule-set-numeric-reading
branch
from
November 5, 2026 03:27
7d0c9a2 to
e6819d3
Compare
Contributor
Author
|
Set membership now compares numerically when both the reading and the set item parse as numbers, and otherwise compares strings exactly as before, so a 3.0 reading is in {3} and a reading of 3 is in a set written [3.0]. text() is back to its dev form, the test covers both directions plus a non-numeric case, ADR 0029 has the line, and the branch is rebased on dev. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
inandnot_inconditions compare a reading's text with the set's text. A typednumberattribute is stored as an f64 (normalize_attr_value/attribute_valuego throughNumber::from_f64), so a reading of 3 comes back fromobject_valueas3.0, andtext()turned it into"3.0". The set operand is written as[3]or["3"]and parsed to"3". The two strings never match, so a rule such as "grade is one of {1, 2, 3}" on a number attribute never fires, andnot_infires for every reading. Nothing reports an error.What changes
text()writes a JSON number in f64 form, so3.0reads as"3"and2.5stays"2.5". String and boolean readings are unchanged.How it was checked
New test
a_stored_number_is_one_of_the_numbers_in_the_set: a readingjson!(3.0)againstIn {"3"}gives one hit.cargo test -p utopia-reason --lib: 109 passed.left: 0,right: 1.cargo fmt --all --checkandcargo clippy -p utopia-reason --all-targets -- -D warningspass.I did not run this against a database. The
3.0shape comes from the f64 written byattribute_value, which Postgresjsonbkeeps as3.0.Before review
git commit -s)cargo fmt --all --check,cargo clippyandcargo testpass for the touched crate