14 releases (7 breaking)
| new 0.8.1 | May 14, 2026 |
|---|---|
| 0.6.1 | Apr 25, 2026 |
| 0.5.0 | Mar 31, 2026 |
| 0.2.1 | Dec 22, 2025 |
#9 in #quantities
507 downloads per month
Used in 9 crates
(via qtty)
620KB
10K
SLoC
Core type system for strongly typed physical quantities.
qtty-core provides a minimal, zero-cost units model:
- A unit is a zero-sized marker type implementing
Unit. - A value tagged with a unit is a [
Quantity<U, S>], whereSis the scalar type (defaults tof64). Supported scalars includef64,f32, signed integers (i8–i128), and optionallyRational64. - Conversion is an explicit, type-checked scaling via
Quantity::to(forRealscalars) orQuantity::to_lossy(forExactscalars). - Derived units like velocity are expressed as [
Per<N, D>] (e.g.Meter/Second).
Most users should depend on qtty (the facade crate) unless they need direct access to these primitives.
What this crate solves
- Compile-time separation of dimensions (length vs time vs angle, …).
- Zero runtime overhead for unit tags (phantom types only).
- Full dimensional arithmetic:
m * m → Prod<Meter, Meter>,m / s → Per<Meter, Second>,m / m → Quantity<Unitless>. Named derived units (e.g.SquareMeter) are obtained via.to(). - Automatic compile-time verification that multiplied/divided quantities produce the correct dimension.
What this crate does not try to solve
- General-purpose symbolic simplification of arbitrary unit expressions.
Products and quotients are structural (
Prod<A, B>,Per<A, B>); use.to()to convert to named units.
Quick start
Convert between predefined units:
use qtty_core::length::{Kilometers, Meter};
let km = Kilometers::new(1.25);
let m = km.to::<Meter>();
assert!((m.value() - 1250.0).abs() < 1e-12);
Compose derived units using /:
use qtty_core::length::{Meter, Meters};
use qtty_core::time::{Second, Seconds};
use qtty_core::velocity::Velocity;
let d = Meters::new(100.0);
let t = Seconds::new(20.0);
let v: Velocity<Meter, Second> = d / t;
assert!((v.value() - 5.0).abs() < 1e-12);
no_std
Disable default features to build qtty-core without std:
[dependencies]
qtty-core = { version = "0.7.0", default-features = false }
When std is disabled, floating-point math that isn't available in core is provided via libm.
Feature flags
std(default): enablesstdsupport.cross-unit-ops(default): enables direct cross-unit comparison operators (==,<, etc.) for built-in unit catalogs.serde: enablesserdesupport forQuantity<U, S>; serialization is the raw scalar value.pyo3: enables PyO3 bindings for Python interop via#[pyclass]and#[pymethods].
Panics and errors
This crate does not define an error type and does not return Result from its core operations. For floating-point
scalars (f64, f32), arithmetic follows IEEE-754 behavior (NaN and infinities propagate). For integer
scalars, abs() uses saturating semantics at the minimum value (e.g. i32::MIN.abs() returns i32::MAX
instead of panicking). Standard integer overflow rules still apply to addition, subtraction, and multiplication.
SemVer and stability
This crate is currently 0.x. Expect breaking changes between minor versions until 1.0.
qtty-core
Low-level type system and built-in unit catalogs behind qtty.
Most applications should depend on qtty
instead. Reach for qtty-core when you need the primitive building blocks
directly:
Unitmarker types andQuantity<U, S>- structural derived units such as
Per<N, D>andProd<A, B> - built-in unit catalogs under
qtty_core::{angular, length, time, ...} no_stdsupport and optionalserde,pyo3,diesel, andtiberiusintegrations
Install:
[dependencies]
qtty-core = "0.8.0"
Minimal no_std:
[dependencies]
qtty-core = { version = "0.8.0", default-features = false }
Repository docs:
- Workspace overview:
../../doc/users/rust-workspace.md - Repository layout:
../../doc/architecture/repository-layout.md
Dependencies
~1–5MB
~97K SLoC