siderust-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +166 -0
- package/.gitmodules +9 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +661 -0
- package/README.md +138 -0
- package/package.json +12 -0
- package/qtty-js/.github/workflows/ci.yml +151 -0
- package/qtty-js/.gitmodules +3 -0
- package/qtty-js/CHANGELOG.md +31 -0
- package/qtty-js/LICENSE +661 -0
- package/qtty-js/README.md +132 -0
- package/qtty-js/package.json +20 -0
- package/qtty-js/qtty/.github/workflows/ci.yml +155 -0
- package/qtty-js/qtty/CHANGELOG.md +120 -0
- package/qtty-js/qtty/Cargo.lock +1462 -0
- package/qtty-js/qtty/Cargo.toml +12 -0
- package/qtty-js/qtty/LICENSE +661 -0
- package/qtty-js/qtty/README.md +9 -0
- package/qtty-js/qtty/qtty/Cargo.toml +41 -0
- package/qtty-js/qtty/qtty/README.md +8 -0
- package/qtty-js/qtty/qtty/examples/angles.rs +14 -0
- package/qtty-js/qtty/qtty/examples/astronomy.rs +17 -0
- package/qtty-js/qtty/qtty/examples/dimensional_arithmetic.rs +83 -0
- package/qtty-js/qtty/qtty/examples/python_integration.rs +61 -0
- package/qtty-js/qtty/qtty/examples/quickstart.rs +15 -0
- package/qtty-js/qtty/qtty/examples/ratios.rs +12 -0
- package/qtty-js/qtty/qtty/examples/serde_with_unit.rs +234 -0
- package/qtty-js/qtty/qtty/examples/serialization.rs +141 -0
- package/qtty-js/qtty/qtty/examples/serialization_advanced.rs +155 -0
- package/qtty-js/qtty/qtty/src/f32.rs +108 -0
- package/qtty-js/qtty/qtty/src/f64.rs +30 -0
- package/qtty-js/qtty/qtty/src/i128.rs +111 -0
- package/qtty-js/qtty/qtty/src/i16.rs +111 -0
- package/qtty-js/qtty/qtty/src/i32.rs +111 -0
- package/qtty-js/qtty/qtty/src/i64.rs +111 -0
- package/qtty-js/qtty/qtty/src/i8.rs +111 -0
- package/qtty-js/qtty/qtty/src/lib.rs +238 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/src/lib.rs +7 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/src/lib.rs +7 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.lock +83 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.toml +10 -0
- package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/src/lib.rs +5 -0
- package/qtty-js/qtty/qtty/tests/integration_tests.rs +529 -0
- package/qtty-js/qtty/qtty/tests/qtty_vec_feature_matrix.rs +58 -0
- package/qtty-js/qtty/qtty-core/Cargo.toml +41 -0
- package/qtty-js/qtty/qtty-core/README.md +8 -0
- package/qtty-js/qtty/qtty-core/examples/diesel_integration.rs +145 -0
- package/qtty-js/qtty/qtty-core/examples/quantity_db_serde.rs +215 -0
- package/qtty-js/qtty/qtty-core/src/dimension.rs +249 -0
- package/qtty-js/qtty/qtty-core/src/feature_diesel.rs +318 -0
- package/qtty-js/qtty/qtty-core/src/feature_pyo3.rs +27 -0
- package/qtty-js/qtty/qtty-core/src/feature_serde.rs +203 -0
- package/qtty-js/qtty/qtty-core/src/feature_tiberius.rs +28 -0
- package/qtty-js/qtty/qtty-core/src/lib.rs +744 -0
- package/qtty-js/qtty/qtty-core/src/macros.rs +93 -0
- package/qtty-js/qtty/qtty-core/src/quantity.rs +810 -0
- package/qtty-js/qtty/qtty-core/src/scalar.rs +1742 -0
- package/qtty-js/qtty/qtty-core/src/unit.rs +332 -0
- package/qtty-js/qtty/qtty-core/src/units/angular.rs +1228 -0
- package/qtty-js/qtty/qtty-core/src/units/area.rs +243 -0
- package/qtty-js/qtty/qtty-core/src/units/frequency.rs +179 -0
- package/qtty-js/qtty/qtty-core/src/units/length.rs +1270 -0
- package/qtty-js/qtty/qtty-core/src/units/mass.rs +488 -0
- package/qtty-js/qtty/qtty-core/src/units/mod.rs +26 -0
- package/qtty-js/qtty/qtty-core/src/units/power.rs +324 -0
- package/qtty-js/qtty/qtty-core/src/units/time.rs +667 -0
- package/qtty-js/qtty/qtty-core/src/units/unitless.rs +212 -0
- package/qtty-js/qtty/qtty-core/src/units/velocity.rs +210 -0
- package/qtty-js/qtty/qtty-core/src/units/volume.rs +269 -0
- package/qtty-js/qtty/qtty-core/tests/core.rs +628 -0
- package/qtty-js/qtty/qtty-core/tests/diesel.rs +461 -0
- package/qtty-js/qtty/qtty-core/tests/integers.rs +632 -0
- package/qtty-js/qtty/qtty-core/tests/no_cross_unit_ops.rs +35 -0
- package/qtty-js/qtty/qtty-core/tests/pyo3.rs +334 -0
- package/qtty-js/qtty/qtty-core/tests/quantity_f32.rs +276 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_decimal.rs +258 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_f32.rs +286 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_f64_real.rs +287 -0
- package/qtty-js/qtty/qtty-core/tests/scalar_rational.rs +260 -0
- package/qtty-js/qtty/qtty-core/tests/serde.rs +256 -0
- package/qtty-js/qtty/qtty-core/tests/tiberius.rs +208 -0
- package/qtty-js/qtty/qtty-derive/Cargo.toml +23 -0
- package/qtty-js/qtty/qtty-derive/README.md +8 -0
- package/qtty-js/qtty/qtty-derive/src/lib.rs +340 -0
- package/qtty-js/qtty/qtty-ffi/ARCHITECTURE.md +3 -0
- package/qtty-js/qtty/qtty-ffi/Cargo.toml +31 -0
- package/qtty-js/qtty/qtty-ffi/README.md +9 -0
- package/qtty-js/qtty/qtty-ffi/build.rs +326 -0
- package/qtty-js/qtty/qtty-ffi/cbindgen.toml +105 -0
- package/qtty-js/qtty/qtty-ffi/include/qtty_ffi.h +1126 -0
- package/qtty-js/qtty/qtty-ffi/src/ffi.rs +1251 -0
- package/qtty-js/qtty/qtty-ffi/src/ffi_serde.rs +294 -0
- package/qtty-js/qtty/qtty-ffi/src/helpers.rs +310 -0
- package/qtty-js/qtty/qtty-ffi/src/lib.rs +229 -0
- package/qtty-js/qtty/qtty-ffi/src/macros.rs +121 -0
- package/qtty-js/qtty/qtty-ffi/src/registry.rs +274 -0
- package/qtty-js/qtty/qtty-ffi/src/types.rs +620 -0
- package/qtty-js/qtty/qtty-ffi/tests/integration_tests.rs +842 -0
- package/qtty-js/qtty/qtty-ffi/units.csv +156 -0
- package/qtty-js/qtty/qtty-ffi/units.csv.md +3 -0
- package/qtty-js/qtty-node/.prettierignore +6 -0
- package/qtty-js/qtty-node/.prettierrc.json +6 -0
- package/qtty-js/qtty-node/README.md +250 -0
- package/qtty-js/qtty-node/c8.config.json +11 -0
- package/qtty-js/qtty-node/eslint.config.js +31 -0
- package/qtty-js/qtty-node/examples/arithmetic.mjs +64 -0
- package/qtty-js/qtty-node/examples/astronomy.mjs +90 -0
- package/qtty-js/qtty-node/examples/quickstart.mjs +36 -0
- package/qtty-js/qtty-node/examples/serialization.mjs +125 -0
- package/qtty-js/qtty-node/examples/unit_factories.mjs +74 -0
- package/qtty-js/qtty-node/index.d.ts +219 -0
- package/qtty-js/qtty-node/index.js +323 -0
- package/qtty-js/qtty-node/lib/DerivedQuantity.js +122 -0
- package/qtty-js/qtty-node/lib/Quantity.js +151 -0
- package/qtty-js/qtty-node/lib/backend.js +25 -0
- package/qtty-js/qtty-node/native.cjs +306 -0
- package/qtty-js/qtty-node/package-lock.json +3223 -0
- package/qtty-js/qtty-node/package.json +70 -0
- package/qtty-js/qtty-node/units.d.ts +299 -0
- package/qtty-js/qtty-node/units.js +210 -0
- package/qtty-js/qtty-web/Cargo.lock +767 -0
- package/qtty-js/qtty-web/Cargo.toml +21 -0
- package/qtty-js/qtty-web/index.d.ts +140 -0
- package/qtty-js/qtty-web/index.js +20 -0
- package/qtty-js/qtty-web/lib/DerivedQuantity.js +58 -0
- package/qtty-js/qtty-web/lib/Quantity.js +75 -0
- package/qtty-js/qtty-web/lib/backend.js +80 -0
- package/qtty-js/qtty-web/package.json +45 -0
- package/qtty-js/qtty-web/src/lib.rs +111 -0
- package/qtty-js/scripts/ci.sh +73 -0
- package/scripts/ci.sh +123 -0
- package/siderust-core/Cargo.lock +787 -0
- package/siderust-core/Cargo.toml +18 -0
- package/siderust-core/DEDUPLICATION.md +124 -0
- package/siderust-core/src/body.rs +120 -0
- package/siderust-core/src/events.rs +184 -0
- package/siderust-core/src/lib.rs +20 -0
- package/siderust-core/src/observer.rs +55 -0
- package/siderust-core/src/position.rs +213 -0
- package/siderust-node/.prettierignore +7 -0
- package/siderust-node/.prettierrc.json +6 -0
- package/siderust-node/Cargo.lock +906 -0
- package/siderust-node/Cargo.toml +29 -0
- package/siderust-node/README.md +109 -0
- package/siderust-node/__test__/index.test.mjs +248 -0
- package/siderust-node/build.rs +5 -0
- package/siderust-node/c8.config.json +3 -0
- package/siderust-node/eslint.config.js +31 -0
- package/siderust-node/examples/01_basic_coordinates.mjs +24 -0
- package/siderust-node/examples/02_coordinate_transformations.mjs +25 -0
- package/siderust-node/examples/03_all_frames_conversions.mjs +26 -0
- package/siderust-node/examples/04_all_center_conversions.mjs +24 -0
- package/siderust-node/examples/05_target_tracking.mjs +22 -0
- package/siderust-node/examples/06_night_events.mjs +18 -0
- package/siderust-node/examples/07_moon_properties.mjs +21 -0
- package/siderust-node/examples/08_solar_system.mjs +19 -0
- package/siderust-node/examples/09_star_observability.mjs +22 -0
- package/siderust-node/examples/10_time_periods.mjs +9 -0
- package/siderust-node/examples/11_serialization.mjs +31 -0
- package/siderust-node/examples/12_runtime_ephemeris.mjs +27 -0
- package/siderust-node/examples/13_coordinate_operations.mjs +20 -0
- package/siderust-node/index.d.ts +623 -0
- package/siderust-node/index.js +79 -0
- package/siderust-node/lib/Observer.js +112 -0
- package/siderust-node/lib/Star.js +118 -0
- package/siderust-node/lib/backend.js +63 -0
- package/siderust-node/lib/wrappers.js +566 -0
- package/siderust-node/main.js +20 -0
- package/siderust-node/native.cjs +360 -0
- package/siderust-node/package-lock.json +3261 -0
- package/siderust-node/package.json +71 -0
- package/siderust-node/src/body.rs +74 -0
- package/siderust-node/src/coordinates.rs +372 -0
- package/siderust-node/src/ephemeris.rs +462 -0
- package/siderust-node/src/events.rs +577 -0
- package/siderust-node/src/lib.rs +43 -0
- package/siderust-node/src/observer.rs +132 -0
- package/siderust-node/src/phase.rs +218 -0
- package/siderust-node/src/position.rs +292 -0
- package/siderust-node/src/star.rs +200 -0
- package/siderust-web/Cargo.lock +855 -0
- package/siderust-web/Cargo.toml +34 -0
- package/siderust-web/README.md +100 -0
- package/siderust-web/__test__/index.test.mjs +118 -0
- package/siderust-web/examples/github-pages/README.md +31 -0
- package/siderust-web/examples/github-pages/index.html +135 -0
- package/siderust-web/index.d.ts +311 -0
- package/siderust-web/index.js +66 -0
- package/siderust-web/lib/Observer.js +103 -0
- package/siderust-web/lib/Star.js +116 -0
- package/siderust-web/lib/backend.js +400 -0
- package/siderust-web/lib/wrappers.js +512 -0
- package/siderust-web/package.json +55 -0
- package/siderust-web/src/body.rs +69 -0
- package/siderust-web/src/coordinates.rs +302 -0
- package/siderust-web/src/ephemeris.rs +456 -0
- package/siderust-web/src/events.rs +520 -0
- package/siderust-web/src/lib.rs +51 -0
- package/siderust-web/src/observer.rs +117 -0
- package/siderust-web/src/phase.rs +190 -0
- package/siderust-web/src/position.rs +291 -0
- package/siderust-web/src/star.rs +178 -0
- package/tempoch-js/.github/workflows/ci.yml +142 -0
- package/tempoch-js/.gitmodules +3 -0
- package/tempoch-js/CHANGELOG.md +25 -0
- package/tempoch-js/LICENSE +661 -0
- package/tempoch-js/README.md +126 -0
- package/tempoch-js/package.json +20 -0
- package/tempoch-js/scripts/ci.sh +73 -0
- package/tempoch-js/tempoch/.github/workflows/ci.yml +113 -0
- package/tempoch-js/tempoch/CHANGELOG.md +82 -0
- package/tempoch-js/tempoch/Cargo.lock +947 -0
- package/tempoch-js/tempoch/Cargo.toml +3 -0
- package/tempoch-js/tempoch/LICENSE +661 -0
- package/tempoch-js/tempoch/README.md +76 -0
- package/tempoch-js/tempoch/tempoch/Cargo.toml +27 -0
- package/tempoch-js/tempoch/tempoch/examples/periods.rs +45 -0
- package/tempoch-js/tempoch/tempoch/examples/quickstart.rs +13 -0
- package/tempoch-js/tempoch/tempoch/src/lib.rs +49 -0
- package/tempoch-js/tempoch/tempoch/tests/integration.rs +57 -0
- package/tempoch-js/tempoch/tempoch-core/Cargo.toml +24 -0
- package/tempoch-js/tempoch/tempoch-core/src/delta_t.rs +345 -0
- package/tempoch-js/tempoch/tempoch-core/src/instant.rs +811 -0
- package/tempoch-js/tempoch/tempoch-core/src/julian_date_ext.rs +142 -0
- package/tempoch-js/tempoch/tempoch-core/src/lib.rs +81 -0
- package/tempoch-js/tempoch/tempoch-core/src/period.rs +1168 -0
- package/tempoch-js/tempoch/tempoch-core/src/scales.rs +779 -0
- package/tempoch-js/tempoch/tempoch-ffi/Cargo.lock +889 -0
- package/tempoch-js/tempoch/tempoch-ffi/Cargo.toml +26 -0
- package/tempoch-js/tempoch/tempoch-ffi/build.rs +24 -0
- package/tempoch-js/tempoch/tempoch-ffi/cbindgen.toml +30 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/error.rs +19 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/lib.rs +82 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/period.rs +101 -0
- package/tempoch-js/tempoch/tempoch-ffi/src/time.rs +711 -0
- package/tempoch-js/tempoch/tempoch-ffi/tests/ffi.rs +265 -0
- package/tempoch-js/tempoch-node/.prettierignore +6 -0
- package/tempoch-js/tempoch-node/.prettierrc.json +6 -0
- package/tempoch-js/tempoch-node/Cargo.lock +496 -0
- package/tempoch-js/tempoch-node/Cargo.toml +29 -0
- package/tempoch-js/tempoch-node/README.md +265 -0
- package/tempoch-js/tempoch-node/__test__/index.test.mjs +598 -0
- package/tempoch-js/tempoch-node/build.rs +5 -0
- package/tempoch-js/tempoch-node/c8.config.json +3 -0
- package/tempoch-js/tempoch-node/eslint.config.js +31 -0
- package/tempoch-js/tempoch-node/examples/periods.mjs +79 -0
- package/tempoch-js/tempoch-node/examples/quickstart.mjs +71 -0
- package/tempoch-js/tempoch-node/examples/timescales.mjs +92 -0
- package/tempoch-js/tempoch-node/index.d.ts +280 -0
- package/tempoch-js/tempoch-node/index.js +32 -0
- package/tempoch-js/tempoch-node/lib/JulianDate.js +176 -0
- package/tempoch-js/tempoch-node/lib/ModifiedJulianDate.js +156 -0
- package/tempoch-js/tempoch-node/lib/Period.js +133 -0
- package/tempoch-js/tempoch-node/lib/backend.js +38 -0
- package/tempoch-js/tempoch-node/lib/qttyCompat.js +92 -0
- package/tempoch-js/tempoch-node/native.cjs +317 -0
- package/tempoch-js/tempoch-node/package-lock.json +3223 -0
- package/tempoch-js/tempoch-node/package.json +56 -0
- package/tempoch-js/tempoch-node/src/lib.rs +573 -0
- package/tempoch-js/tempoch-web/Cargo.toml +23 -0
- package/tempoch-js/tempoch-web/index.d.ts +95 -0
- package/tempoch-js/tempoch-web/index.js +27 -0
- package/tempoch-js/tempoch-web/lib/JulianDate.js +170 -0
- package/tempoch-js/tempoch-web/lib/ModifiedJulianDate.js +145 -0
- package/tempoch-js/tempoch-web/lib/Period.js +121 -0
- package/tempoch-js/tempoch-web/lib/backend.js +118 -0
- package/tempoch-js/tempoch-web/package.json +46 -0
- package/tempoch-js/tempoch-web/src/lib.rs +184 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
//! Dimensionless helpers.
|
|
2
|
+
//!
|
|
3
|
+
//! This module contains small adapters for working with dimensionless values.
|
|
4
|
+
//!
|
|
5
|
+
//! The provided conversion from a dimensioned quantity to a unitless quantity is *lossy*: it drops the unit type
|
|
6
|
+
//! without performing any normalization. The numeric value is preserved as-is.
|
|
7
|
+
//!
|
|
8
|
+
//! ```rust
|
|
9
|
+
//! use qtty_core::time::Seconds;
|
|
10
|
+
//! use qtty_core::{Quantity, Unitless};
|
|
11
|
+
//!
|
|
12
|
+
//! let t = Seconds::new(3.0);
|
|
13
|
+
//! let u: Quantity<Unitless> = t.into();
|
|
14
|
+
//! assert_eq!(u.value(), 3.0);
|
|
15
|
+
//! ```
|
|
16
|
+
|
|
17
|
+
use crate::dimension::{
|
|
18
|
+
Acceleration, AmountOfSubstance, Angular, Area, Current, Energy, Force, FrequencyDim, Length,
|
|
19
|
+
LuminousIntensity, Mass, Power, Temperature, Time, VelocityDim, Volume,
|
|
20
|
+
};
|
|
21
|
+
use crate::scalar::Scalar;
|
|
22
|
+
use crate::{Quantity, Unit, Unitless};
|
|
23
|
+
|
|
24
|
+
trait SupportedDimension {}
|
|
25
|
+
impl SupportedDimension for Length {}
|
|
26
|
+
impl SupportedDimension for Time {}
|
|
27
|
+
impl SupportedDimension for Mass {}
|
|
28
|
+
impl SupportedDimension for Temperature {}
|
|
29
|
+
impl SupportedDimension for Current {}
|
|
30
|
+
impl SupportedDimension for AmountOfSubstance {}
|
|
31
|
+
impl SupportedDimension for LuminousIntensity {}
|
|
32
|
+
impl SupportedDimension for Angular {}
|
|
33
|
+
impl SupportedDimension for Area {}
|
|
34
|
+
impl SupportedDimension for Volume {}
|
|
35
|
+
impl SupportedDimension for VelocityDim {}
|
|
36
|
+
impl SupportedDimension for Acceleration {}
|
|
37
|
+
impl SupportedDimension for Force {}
|
|
38
|
+
impl SupportedDimension for Energy {}
|
|
39
|
+
impl SupportedDimension for Power {}
|
|
40
|
+
impl SupportedDimension for FrequencyDim {}
|
|
41
|
+
|
|
42
|
+
trait DimensionedUnit: Unit {}
|
|
43
|
+
impl<U: Unit> DimensionedUnit for U where U::Dim: SupportedDimension {}
|
|
44
|
+
|
|
45
|
+
impl<U: DimensionedUnit, S: Scalar> From<Quantity<U, S>> for Quantity<Unitless, S> {
|
|
46
|
+
#[inline]
|
|
47
|
+
fn from(quantity: Quantity<U, S>) -> Self {
|
|
48
|
+
Self::new(quantity.value())
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#[cfg(test)]
|
|
53
|
+
mod tests {
|
|
54
|
+
use super::*;
|
|
55
|
+
use crate::units::angular::Degrees;
|
|
56
|
+
use crate::units::length::Meters;
|
|
57
|
+
use crate::units::mass::Kilogram;
|
|
58
|
+
use crate::units::mass::Kilograms;
|
|
59
|
+
use crate::units::time::Seconds;
|
|
60
|
+
use crate::Unit;
|
|
61
|
+
use approx::assert_abs_diff_eq;
|
|
62
|
+
use proptest::prelude::*;
|
|
63
|
+
|
|
64
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
65
|
+
// Basic Unitless behavior
|
|
66
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
#[test]
|
|
69
|
+
fn unitless_new_and_value() {
|
|
70
|
+
let u: Quantity<Unitless> = Quantity::new(42.0);
|
|
71
|
+
assert_eq!(u.value(), 42.0);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#[test]
|
|
75
|
+
fn unitless_from_f64() {
|
|
76
|
+
let u: Quantity<Unitless> = 1.23456.into();
|
|
77
|
+
assert_abs_diff_eq!(u.value(), 1.23456, epsilon = 1e-12);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
+
// Display formatting
|
|
82
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
#[test]
|
|
85
|
+
fn display_unitless() {
|
|
86
|
+
let u: Quantity<Unitless> = Quantity::new(123.456);
|
|
87
|
+
let s = format!("{}", u);
|
|
88
|
+
assert_eq!(s, "123.456");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#[test]
|
|
92
|
+
fn display_unitless_integer() {
|
|
93
|
+
let u: Quantity<Unitless> = Quantity::new(42.0);
|
|
94
|
+
let s = format!("{}", u);
|
|
95
|
+
assert_eq!(s, "42");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
99
|
+
// Conversion from dimensioned quantities
|
|
100
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
#[test]
|
|
103
|
+
fn from_length() {
|
|
104
|
+
let m = Meters::new(42.0);
|
|
105
|
+
let u: Quantity<Unitless> = m.into();
|
|
106
|
+
assert_eq!(u.value(), 42.0);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#[test]
|
|
110
|
+
fn from_time() {
|
|
111
|
+
let t = Seconds::new(5.0);
|
|
112
|
+
let u: Quantity<Unitless> = t.into();
|
|
113
|
+
assert_eq!(u.value(), 5.0);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#[test]
|
|
117
|
+
fn from_mass() {
|
|
118
|
+
let m = Kilograms::new(2.5);
|
|
119
|
+
let u: Quantity<Unitless> = m.into();
|
|
120
|
+
assert_eq!(u.value(), 2.5);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#[test]
|
|
124
|
+
fn from_angular() {
|
|
125
|
+
let a = Degrees::new(90.0);
|
|
126
|
+
let u: Quantity<Unitless> = a.into();
|
|
127
|
+
assert_eq!(u.value(), 90.0);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#[test]
|
|
131
|
+
fn from_mass_preserves_non_default_scalar_type() {
|
|
132
|
+
let m: Quantity<Kilogram, i32> = Quantity::new(7);
|
|
133
|
+
let u: Quantity<Unitless, i32> = m.into();
|
|
134
|
+
assert_eq!(u.value(), 7);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
138
|
+
// Arithmetic operations
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
#[test]
|
|
142
|
+
fn unitless_addition() {
|
|
143
|
+
let a: Quantity<Unitless> = Quantity::new(3.0);
|
|
144
|
+
let b: Quantity<Unitless> = Quantity::new(4.0);
|
|
145
|
+
assert_eq!((a + b).value(), 7.0);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#[test]
|
|
149
|
+
fn unitless_subtraction() {
|
|
150
|
+
let a: Quantity<Unitless> = Quantity::new(10.0);
|
|
151
|
+
let b: Quantity<Unitless> = Quantity::new(3.0);
|
|
152
|
+
assert_eq!((a - b).value(), 7.0);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
#[test]
|
|
156
|
+
fn unitless_multiplication() {
|
|
157
|
+
let a: Quantity<Unitless> = Quantity::new(3.0);
|
|
158
|
+
assert_eq!((a * 4.0).value(), 12.0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#[test]
|
|
162
|
+
fn unitless_division() {
|
|
163
|
+
let a: Quantity<Unitless> = Quantity::new(12.0);
|
|
164
|
+
assert_eq!((a / 4.0).value(), 3.0);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
168
|
+
// Unit trait implementation
|
|
169
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
170
|
+
|
|
171
|
+
#[test]
|
|
172
|
+
fn unitless_ratio() {
|
|
173
|
+
assert_eq!(Unitless::RATIO, 1.0);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
#[test]
|
|
177
|
+
fn unitless_symbol() {
|
|
178
|
+
assert_eq!(Unitless::SYMBOL, "");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
182
|
+
// Property-based tests
|
|
183
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
184
|
+
|
|
185
|
+
proptest! {
|
|
186
|
+
#[test]
|
|
187
|
+
fn prop_unitless_arithmetic(a in -1e6..1e6f64, b in -1e6..1e6f64) {
|
|
188
|
+
let qa: Quantity<Unitless> = Quantity::new(a);
|
|
189
|
+
let qb: Quantity<Unitless> = Quantity::new(b);
|
|
190
|
+
|
|
191
|
+
// Addition is commutative
|
|
192
|
+
prop_assert!((((qa + qb).value() - (qb + qa).value()).abs() < 1e-9));
|
|
193
|
+
|
|
194
|
+
// Value is preserved
|
|
195
|
+
prop_assert!(((qa + qb).value() - (a + b)).abs() < 1e-9);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#[test]
|
|
199
|
+
fn prop_from_length_preserves_value(v in -1e6..1e6f64) {
|
|
200
|
+
let m = Meters::new(v);
|
|
201
|
+
let u: Quantity<Unitless> = m.into();
|
|
202
|
+
prop_assert!((u.value() - v).abs() < 1e-12);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#[test]
|
|
206
|
+
fn prop_from_time_preserves_value(v in -1e6..1e6f64) {
|
|
207
|
+
let t = Seconds::new(v);
|
|
208
|
+
let u: Quantity<Unitless> = t.into();
|
|
209
|
+
prop_assert!((u.value() - v).abs() < 1e-12);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
//! Velocity unit aliases (`Length / Time`).
|
|
2
|
+
//!
|
|
3
|
+
//! This module defines velocity units as *pure type aliases* over [`Per`] using
|
|
4
|
+
//! length and time units already defined elsewhere in the crate.
|
|
5
|
+
//!
|
|
6
|
+
//! No standalone velocity units are introduced: every velocity is represented as
|
|
7
|
+
//! `Length / Time` at the type level.
|
|
8
|
+
//!
|
|
9
|
+
//! ## Design notes
|
|
10
|
+
//!
|
|
11
|
+
//! - The velocity *dimension* is [`Velocity`] = [`Length`] / [`Time`].
|
|
12
|
+
//! - All velocity units are zero-cost type aliases.
|
|
13
|
+
//! - Conversions are handled automatically via the underlying length and time units.
|
|
14
|
+
//! - No assumptions are made about reference frames, relativistic effects, or media.
|
|
15
|
+
//!
|
|
16
|
+
//! ## Examples
|
|
17
|
+
//!
|
|
18
|
+
//! ```rust
|
|
19
|
+
//! use qtty_core::length::{Kilometer, Kilometers};
|
|
20
|
+
//! use qtty_core::time::{Second, Seconds};
|
|
21
|
+
//! use qtty_core::velocity::Velocity;
|
|
22
|
+
//!
|
|
23
|
+
//! let d = Kilometers::new(42.0);
|
|
24
|
+
//! let t = Seconds::new(2.0);
|
|
25
|
+
//! let v: Velocity<Kilometer, Second> = d / t;
|
|
26
|
+
//! assert!((v.value() - 21.0).abs() < 1e-12);
|
|
27
|
+
//! ```
|
|
28
|
+
//!
|
|
29
|
+
//! ```rust
|
|
30
|
+
//! use qtty_core::length::{Meter, Meters};
|
|
31
|
+
//! use qtty_core::time::{Hour, Hours};
|
|
32
|
+
//! use qtty_core::velocity::Velocity;
|
|
33
|
+
//!
|
|
34
|
+
//! let v: Velocity<Meter, Hour> = Meters::new(3_600.0) / Hours::new(1.0);
|
|
35
|
+
//! assert!((v.value() - 3_600.0).abs() < 1e-12);
|
|
36
|
+
//! ```
|
|
37
|
+
|
|
38
|
+
use crate::{Per, Quantity, Unit};
|
|
39
|
+
|
|
40
|
+
/// Re-export the velocity dimension from the dimension module.
|
|
41
|
+
pub use crate::dimension::VelocityDim;
|
|
42
|
+
|
|
43
|
+
/// Marker trait for any unit whose dimension is [`VelocityDim`].
|
|
44
|
+
pub trait VelocityUnit: Unit<Dim = VelocityDim> {}
|
|
45
|
+
impl<T: Unit<Dim = VelocityDim>> VelocityUnit for T {}
|
|
46
|
+
|
|
47
|
+
/// A velocity quantity parameterized by length and time units.
|
|
48
|
+
///
|
|
49
|
+
/// # Examples
|
|
50
|
+
///
|
|
51
|
+
/// ```rust
|
|
52
|
+
/// use qtty_core::length::{Kilometer, Meter};
|
|
53
|
+
/// use qtty_core::time::{Second, Hour};
|
|
54
|
+
/// use qtty_core::velocity::Velocity;
|
|
55
|
+
///
|
|
56
|
+
/// let v1: Velocity<Meter, Second> = Velocity::new(10.0);
|
|
57
|
+
/// let v2: Velocity<Kilometer, Hour> = Velocity::new(36.0);
|
|
58
|
+
/// ```
|
|
59
|
+
pub type Velocity<N, D> = Quantity<Per<N, D>>;
|
|
60
|
+
|
|
61
|
+
#[cfg(test)]
|
|
62
|
+
mod tests {
|
|
63
|
+
use super::*;
|
|
64
|
+
use crate::units::length::{Au, Kilometer, Kilometers, Meter};
|
|
65
|
+
use crate::units::time::{Day, Hour, Second, Seconds};
|
|
66
|
+
use crate::Per;
|
|
67
|
+
use approx::{assert_abs_diff_eq, assert_relative_eq};
|
|
68
|
+
use proptest::prelude::*;
|
|
69
|
+
|
|
70
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
71
|
+
// Basic velocity conversions
|
|
72
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
#[test]
|
|
75
|
+
fn km_per_s_to_m_per_s() {
|
|
76
|
+
let v: Velocity<Kilometer, Second> = Velocity::new(1.0);
|
|
77
|
+
let v_mps: Velocity<Meter, Second> = v.to();
|
|
78
|
+
assert_abs_diff_eq!(v_mps.value(), 1000.0, epsilon = 1e-9);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#[test]
|
|
82
|
+
fn m_per_s_to_km_per_s() {
|
|
83
|
+
let v: Velocity<Meter, Second> = Velocity::new(1000.0);
|
|
84
|
+
let v_kps: Velocity<Kilometer, Second> = v.to();
|
|
85
|
+
assert_abs_diff_eq!(v_kps.value(), 1.0, epsilon = 1e-12);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#[test]
|
|
89
|
+
fn km_per_h_to_m_per_s() {
|
|
90
|
+
let v: Velocity<Kilometer, Hour> = Velocity::new(3.6);
|
|
91
|
+
let v_mps: Velocity<Meter, Second> = v.to();
|
|
92
|
+
// 3.6 km/h = 1 m/s
|
|
93
|
+
assert_abs_diff_eq!(v_mps.value(), 1.0, epsilon = 1e-12);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
#[test]
|
|
97
|
+
fn km_per_h_to_km_per_s() {
|
|
98
|
+
let v: Velocity<Kilometer, Hour> = Velocity::new(3600.0);
|
|
99
|
+
let v_kps: Velocity<Kilometer, Second> = v.to();
|
|
100
|
+
// 3600 km/h = 1 km/s
|
|
101
|
+
assert_abs_diff_eq!(v_kps.value(), 1.0, epsilon = 1e-12);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#[test]
|
|
105
|
+
fn au_per_day_to_km_per_s() {
|
|
106
|
+
let v: Velocity<Au, Day> = Velocity::new(1.0);
|
|
107
|
+
let v_kps: Velocity<Kilometer, Second> = v.to();
|
|
108
|
+
// 1 AU/day = 149,597,870.7 km / 86400 s ≈ 1731.5 km/s
|
|
109
|
+
assert_relative_eq!(v_kps.value(), 1731.5, max_relative = 1e-3);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
113
|
+
// Per ratio behavior
|
|
114
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
#[test]
|
|
117
|
+
fn per_ratio_km_s() {
|
|
118
|
+
// Per<Kilometer, Second> should have RATIO = 1000 / 1 = 1000
|
|
119
|
+
let ratio = <Per<Kilometer, Second>>::RATIO;
|
|
120
|
+
// Kilometer::RATIO = 1000, Second::RATIO = 1.0
|
|
121
|
+
// So Per ratio = 1000 / 1.0 = 1000
|
|
122
|
+
assert_relative_eq!(ratio, 1000.0, max_relative = 1e-12);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#[test]
|
|
126
|
+
fn per_ratio_m_s() {
|
|
127
|
+
// Per<Meter, Second> has RATIO = 1 / 1 = 1
|
|
128
|
+
let ratio = <Per<Meter, Second>>::RATIO;
|
|
129
|
+
assert_relative_eq!(ratio, 1.0, max_relative = 1e-12);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
133
|
+
// Velocity * Time = Length
|
|
134
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
#[test]
|
|
137
|
+
fn velocity_times_time() {
|
|
138
|
+
let v: Velocity<Kilometer, Second> = Velocity::new(10.0);
|
|
139
|
+
let t: Seconds = Seconds::new(5.0);
|
|
140
|
+
let d: Kilometers = (v * t).to();
|
|
141
|
+
assert_abs_diff_eq!(d.value(), 50.0, epsilon = 1e-9);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#[test]
|
|
145
|
+
fn time_times_velocity() {
|
|
146
|
+
let v: Velocity<Kilometer, Second> = Velocity::new(10.0);
|
|
147
|
+
let t: Seconds = Seconds::new(5.0);
|
|
148
|
+
let d: Kilometers = (t * v).to();
|
|
149
|
+
assert_abs_diff_eq!(d.value(), 50.0, epsilon = 1e-9);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
153
|
+
// Length / Time = Velocity
|
|
154
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
#[test]
|
|
157
|
+
fn length_div_time() {
|
|
158
|
+
let d: Kilometers = Kilometers::new(100.0);
|
|
159
|
+
let t: Seconds = Seconds::new(10.0);
|
|
160
|
+
let v: Velocity<Kilometer, Second> = d / t;
|
|
161
|
+
assert_abs_diff_eq!(v.value(), 10.0, epsilon = 1e-9);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
165
|
+
// Roundtrip conversions
|
|
166
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
167
|
+
|
|
168
|
+
#[test]
|
|
169
|
+
fn roundtrip_mps_kps() {
|
|
170
|
+
let original: Velocity<Meter, Second> = Velocity::new(500.0);
|
|
171
|
+
let converted: Velocity<Kilometer, Second> = original.to();
|
|
172
|
+
let back: Velocity<Meter, Second> = converted.to();
|
|
173
|
+
assert_abs_diff_eq!(back.value(), original.value(), epsilon = 1e-9);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
177
|
+
// Property-based tests
|
|
178
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
proptest! {
|
|
181
|
+
#[test]
|
|
182
|
+
fn prop_roundtrip_mps_kps(v in 1e-6..1e6f64) {
|
|
183
|
+
let original: Velocity<Meter, Second> = Velocity::new(v);
|
|
184
|
+
let converted: Velocity<Kilometer, Second> = original.to();
|
|
185
|
+
let back: Velocity<Meter, Second> = converted.to();
|
|
186
|
+
prop_assert!((back.value() - original.value()).abs() < 1e-9 * v.abs().max(1.0));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#[test]
|
|
190
|
+
fn prop_mps_kps_ratio(v in 1e-6..1e6f64) {
|
|
191
|
+
let mps: Velocity<Meter, Second> = Velocity::new(v);
|
|
192
|
+
let kps: Velocity<Kilometer, Second> = mps.to();
|
|
193
|
+
// 1000 m/s = 1 km/s
|
|
194
|
+
prop_assert!((mps.value() / kps.value() - 1000.0).abs() < 1e-9);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#[test]
|
|
198
|
+
fn prop_velocity_time_roundtrip(
|
|
199
|
+
v_val in 1e-3..1e3f64,
|
|
200
|
+
t_val in 1e-3..1e3f64
|
|
201
|
+
) {
|
|
202
|
+
let v: Velocity<Kilometer, Second> = Velocity::new(v_val);
|
|
203
|
+
let t: Seconds = Seconds::new(t_val);
|
|
204
|
+
let d: Kilometers = (v * t).to();
|
|
205
|
+
// d / t should give back v
|
|
206
|
+
let v_back: Velocity<Kilometer, Second> = d / t;
|
|
207
|
+
prop_assert!((v_back.value() - v.value()).abs() / v.value() < 1e-12);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
//! Volume units.
|
|
2
|
+
//!
|
|
3
|
+
//! The canonical scaling unit for this dimension is the **cubic metre** (`CubicMeter::RATIO == 1.0`).
|
|
4
|
+
//! All other volume units are expressed as exact ratios to cubic metres.
|
|
5
|
+
//!
|
|
6
|
+
//! This module provides:
|
|
7
|
+
//!
|
|
8
|
+
//! - **Metric cubes**: cubic millimetre, cubic centimetre, cubic metre, cubic kilometre.
|
|
9
|
+
//! - **Litre family**: microlitre, millilitre, centilitre, decilitre, litre.
|
|
10
|
+
//! - **Imperial/US**: cubic inch, cubic foot, US gallon, US fluid ounce.
|
|
11
|
+
//!
|
|
12
|
+
//! Volume units can also arise *automatically* from multiplying length × area quantities:
|
|
13
|
+
//!
|
|
14
|
+
//! ```rust
|
|
15
|
+
//! use qtty_core::length::{Meter, Meters};
|
|
16
|
+
//! use qtty_core::area::{SquareMeter, SquareMeters};
|
|
17
|
+
//! use qtty_core::volume::{CubicMeters, CubicMeter};
|
|
18
|
+
//! use qtty_core::Prod;
|
|
19
|
+
//!
|
|
20
|
+
//! let side = Meters::new(3.0);
|
|
21
|
+
//! let face: SquareMeters = (side * side).to();
|
|
22
|
+
//! let vol_prod = face * side; // Quantity<Prod<SquareMeter, Meter>>
|
|
23
|
+
//! let vol: CubicMeters = vol_prod.to();
|
|
24
|
+
//! assert!((vol.value() - 27.0).abs() < 1e-12);
|
|
25
|
+
//! ```
|
|
26
|
+
//!
|
|
27
|
+
//! ## All volume units
|
|
28
|
+
//!
|
|
29
|
+
//! ```rust
|
|
30
|
+
//! use qtty_core::volume::*;
|
|
31
|
+
//!
|
|
32
|
+
//! macro_rules! touch {
|
|
33
|
+
//! ($T:ty, $v:expr) => {{ let q = <$T>::new($v); let _c = q; assert!(q == q); }};
|
|
34
|
+
//! }
|
|
35
|
+
//!
|
|
36
|
+
//! touch!(CubicMeters, 1.0); touch!(CubicKilometers, 1.0);
|
|
37
|
+
//! touch!(CubicCentimeters, 1.0); touch!(CubicMillimeters, 1.0);
|
|
38
|
+
//! touch!(Liters, 1.0); touch!(Milliliters, 1.0);
|
|
39
|
+
//! touch!(Microliters, 1.0); touch!(Centiliters, 1.0);
|
|
40
|
+
//! touch!(Deciliters, 1.0); touch!(CubicInches, 1.0);
|
|
41
|
+
//! touch!(CubicFeet, 1.0); touch!(UsGallons, 1.0);
|
|
42
|
+
//! touch!(UsFluidOunces, 1.0);
|
|
43
|
+
//! ```
|
|
44
|
+
|
|
45
|
+
use crate::{Quantity, Unit};
|
|
46
|
+
use qtty_derive::Unit;
|
|
47
|
+
|
|
48
|
+
/// Re-export the volume dimension from the dimension module.
|
|
49
|
+
pub use crate::dimension::Volume;
|
|
50
|
+
|
|
51
|
+
/// Marker trait for any [`Unit`] whose dimension is [`Volume`].
|
|
52
|
+
pub trait VolumeUnit: Unit<Dim = Volume> {}
|
|
53
|
+
impl<T: Unit<Dim = Volume>> VolumeUnit for T {}
|
|
54
|
+
|
|
55
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
// SI / metric volume units
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
/// Cubic metre (SI derived unit of volume).
|
|
60
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
61
|
+
#[unit(symbol = "m³", dimension = Volume, ratio = 1.0)]
|
|
62
|
+
pub struct CubicMeter;
|
|
63
|
+
/// A quantity measured in cubic metres.
|
|
64
|
+
pub type CubicMeters = Quantity<CubicMeter>;
|
|
65
|
+
|
|
66
|
+
/// Cubic kilometre (`1e9 m³`).
|
|
67
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
68
|
+
#[unit(symbol = "km³", dimension = Volume, ratio = 1e9)]
|
|
69
|
+
pub struct CubicKilometer;
|
|
70
|
+
/// A quantity measured in cubic kilometres.
|
|
71
|
+
pub type CubicKilometers = Quantity<CubicKilometer>;
|
|
72
|
+
|
|
73
|
+
/// Cubic centimetre (`1e-6 m³`).
|
|
74
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
75
|
+
#[unit(symbol = "cm³", dimension = Volume, ratio = 1e-6)]
|
|
76
|
+
pub struct CubicCentimeter;
|
|
77
|
+
/// A quantity measured in cubic centimetres.
|
|
78
|
+
pub type CubicCentimeters = Quantity<CubicCentimeter>;
|
|
79
|
+
|
|
80
|
+
/// Cubic millimetre (`1e-9 m³`).
|
|
81
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
82
|
+
#[unit(symbol = "mm³", dimension = Volume, ratio = 1e-9)]
|
|
83
|
+
pub struct CubicMillimeter;
|
|
84
|
+
/// A quantity measured in cubic millimetres.
|
|
85
|
+
pub type CubicMillimeters = Quantity<CubicMillimeter>;
|
|
86
|
+
|
|
87
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
+
// Litre family
|
|
89
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
/// Litre (`1e-3 m³`, exact).
|
|
92
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
93
|
+
#[unit(symbol = "L", dimension = Volume, ratio = 1e-3)]
|
|
94
|
+
pub struct Liter;
|
|
95
|
+
/// A quantity measured in litres.
|
|
96
|
+
pub type Liters = Quantity<Liter>;
|
|
97
|
+
|
|
98
|
+
/// Millilitre (`1e-6 m³`, exact).
|
|
99
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
100
|
+
#[unit(symbol = "mL", dimension = Volume, ratio = 1e-6)]
|
|
101
|
+
pub struct Milliliter;
|
|
102
|
+
/// A quantity measured in millilitres.
|
|
103
|
+
pub type Milliliters = Quantity<Milliliter>;
|
|
104
|
+
|
|
105
|
+
/// Microlitre (`1e-9 m³`, exact).
|
|
106
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
107
|
+
#[unit(symbol = "µL", dimension = Volume, ratio = 1e-9)]
|
|
108
|
+
pub struct Microliter;
|
|
109
|
+
/// A quantity measured in microlitres.
|
|
110
|
+
pub type Microliters = Quantity<Microliter>;
|
|
111
|
+
|
|
112
|
+
/// Centilitre (`1e-5 m³`, exact).
|
|
113
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
114
|
+
#[unit(symbol = "cL", dimension = Volume, ratio = 1e-5)]
|
|
115
|
+
pub struct Centiliter;
|
|
116
|
+
/// A quantity measured in centilitres.
|
|
117
|
+
pub type Centiliters = Quantity<Centiliter>;
|
|
118
|
+
|
|
119
|
+
/// Decilitre (`1e-4 m³`, exact).
|
|
120
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
121
|
+
#[unit(symbol = "dL", dimension = Volume, ratio = 1e-4)]
|
|
122
|
+
pub struct Deciliter;
|
|
123
|
+
/// A quantity measured in decilitres.
|
|
124
|
+
pub type Deciliters = Quantity<Deciliter>;
|
|
125
|
+
|
|
126
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
127
|
+
// Imperial / US customary volume units
|
|
128
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
/// Cubic inch (`1.6387064e-5 m³`, exact: `0.0254³ m³`).
|
|
131
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
132
|
+
#[unit(symbol = "in³", dimension = Volume, ratio = 1.638_706_4e-5)]
|
|
133
|
+
pub struct CubicInch;
|
|
134
|
+
/// A quantity measured in cubic inches.
|
|
135
|
+
pub type CubicInches = Quantity<CubicInch>;
|
|
136
|
+
|
|
137
|
+
/// Cubic foot (`0.028316846592 m³`, exact: `0.3048³ m³`).
|
|
138
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
139
|
+
#[unit(symbol = "ft³", dimension = Volume, ratio = 0.028_316_846_592)]
|
|
140
|
+
pub struct CubicFoot;
|
|
141
|
+
/// A quantity measured in cubic feet.
|
|
142
|
+
pub type CubicFeet = Quantity<CubicFoot>;
|
|
143
|
+
|
|
144
|
+
/// US liquid gallon (`0.003785411784 m³`, exact: `231 in³`).
|
|
145
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
146
|
+
#[unit(symbol = "gal", dimension = Volume, ratio = 0.003_785_411_784)]
|
|
147
|
+
pub struct UsGallon;
|
|
148
|
+
/// A quantity measured in US gallons.
|
|
149
|
+
pub type UsGallons = Quantity<UsGallon>;
|
|
150
|
+
|
|
151
|
+
/// US fluid ounce (`2.95735295625e-5 m³`, exact: `gal / 128`).
|
|
152
|
+
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
|
|
153
|
+
#[unit(symbol = "fl oz", dimension = Volume, ratio = 2.957_352_956_25e-5)]
|
|
154
|
+
pub struct UsFluidOunce;
|
|
155
|
+
/// A quantity measured in US fluid ounces.
|
|
156
|
+
pub type UsFluidOunces = Quantity<UsFluidOunce>;
|
|
157
|
+
|
|
158
|
+
#[cfg(test)]
|
|
159
|
+
mod tests {
|
|
160
|
+
use super::*;
|
|
161
|
+
use approx::assert_abs_diff_eq;
|
|
162
|
+
|
|
163
|
+
#[test]
|
|
164
|
+
fn liter_to_cubic_meter() {
|
|
165
|
+
let l = Liters::new(1.0);
|
|
166
|
+
let m: CubicMeters = l.to();
|
|
167
|
+
assert_abs_diff_eq!(m.value(), 0.001, epsilon = 1e-15);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
#[test]
|
|
171
|
+
fn milliliter_to_liter() {
|
|
172
|
+
let ml = Milliliters::new(1000.0);
|
|
173
|
+
let l: Liters = ml.to();
|
|
174
|
+
assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
#[test]
|
|
178
|
+
fn cubic_cm_to_ml() {
|
|
179
|
+
let cc = CubicCentimeters::new(1.0);
|
|
180
|
+
let ml: Milliliters = cc.to();
|
|
181
|
+
assert_abs_diff_eq!(ml.value(), 1.0, epsilon = 1e-12);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
#[test]
|
|
185
|
+
fn us_gallon_to_liter() {
|
|
186
|
+
let g = UsGallons::new(1.0);
|
|
187
|
+
let l: Liters = g.to();
|
|
188
|
+
assert_abs_diff_eq!(l.value(), 3.785_411_784, epsilon = 1e-6);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#[test]
|
|
192
|
+
fn cubic_foot_to_liter() {
|
|
193
|
+
let cf = CubicFeet::new(1.0);
|
|
194
|
+
let l: Liters = cf.to();
|
|
195
|
+
assert_abs_diff_eq!(l.value(), 28.316_846_592, epsilon = 1e-6);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#[test]
|
|
199
|
+
fn length_times_area_to_volume() {
|
|
200
|
+
use crate::area::{SquareMeter, SquareMeters};
|
|
201
|
+
use crate::length::{Meter, Meters};
|
|
202
|
+
use crate::Prod;
|
|
203
|
+
|
|
204
|
+
let side = Meters::new(3.0);
|
|
205
|
+
let face: SquareMeters = (side * side).to();
|
|
206
|
+
let vol_prod: Quantity<Prod<SquareMeter, Meter>> = face * side;
|
|
207
|
+
let vol: CubicMeters = vol_prod.to();
|
|
208
|
+
assert_abs_diff_eq!(vol.value(), 27.0, epsilon = 1e-12);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#[test]
|
|
212
|
+
fn cubic_km_to_liter() {
|
|
213
|
+
let ckm = CubicKilometers::new(1.0);
|
|
214
|
+
let l: Liters = ckm.to();
|
|
215
|
+
assert_abs_diff_eq!(l.value(), 1e12, epsilon = 1e3);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
#[test]
|
|
219
|
+
fn cubic_mm_to_cubic_cm() {
|
|
220
|
+
let mm3 = CubicMillimeters::new(1000.0);
|
|
221
|
+
let cm3: CubicCentimeters = mm3.to();
|
|
222
|
+
assert_abs_diff_eq!(cm3.value(), 1.0, epsilon = 1e-12);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#[test]
|
|
226
|
+
fn microliter_to_milliliter() {
|
|
227
|
+
let ul = Microliters::new(1000.0);
|
|
228
|
+
let ml: Milliliters = ul.to();
|
|
229
|
+
assert_abs_diff_eq!(ml.value(), 1.0, epsilon = 1e-12);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
#[test]
|
|
233
|
+
fn centiliter_to_liter() {
|
|
234
|
+
let cl = Centiliters::new(100.0);
|
|
235
|
+
let l: Liters = cl.to();
|
|
236
|
+
assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
#[test]
|
|
240
|
+
fn deciliter_to_liter() {
|
|
241
|
+
let dl = Deciliters::new(10.0);
|
|
242
|
+
let l: Liters = dl.to();
|
|
243
|
+
assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#[test]
|
|
247
|
+
fn cubic_inch_to_cubic_cm() {
|
|
248
|
+
let cin = CubicInches::new(1.0);
|
|
249
|
+
let cc: CubicCentimeters = cin.to();
|
|
250
|
+
// 1 in³ = 16.387064 cm³
|
|
251
|
+
assert_abs_diff_eq!(cc.value(), 16.387_064, epsilon = 1e-4);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
#[test]
|
|
255
|
+
fn us_fluid_ounce_to_milliliter() {
|
|
256
|
+
let floz = UsFluidOunces::new(1.0);
|
|
257
|
+
let ml: Milliliters = floz.to();
|
|
258
|
+
// 1 US fl oz ≈ 29.5735 mL
|
|
259
|
+
assert_abs_diff_eq!(ml.value(), 29.573_529_562_5, epsilon = 1e-6);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#[test]
|
|
263
|
+
fn symbols_are_correct() {
|
|
264
|
+
assert_eq!(CubicMeter::SYMBOL, "m³");
|
|
265
|
+
assert_eq!(Liter::SYMBOL, "L");
|
|
266
|
+
assert_eq!(Milliliter::SYMBOL, "mL");
|
|
267
|
+
assert_eq!(UsGallon::SYMBOL, "gal");
|
|
268
|
+
}
|
|
269
|
+
}
|