v0.6..1 - 25/04/2026
[0.6.1] - 2026-04-25
Fixed
-
qtty-ffipackaged builds no longer depend on sibling workspace paths during
build.rs;cargo package/cargo publishnow verify cleanly from the
packaged crate source. -
Updated crate docs, README dependency snippets, and the FFI version helper to
the0.6.1release line (qtty_ffi_version() == 601).
[0.6.0] - 2026-04-25
Added
-
Quantity-level real-number rounding helpers (
qtty-core, re-exported by
qtty) —Quantity<U, S>forS: Realnow exposesfloor(),ceil(),
round(),trunc(), andfract(), matching the scalarRealsurface while
preserving unit types through common rounding workflows. -
assert_units_are_builtin!(qtty-core,#[doc(hidden)]) — compile-time
assertion macro driven by each dimension's inventory macro under#[cfg(test)].
Uses a supertrait bound pattern: adding a unit to a dimension inventory without
also registering it inregister_builtin_units!becomes a compile error. Catches
the most common drift case (new unit added to the dimension file but the
cross-dimension registry not updated). -
Facade consistency test (
qtty/tests/inventory_consistency.rs) — compile-time
integration test that uses exported inventory macros to assert every always-available
unit inangular,length,time,mass,power,area, andvolume
is both re-exported inqtty::unit::*and has a root quantity alias inqtty::*.
Adding a unit to an inventory but forgetting the correspondinglib.rsre-export
or root alias generation now fails CI instead of silently becoming a missing export. -
New public acceleration / force / energy unit families across
qtty-core
andqtty, includingAccel<L, T>,MeterPerSecondSquared,
StandardGravity, SI newton/joule ladders, and feature-gated
PoundForce,Dyne,Calorie, and electron-volt units. -
SquareOf<L>/CubeOf<L>helper aliases — new typed composition helpers
for area and volume quantities derived from multiplied length quantities. -
New stable unit arithmetic layer (
unit_arithmeticmodule) withUnitDivandUnitMulextension traits that control output types for quantity division and multiplication, replacing the previous blanket impls. -
Generic recovery impls:
U / U → Unitless,N / Per<N, D> → D,Per<N, D> * D → N,D * Per<N, D> → N. -
Macro-generated fallback pair tables for all built-in unit marker types: cross-unit division produces
Per<A, B>, multiplication producesProd<A, B>. -
Exported macros
impl_unit_division_pairs!,impl_unit_multiplication_pairs!, andimpl_unit_arithmetic_pairs!for downstream custom units to opt into the same generated arithmetic. -
asin,acos, andatanmethods onQuantity<Unitless, S>(moved fromQuantity<Per<U, U>>) so same-unit ratios keep ergonomic trig behavior. -
Comprehensive compile-time and runtime tests for unit arithmetic covering all recovery patterns, cross-unit pairs, and custom-unit registration.
-
Added invalid-unit regression coverage for
qtty-ffiquantity carriers so rawu32unit IDs from C callers are rejected cleanly instead of producing undefined behavior. -
Added serde round-trip coverage for the Rust-side
qtty-fficarrier structs using their raw numeric unit IDs. -
qtty-ffiArea & Volume FFI coverage —DimensionId::Area(6) andDimensionId::Volume(7) are now part of the ABI, exposing 11 area units (SquareMeter…SquareDecimeter) and 13 volume units (CubicMeter…UsTeaspoon) with stable discriminant ranges 60000–60010 and 70000–70012 respectively. -
qtty-ffidiscriminants.csv— new file that is the sole source of ABI-stable discriminant values. All unit metadata (ratios, symbols) is now derived at compile time from<Type as qtty::Unit>::RATIO/::SYMBOL, eliminating the historic dual-source-of-truth betweenunits.csvand qtty-core. -
qttycrate-root module re-exports —qtty::{area, volume, acceleration, force, energy}are now re-exported at the crate root, and root quantity aliases are generated from the inventory macros for all built-in scalar families. -
Auto-generated FFI unit constants —
qtty-ffinow emits namedQTTY_UNIT_*
constants fromdiscriminants.csvfor the full registry instead of maintaining
a hand-written subset. -
AngularRate<N, D>type alias andAngularRateUnittrait as the primary
names for angular-rate quantities (Angular / Time), replacing the
misleadingFrequency/FrequencyUnitnames. The dimension alias is now
AngularRate. -
Exact::checked_from_f64(value: f64) -> Option<Self>for converting a
floating-point value to an exact scalar without silent overflow; returns
Nonewhen the value is out of range or non-representable. (QTTY-003) -
Quantity::checked_to_lossy<T>() -> Option<Quantity<T, S>>for safe
cross-unit conversion when the scalar type isExact; returnsNone
instead of silently saturating. -
18 regression tests in
qtty-core/tests/audit_regressions.rscovering
cross-unit comparison symmetry, integerabs()boundary behaviour, and
lossy/checked conversion semantics. -
MulAssign<S>forQuantity<U, S>— in-place scalar multiplication
(q *= 2.0), symmetric with the pre-existingDivAssign<S>. -
Rem<Quantity<U, S>>for same-unit remainder —5 m % 3 m == 2 m,
complementing the pre-existing scalarRem<S>. -
DAYS_PER_GREGORIAN_YEARnamed constant (qtty-core::time) — replaces
the four repeated365.242_5literals inYear/Decade/Century/Millennium
ratio expressions.
Removed
qtty-ffiunits.csv— hardcoded ratio/symbol data removed; metadata is now derived from qtty-core trait constants so divergence is impossible at compile time.qtty-ffideprecated helper functions —meters_into_ffi,try_into_meters,kilometers_into_ffi,try_into_kilometers,seconds_into_ffi,try_into_seconds,minutes_into_ffi,try_into_minutes,hours_into_ffi,try_into_hours,days_into_ffi,try_into_days,radians_into_ffi,try_into_radians,degrees_into_ffi,try_into_degreeshave been removed. UseFrom/TryFromdirectly (qty.into(),qty.try_into()).- Removed the
scalar-decimalfeature andrust_decimalscalar support fromqtty-coreand theqttyfacade crate. - Breaking: Removed the public
Simplifytrait and.simplify()method fromqtty-coreand theqttyfacade crate; unit arithmetic now resolves these cases at compile time. - Breaking: Removed the deprecated
frequencyalias modules fromqtty-coreandqtty. Useangular_rateforAngular / Timequantities. - Breaking: Removed deprecated
Quantity<Unitless>::asin(),acos(), andatan()scalar-returning methods. Useasin_angle(),acos_angle(), andatan_angle()instead.
Changed
-
Downstream crates can now keep more rounding and timestamp-normalization logic
in typed quantities instead of erasing units to raw floating-point values for
floor/ceil/round/fractional extraction. -
CODATA 2018 → 2022 (
fundamental-physics) — Updated Bohr radius,
classical electron radius, and electron reduced Compton wavelength to the
CODATA 2022 recommended values. Planck length and atomic mass unit are
unchanged (identical in both adjustments). Affected constants and their
tests updated accordingly. -
Internal: inventory macros are now the canonical unit lists — every
always-available unit family inqtty-core(angular,length,time,
mass,power,area,volume,acceleration,force,energy) and the
relevant feature-gated subfamilies now expose a{family}_units!($cb:path)
macro that drives conversions, cross-unit ops, facade alias generation,
FFI registry generation, and builtin-unit checks. No public API change. -
Internal: nominal length units have full pairwise
Fromconversions —
length_nominal_units!now drivesimpl_unit_from_conversions!for all 8 nominal
units (SolarRadius,SolarDiameter,EarthRadius,EarthEquatorialRadius,
EarthPolarRadius,JupiterRadius,LunarRadius,LunarDistance). Previously
onlySolarRadius ↔ Kilometerwas generated. The explicit cross-group pair is
retained. -
Breaking: Metric area marker types
SquareMeter,SquareKilometer,
SquareCentimeter, andSquareMillimeterare nowProd<Length, Length>
aliases.side * sidecan therefore be assigned directly toSquareMeters,
but symbol behavior now followsProd(Displayrendersm·m; there is no
dedicatedSquareMeter::SYMBOLvalue likem²). -
Breaking: Same-unit division (
Meter / Meter) now directly returnsQuantity<Unitless>instead ofQuantity<Per<Meter, Meter>>. Code that type-annotated the result asQuantity<Per<U, U>>must be updated. -
qtty-ffibuild pipeline —build.rsnow resolves all unit metadata by extracting inventory types from qtty-core source files and emitting<Type as qtty::Unit>::RATIO/::SYMBOLexpressions directly. Hardcoded floats are gone; the generated registry is always in sync with qtty-core by construction. -
qtty-fficonsistency test —tests/csv_inventory_consistency.rsreplaced bytests/consistency.rs. The new test uses only compile-timeUnitId::$variantassertions (forward check) and a lightweight runtime smoke-test that verifies trait-derived metadata matches the registry. TheKNOWN_RATIO_DIVERGENCES/KNOWN_SYMBOL_DIVERGENCESworkaround lists are gone. -
Breaking:
Per<N, D> * DandD * Per<N, D>now directly return the numerator quantity (e.g.,Quantity<Meter>) instead ofQuantity<Prod<Per<N, D>, D>>. The.to()call to recover the numerator is no longer needed. -
Breaking:
N / Per<N, D>now directly returns the denominator quantity (e.g.,Quantity<Second>) instead ofQuantity<Per<N, Per<N, D>>>. -
Breaking:
asin/acos/atanare now onQuantity<Unitless>instead ofQuantity<Per<U, U>>. Since same-unit division now yieldsUnitlessdirectly, this is transparent for(a / b).asin()patterns. -
qtty-ffiquantity carrier fields and C-facing unit parameters now use rawu32/uint32_tunit IDs, andqtty_ffi_version()now reports ABI version600. -
Quantity::sqrt()was renamed toQuantity::scalar_sqrt()to make it explicit that the operation returns the underlying scalar rather than a quantity with the original unit type. -
Breaking: Dimension aliases
VelocityDimandAngularRateDimare now
VelocityandAngularRate. At theqttycrate root,Velocityand
AngularRatenow name dimensions; the quantity aliases remain under
qtty::velocity::Velocity<L, T>andqtty::frequency::AngularRate<N, D>. -
Breaking:
Frequency<N, D>,FrequencyUnit, andFrequencyDimare
removed. UseAngularRate<N, D>,AngularRateUnit, andAngularRate. -
Canonical symbols were tightened for two built-in units:
Turnnow renders as
trandCenturynow renders asc. -
Cross-unit comparison (
==,<, …) is now symmetric: both operands
are independently scaled to the same reference unit before comparison,
eliminating the previous asymmetry wherea == bcould differ from
b == aafter a floating-point round-trip.
Fixed
-
Pound-force value corrected (
qtty-core::force, featurecustomary) —
PoundForce::RATIOwas4.448_222_615_260_5(typo in digit 6) instead of the
exact NIST SP 1247 value4.448_221_615_260_5 N(=g₀ × 1 lb). The error
was one part per million and affected all conversions involvingPoundForce.
The accompanying test and docstring were updated to match. -
Year/Decade/Century/Millennium docstrings (
qtty-core::time) — doc
comments incorrectly described theYearstruct and its multiples as "mean
tropical year". The ratio used (365.242 5 d = DAYS_PER_GREGORIAN_YEAR) is the
Gregorian calendar mean year (365 + 97/400), not the astronomical mean
tropical year (≈ 365.242 19 d, which differs by ~27 s/yr). Docstrings for
Year,Decade,Century, andMillenniumnow correctly say "mean Gregorian
year" and explain the distinction. A stale// (tropical year)test comment in
angular_rate.rswas corrected to match. -
Removed
unitless.rstombstone file (qtty-core) — a file containing only
a comment ("TheUnitlesstype has been removed") was left dangling after the
removal of theUnitlesstype in a prior release. It was never included in any
moddeclaration and served no purpose; deleted to avoid confusion. -
f32to_constprecision — ratio conversion forf32-backed quantities
now performs theU::RATIO / T::RATIOdivision inf64before casting to
f32, matching thef64code path and avoiding doubled rounding error from
two independentas f32casts. -
Cleaned up stale
scalar-decimalcfg gates, tests, and documentation left behind by the Decimal removal so current builds no longer emitunexpected_cfgswarnings. -
Made
Quantity::mean()overflow-safe for integer-backed quantities by avoiding addition before division. -
Made
Degrees::from_dms()andHourAngles::from_hms()safe fori32::MINinputs by avoiding signed integer negation before widening. -
Fixed
qtty-corepureno_stdtest builds by gating std-dependent internal test modules behind thestdfeature. -
Fixed
qttypureno_stdtest/example target checks by gating std-only integration tests and theall_unitsexample. -
Generalized generated pairwise unit
From/Intoconversions acrossRealscalar types so non-default scalar modules such asqtty::f32get the same conversion ergonomics as the defaultf64surface. -
Refreshed the workspace and crate READMEs to match the current public API and publishing layout, including the
all_unitsexample command and theqtty-ffipackage README. -
Updated crate docs and README dependency snippets to the current
0.6.0release line. -
Integer
abs()no longer panics in debug builds on the minimum signed
value (e.g.i32::MIN); it now usessaturating_abs(), returning
i32::MAX. (QTTY-002) -
qtty-ffiformatting now clamps requested precision to 100 to avoid
pathological allocations and returnsQTTY_ERR_BUFFER_TOO_SMALLfor
zero-length output buffers instead ofQTTY_ERR_NULL_OUT. -
to_lossy()documentation now explicitly describes truncation and
saturation semantics for integer scalars and warns that the result may
not equal the original value. (QTTY-003) -
Crate-level docs in
qtty-coreandqttycorrected: removed the claim
that all quantities are "backed by anf64"; serde section now says "raw
scalar value" instead of "rawf64value".