QuantityValue implemented as a fractional number 🐲 #1544
Conversation
- IQuantity interfaces optimized (some methods refactored as extensions) - QuantityInfo/UnitInfo hierachy re-implemented (same properties, different constructors) - QuantityInfoLookup is now public - UntAbbreviationsCache, UnitParser, QuantityParser optimized - UnitConverter: re-implemented (multiple versions) - removed the IConvertible interface - updated the JsonNet converters - introducing the SystemTextJson project - added a new UnitsNetConfiguration to the Samples project showcasing the new configuration options - many more tests and benchmarks (perhaps too many)
|
@angularsen Clearly, I don't expect this to get merged in the Gitty up! fashion, but at least we have the whole picture, with sources that I can reference. If you want, send me an e-mail, we could do a quick walk-through / discussion. |
…lection constructors with IEnumerable - `UnitAbbreviationsCacheInitializationBenchmarks`: replaced some obsolete usages
I tried to create this PR twice before (many months ago), while the changes to the unit definitions were still not merged- and the web interface was giving me an error when trying to browse the files changed.. Something like "Too many files to display" 😄 |
|
Ok, I'm not going to get through a review of this many files anytime soon. On the surface though, it seems like this could be split up into chunks. I know it's tedious and extra work, but it will be way faster to review. Do you see any chunks of changes to easily split off into separate PRs? |
Sofia (GMT+3), but time zones are not relevant to my sleep schedule - so basically any time you want.
Yes, I do have some ideas:
Hopefully by the time we get to 5) you'd be up to speed (and fed up with PRs) and we can turn back to reviewing / working on the rest of it as a whole 😄 |
|
Ok, sounds good. Just send PRs my way and I'll try to get to them. I have a little bit of extra time this weekend. |
…ions into their own folder
- UnitAbbreviationsCache: removing the obsolete overload - adding a few more tests
|
This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
|
This PR was automatically closed due to inactivity. |
…ramework (net8.0) with 9.0 on the QuantityInfoBenchmarks
|
This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
|
This PR was automatically closed due to inactivity. |
|
@angularsen I've reopened this:
|
Extracted from #1544 because deterministic code generation is independent of the QuantityValue feature and improves the existing generator on its own. Moving it out reduces the size and conflict surface of the original PR. Changes: - Deserialize relation definitions without relying on SortedSet's current-culture comparer. - Normalize relations with an ordinal, case-insensitive immutable sorted set before parsing and rewriting the file. Tests: - No test cases changed; verified by running the full code generator and confirming it produced no unrelated generated-file changes.
Extracted from #1544 because format-string parsing is unrelated to QuantityValue and is a standalone correctness improvement for the existing formatter. Moving it out keeps the feature PR focused and lets this behavior ship independently. Changes: - Parse significant-digit, abbreviation-index, currency, and percent suffixes with invariant culture. - Apply the same parsing rules to the span-based and .NET Framework-compatible code paths. Tests: - Add Format_CustomSpecifierSuffix_ParsesUsingInvariantCulture for abbreviation and significant-digit formats.
Extracted from #1544 because representing a unit system for only the dimensions an application uses is useful independently of QuantityValue. Moving it out gives the API change focused review and reduces the original PR's scope. Changes: - Allow UnitSystem to be constructed from any BaseUnits value defining at least one dimension. - Continue rejecting null and fully undefined base-unit sets. - Clarify the constructor documentation and exception message. Tests: - Change the seven previously rejected one-dimension-missing cases to assert successful construction. - Add a single-dimension UnitSystem case. - Add a dedicated assertion that BaseUnits.Undefined remains invalid.
Extracted from #1544 because composing an isolated quantity catalog is useful for custom quantities without depending on QuantityValue. Moving this API out gives the catalog design focused review and reduces the feature PR's size and initialization surface. Changes: - Add QuantitiesSelector for appending external quantity definitions to a base catalog. - Add configured factory overloads for QuantityInfoLookup, UnitAbbreviationsCache, and UnitParser. - Allow parser factories to configure abbreviations before parser construction. - Add UnitsNetSetup.Create and a selection builder for isolated, consistently wired setups. - Keep UnitsNetSetup.Default behavior unchanged. Tests: - Add QuantitiesSelector coverage for base, chained additions, ordering, and null input. - Add cache factory coverage for default and custom base catalogs. - Add parser factory coverage for external quantities and custom abbreviations. - Add isolated setup coverage for component wiring, catalog selection, additions, and duplicate base selection.
Extracted from #1544 (#1544) because choosing the global quantity catalog is an independent setup capability, not a requirement of fractional QuantityValue. Keeping it separate makes the singleton initialization and compatibility implications explicit and allows this commit to be deferred without blocking the isolated factory APIs. Changes: - Lazily create UnitsNetSetup.Default from the existing setup builder. - Add ConfigureDefaults for selecting the global catalog before first use. - Synchronize configuration and creation so concurrent first access cannot observe a partially configured builder. - Reject configuration after the singleton has been created. Tests: - Add a dedicated test assembly so global singleton state is isolated from the existing suite. - Verify configured catalog selection, default cache/parser wiring, excluded units, and rejection of reconfiguration. - Run the regression on net10.0 and net48 (1 test per target).
Extracted from #1544 because choosing the global quantity catalog is an independent setup capability, not a requirement of fractional QuantityValue. Keeping it separate makes the singleton initialization and compatibility implications explicit and allows this commit to be deferred without blocking the isolated factory APIs. Changes: - Lazily create UnitsNetSetup.Default from the existing setup builder. - Add ConfigureDefaults for selecting the global catalog before first use. - Synchronize configuration and creation so concurrent first access cannot observe a partially configured builder. - Reject configuration after the singleton has been created. Tests: - Add a dedicated test assembly so global singleton state is isolated from the existing suite. - Verify configured catalog selection, default cache/parser wiring, excluded units, and rejection of reconfiguration.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1544 +/- ##
=========================================
Coverage 96% 97%
=========================================
Files 457 237 -220
Lines 30163 18371 -11792
=========================================
- Hits 29098 17880 -11218
+ Misses 1065 491 -574
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@lipchev I took the liberty of splitting out some more changes and syncing this PR branch again. |

QuantityValueimplemented as a fractional numberIQuantityinterfaces optimized (some methods refactored as extensions)UnitInfo: introduced two new properties:ConversionFromBaseandConversionToBasewhich are used instead of theswitch(Unit)conversionUnitsNetSetup: introduced helper methods for adding external quantities, or re-configuring one or more of the existing onesUntAbbreviationsCache: introduced additional factory methods (using a configuration delegate)UnitParser: introduced additional factory methods (using a configuration delegate)UnitConverter: re-implemented (multiple versions)Inverserelationship mapping implemented as a type of implicit conversion