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,41 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "qtty-core"
|
|
3
|
+
description = "Core types for zero-cost strongly-typed physical quantities."
|
|
4
|
+
version.workspace = true
|
|
5
|
+
edition.workspace = true
|
|
6
|
+
authors.workspace = true
|
|
7
|
+
license.workspace = true
|
|
8
|
+
repository.workspace = true
|
|
9
|
+
keywords.workspace = true
|
|
10
|
+
categories.workspace = true
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
documentation = "https://docs.rs/qtty-core"
|
|
13
|
+
|
|
14
|
+
[features]
|
|
15
|
+
default = ["std", "cross-unit-ops"]
|
|
16
|
+
std = []
|
|
17
|
+
cross-unit-ops = []
|
|
18
|
+
serde = ["dep:serde"]
|
|
19
|
+
|
|
20
|
+
# Optional support
|
|
21
|
+
scalar-decimal = ["rust_decimal"]
|
|
22
|
+
scalar-rational = ["num-rational"]
|
|
23
|
+
pyo3 = ["dep:pyo3"]
|
|
24
|
+
tiberius = ["dep:tiberius"]
|
|
25
|
+
diesel = ["dep:diesel"]
|
|
26
|
+
|
|
27
|
+
[dependencies]
|
|
28
|
+
rust_decimal = { version = "1.36", optional = true, features = ["maths"] }
|
|
29
|
+
num-rational = { version = "0.4", optional = true, default-features = false }
|
|
30
|
+
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true }
|
|
31
|
+
pyo3 = { version = "0.28.2", optional = true, features = ["auto-initialize"] }
|
|
32
|
+
tiberius = { version = "0.12", default-features = false, optional = true }
|
|
33
|
+
diesel = { version = "2.1", default-features = false, optional = true }
|
|
34
|
+
libm = "0.2"
|
|
35
|
+
typenum = "1.17"
|
|
36
|
+
qtty-derive = { version = "0.4.0", path = "../qtty-derive" }
|
|
37
|
+
|
|
38
|
+
[dev-dependencies]
|
|
39
|
+
approx = "0.5"
|
|
40
|
+
proptest = "1.4"
|
|
41
|
+
serde_json = "1.0"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# qtty-core crate
|
|
2
|
+
|
|
3
|
+
Centralized documentation lives under the repository `doc/` tree.
|
|
4
|
+
|
|
5
|
+
- Workspace overview: [`../../doc/users/rust-workspace.md`](../../doc/users/rust-workspace.md)
|
|
6
|
+
- Repository layout: [`../../doc/architecture/repository-layout.md`](../../doc/architecture/repository-layout.md)
|
|
7
|
+
|
|
8
|
+
This README remains as the crate metadata entrypoint.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
//! Example showing how to use `qtty_core::Quantity` types with Diesel ORM.
|
|
2
|
+
//!
|
|
3
|
+
//! This example demonstrates:
|
|
4
|
+
//! - Using `Quantity<U>` types (e.g., `Degrees`, `Meters`) directly in Diesel models
|
|
5
|
+
//! - Automatic serialization/deserialization to/from SQL DOUBLE PRECISION columns
|
|
6
|
+
//! - Type-safe queries with strongly-typed physical quantities
|
|
7
|
+
//!
|
|
8
|
+
//! # Running this example
|
|
9
|
+
//!
|
|
10
|
+
//! ```bash
|
|
11
|
+
//! cargo run -p qtty-core --example diesel_integration --features diesel
|
|
12
|
+
//! ```
|
|
13
|
+
//!
|
|
14
|
+
//! Note: This is a conceptual example showing the API usage. For a real database integration,
|
|
15
|
+
//! you would need to set up an actual database connection and schema.
|
|
16
|
+
|
|
17
|
+
#[cfg(feature = "diesel")]
|
|
18
|
+
fn main() {
|
|
19
|
+
use qtty_core::angular::Degrees;
|
|
20
|
+
use qtty_core::length::Meters;
|
|
21
|
+
|
|
22
|
+
println!("=== Diesel ORM Integration Example ===\n");
|
|
23
|
+
|
|
24
|
+
// Example 1: Conceptual Diesel model using Quantity types
|
|
25
|
+
println!("1. Diesel Model with Quantity Types:\n");
|
|
26
|
+
|
|
27
|
+
#[derive(Debug)]
|
|
28
|
+
#[allow(dead_code)]
|
|
29
|
+
struct Observatory {
|
|
30
|
+
id: i32,
|
|
31
|
+
name: String,
|
|
32
|
+
latitude: Degrees, // Instead of f64!
|
|
33
|
+
longitude: Degrees, // Type-safe angles
|
|
34
|
+
elevation: Meters, // Type-safe length
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let obs = Observatory {
|
|
38
|
+
id: 1,
|
|
39
|
+
name: "Mauna Kea".to_string(),
|
|
40
|
+
latitude: Degrees::new(19.8207),
|
|
41
|
+
longitude: Degrees::new(-155.4681),
|
|
42
|
+
elevation: Meters::new(4207.0),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
println!("Observatory: {}", obs.name);
|
|
46
|
+
println!(
|
|
47
|
+
" Location: {:.4}° N, {:.4}° W",
|
|
48
|
+
obs.latitude.value(),
|
|
49
|
+
obs.longitude.value().abs()
|
|
50
|
+
);
|
|
51
|
+
println!(" Elevation: {:.0} m", obs.elevation.value());
|
|
52
|
+
|
|
53
|
+
// Example 2: Type conversion
|
|
54
|
+
println!("\n2. Type Conversions:");
|
|
55
|
+
use qtty_core::angular::Radians;
|
|
56
|
+
use qtty_core::length::Kilometers;
|
|
57
|
+
|
|
58
|
+
let lat_rad: Radians = obs.latitude.to();
|
|
59
|
+
let elev_km: Kilometers = obs.elevation.to();
|
|
60
|
+
|
|
61
|
+
println!(" Latitude: {:.6} rad", lat_rad.value());
|
|
62
|
+
println!(" Elevation: {:.3} km", elev_km.value());
|
|
63
|
+
|
|
64
|
+
// Example 3: Conceptual schema definition
|
|
65
|
+
println!("\n3. Conceptual Diesel Schema:");
|
|
66
|
+
println!(
|
|
67
|
+
r#"
|
|
68
|
+
// In your Diesel schema.rs:
|
|
69
|
+
table! {{
|
|
70
|
+
observatories (id) {{
|
|
71
|
+
id -> Int4,
|
|
72
|
+
name -> Text,
|
|
73
|
+
latitude -> Float8, // Maps to qtty::Degrees
|
|
74
|
+
longitude -> Float8, // Maps to qtty::Degrees
|
|
75
|
+
elevation -> Float8, // Maps to qtty::Meters
|
|
76
|
+
}}
|
|
77
|
+
}}
|
|
78
|
+
|
|
79
|
+
// In your models.rs:
|
|
80
|
+
use qtty::{{Degrees, Meters}};
|
|
81
|
+
|
|
82
|
+
#[derive(Queryable, Selectable)]
|
|
83
|
+
#[diesel(table_name = observatories)]
|
|
84
|
+
pub struct Observatory {{
|
|
85
|
+
pub id: i32,
|
|
86
|
+
pub name: String,
|
|
87
|
+
pub latitude: Degrees, // Direct use of Quantity types!
|
|
88
|
+
pub longitude: Degrees,
|
|
89
|
+
pub elevation: Meters,
|
|
90
|
+
}}
|
|
91
|
+
|
|
92
|
+
#[derive(Insertable)]
|
|
93
|
+
#[diesel(table_name = observatories)]
|
|
94
|
+
pub struct NewObservatory {{
|
|
95
|
+
pub name: String,
|
|
96
|
+
pub latitude: Degrees,
|
|
97
|
+
pub longitude: Degrees,
|
|
98
|
+
pub elevation: Meters,
|
|
99
|
+
}}
|
|
100
|
+
"#
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// Example 4: Optional fields
|
|
104
|
+
println!("\n4. Optional Quantity Fields:");
|
|
105
|
+
|
|
106
|
+
#[derive(Debug)]
|
|
107
|
+
#[allow(dead_code)]
|
|
108
|
+
struct Telescope {
|
|
109
|
+
id: i32,
|
|
110
|
+
name: String,
|
|
111
|
+
min_altitude: Option<Degrees>, // Optional constraint
|
|
112
|
+
max_altitude: Option<Degrees>,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let telescope = Telescope {
|
|
116
|
+
id: 1,
|
|
117
|
+
name: "Keck I".to_string(),
|
|
118
|
+
min_altitude: Some(Degrees::new(15.0)),
|
|
119
|
+
max_altitude: Some(Degrees::new(85.0)),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
println!("Telescope: {}", telescope.name);
|
|
123
|
+
if let Some(min_alt) = telescope.min_altitude {
|
|
124
|
+
println!(" Min altitude: {}°", min_alt.value());
|
|
125
|
+
}
|
|
126
|
+
if let Some(max_alt) = telescope.max_altitude {
|
|
127
|
+
println!(" Max altitude: {}°", max_alt.value());
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Example 5: Benefits summary
|
|
131
|
+
println!("\n5. Benefits of Using Quantity Types:");
|
|
132
|
+
println!(" ✓ Compile-time unit checking");
|
|
133
|
+
println!(" ✓ No manual unit conversions in database layer");
|
|
134
|
+
println!(" ✓ Self-documenting code (field type shows units)");
|
|
135
|
+
println!(" ✓ Automatic serialization/deserialization");
|
|
136
|
+
println!(" ✓ Zero runtime overhead (newtype pattern)");
|
|
137
|
+
|
|
138
|
+
println!("\n=== Example Complete ===");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#[cfg(not(feature = "diesel"))]
|
|
142
|
+
fn main() {
|
|
143
|
+
println!("This example requires the 'diesel' feature to be enabled.");
|
|
144
|
+
println!("Run with: cargo run -p qtty-core --example diesel_integration --features diesel");
|
|
145
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
//! Example showing how to use `qtty_core::Quantity` types with `serde` and (optionally) Tiberius DB.
|
|
2
|
+
//!
|
|
3
|
+
//! This demonstrates:
|
|
4
|
+
//! - Default serde behavior: `Quantity<U>` serializes as a raw `f64` by default
|
|
5
|
+
//! - `qtty_core::serde_with_unit`: serialize with unit information using `#[serde(with = "...")]`
|
|
6
|
+
//! - `tiberius` feature: bind/extract `Quantity<U>` directly (conceptual example)
|
|
7
|
+
//!
|
|
8
|
+
//! Run with:
|
|
9
|
+
//! - `cargo run -p qtty-core --example quantity_db_serde --features serde`
|
|
10
|
+
//! - `cargo run -p qtty-core --example quantity_db_serde --features serde,tiberius`
|
|
11
|
+
|
|
12
|
+
#[cfg(feature = "serde")]
|
|
13
|
+
use qtty_core::angular::Degrees;
|
|
14
|
+
#[cfg(feature = "serde")]
|
|
15
|
+
use qtty_core::time::Seconds;
|
|
16
|
+
#[cfg(feature = "serde")]
|
|
17
|
+
use serde::{Deserialize, Serialize};
|
|
18
|
+
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
// Example 1: Serde with default f64 serialization
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
#[cfg(feature = "serde")]
|
|
24
|
+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
25
|
+
struct SchedulingConstraints {
|
|
26
|
+
/// Minimum altitude in degrees (serializes as raw f64 by default)
|
|
27
|
+
pub min_altitude: Degrees,
|
|
28
|
+
|
|
29
|
+
/// Maximum altitude in degrees (serializes as raw f64 by default)
|
|
30
|
+
pub max_altitude: Degrees,
|
|
31
|
+
|
|
32
|
+
/// Minimum azimuth in degrees (serializes as raw f64 by default)
|
|
33
|
+
pub min_azimuth: Degrees,
|
|
34
|
+
|
|
35
|
+
/// Maximum azimuth in degrees (serializes as raw f64 by default)
|
|
36
|
+
pub max_azimuth: Degrees,
|
|
37
|
+
|
|
38
|
+
/// Minimum observation time in seconds (serializes as raw f64 by default)
|
|
39
|
+
pub min_observation_time: Seconds,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#[cfg(feature = "serde")]
|
|
43
|
+
fn example_serde() {
|
|
44
|
+
println!("=== Default Serde Example (compact f64) ===\n");
|
|
45
|
+
|
|
46
|
+
// Create constraints with typed quantities
|
|
47
|
+
let constraints = SchedulingConstraints {
|
|
48
|
+
min_altitude: Degrees::new(30.0),
|
|
49
|
+
max_altitude: Degrees::new(90.0),
|
|
50
|
+
min_azimuth: Degrees::new(0.0),
|
|
51
|
+
max_azimuth: Degrees::new(360.0),
|
|
52
|
+
min_observation_time: Seconds::new(1200.0),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Serialize to JSON (as raw f64 values - compact!)
|
|
56
|
+
let json = serde_json::to_string_pretty(&constraints).unwrap();
|
|
57
|
+
println!("Serialized JSON:\n{}\n", json);
|
|
58
|
+
|
|
59
|
+
// Deserialize back
|
|
60
|
+
let parsed: SchedulingConstraints = serde_json::from_str(&json).unwrap();
|
|
61
|
+
println!("Deserialized successfully!");
|
|
62
|
+
assert_eq!(
|
|
63
|
+
constraints.min_altitude.value(),
|
|
64
|
+
parsed.min_altitude.value()
|
|
65
|
+
);
|
|
66
|
+
println!("✓ Round-trip successful\n");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
70
|
+
// Example 1b: Serde with unit information (for self-documenting APIs)
|
|
71
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
#[cfg(feature = "serde")]
|
|
74
|
+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
75
|
+
struct ConfigWithUnits {
|
|
76
|
+
/// Maximum speed with unit information preserved
|
|
77
|
+
#[serde(with = "qtty_core::serde_with_unit")]
|
|
78
|
+
pub max_altitude: Degrees,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#[cfg(feature = "serde")]
|
|
82
|
+
fn example_serde_with_unit() {
|
|
83
|
+
println!("=== Serde with Unit Information (self-documenting) ===\n");
|
|
84
|
+
|
|
85
|
+
let config = ConfigWithUnits {
|
|
86
|
+
max_altitude: Degrees::new(90.0),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Serialize to JSON with unit information
|
|
90
|
+
let json = serde_json::to_string_pretty(&config).unwrap();
|
|
91
|
+
println!("Serialized JSON:\n{}\n", json);
|
|
92
|
+
println!("✓ Unit symbol preserved in output for clarity!\n");
|
|
93
|
+
|
|
94
|
+
// Deserialize back
|
|
95
|
+
let parsed: ConfigWithUnits = serde_json::from_str(&json).unwrap();
|
|
96
|
+
assert_eq!(config.max_altitude.value(), parsed.max_altitude.value());
|
|
97
|
+
println!("✓ Round-trip successful\n");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
101
|
+
// Example 2: Direct DB usage (conceptual - requires actual DB connection)
|
|
102
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
#[cfg(all(feature = "serde", feature = "tiberius"))]
|
|
105
|
+
fn example_tiberius_concept() {
|
|
106
|
+
println!("=== Tiberius DB Example (conceptual) ===\n");
|
|
107
|
+
|
|
108
|
+
// In real code, you would:
|
|
109
|
+
// 1. Bind Quantity types directly to queries:
|
|
110
|
+
println!("// Binding Quantity to query:");
|
|
111
|
+
println!("let min_alt = Degrees::new(30.0);");
|
|
112
|
+
println!("query.bind(min_alt); // Works directly!\n");
|
|
113
|
+
|
|
114
|
+
// 2. Extract Quantity types from result rows:
|
|
115
|
+
println!("// Extracting Quantity from DB row:");
|
|
116
|
+
println!("let altitude: Degrees = row.try_get(\"altitude\")?.unwrap();");
|
|
117
|
+
println!("// No manual f64 → Degrees conversion needed!\n");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
121
|
+
// Example 3: Migration comparison
|
|
122
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
#[cfg(feature = "serde")]
|
|
125
|
+
fn example_migration_comparison() {
|
|
126
|
+
println!("=== Migration Comparison ===\n");
|
|
127
|
+
|
|
128
|
+
// Old approach: store as f64, convert on access
|
|
129
|
+
struct OldConstraints {
|
|
130
|
+
min_alt: f64,
|
|
131
|
+
max_alt: f64,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
impl OldConstraints {
|
|
135
|
+
fn min_alt(&self) -> Degrees {
|
|
136
|
+
Degrees::new(self.min_alt)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn max_alt(&self) -> Degrees {
|
|
140
|
+
Degrees::new(self.max_alt)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let old = OldConstraints {
|
|
145
|
+
min_alt: 30.0,
|
|
146
|
+
max_alt: 90.0,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
println!("Old approach:");
|
|
150
|
+
println!(" - Store: f64");
|
|
151
|
+
println!(" - Access: .min_alt() -> Degrees");
|
|
152
|
+
println!(
|
|
153
|
+
" - Values: {}..{} degrees\n",
|
|
154
|
+
old.min_alt().value(),
|
|
155
|
+
old.max_alt().value()
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// New approach: store as Quantity directly
|
|
159
|
+
#[derive(Serialize, Deserialize)]
|
|
160
|
+
struct NewConstraints {
|
|
161
|
+
min_alt: Degrees,
|
|
162
|
+
max_alt: Degrees,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let new = NewConstraints {
|
|
166
|
+
min_alt: Degrees::new(30.0),
|
|
167
|
+
max_alt: Degrees::new(90.0),
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
println!("New approach:");
|
|
171
|
+
println!(" - Store: Degrees (typed!)");
|
|
172
|
+
println!(" - Access: .min_alt (direct)");
|
|
173
|
+
println!(
|
|
174
|
+
" - Values: {}..{} degrees",
|
|
175
|
+
new.min_alt.value(),
|
|
176
|
+
new.max_alt.value()
|
|
177
|
+
);
|
|
178
|
+
println!(" ✓ No conversion methods needed!");
|
|
179
|
+
println!(" ✓ Type safety at compile time!\n");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
183
|
+
// Main
|
|
184
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
#[cfg(feature = "serde")]
|
|
187
|
+
fn run() {
|
|
188
|
+
println!("\n╔═══════════════════════════════════════════════════════╗");
|
|
189
|
+
println!("║ qtty-core: Serde and DB Integration Examples ║");
|
|
190
|
+
println!("╚═══════════════════════════════════════════════════════╝\n");
|
|
191
|
+
|
|
192
|
+
example_serde();
|
|
193
|
+
example_serde_with_unit();
|
|
194
|
+
|
|
195
|
+
#[cfg(feature = "tiberius")]
|
|
196
|
+
example_tiberius_concept();
|
|
197
|
+
|
|
198
|
+
example_migration_comparison();
|
|
199
|
+
|
|
200
|
+
println!("═══════════════════════════════════════════════════════");
|
|
201
|
+
println!("All examples completed successfully!");
|
|
202
|
+
println!("═══════════════════════════════════════════════════════\n");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
fn main() {
|
|
206
|
+
#[cfg(feature = "serde")]
|
|
207
|
+
{
|
|
208
|
+
run();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#[cfg(not(feature = "serde"))]
|
|
212
|
+
{
|
|
213
|
+
eprintln!("This example requires `--features serde`.");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
//! Dimension types and traits.
|
|
2
|
+
//!
|
|
3
|
+
//! Dimensions are modelled as a single generic struct [`Dim`] parameterised by eight
|
|
4
|
+
//! [`typenum`] signed integers representing the exponents of the fundamental physical
|
|
5
|
+
//! dimensions. Multiplying two dimensions adds exponents; dividing subtracts them.
|
|
6
|
+
//! Because typenum arithmetic resolves at compile time, compound types like `Length * Length`
|
|
7
|
+
//! automatically become `Area` (exponent 2), and `Area / Length` collapses back to `Length`
|
|
8
|
+
//! (exponent 1) — all verified by the type checker.
|
|
9
|
+
//!
|
|
10
|
+
//! # Layout
|
|
11
|
+
//!
|
|
12
|
+
//! The eight exponent slots are:
|
|
13
|
+
//!
|
|
14
|
+
//! | Position | Base quantity | SI symbol |
|
|
15
|
+
//! |----------|--------------------------|-----------|
|
|
16
|
+
//! | `L` | Length | m |
|
|
17
|
+
//! | `T` | Time | s |
|
|
18
|
+
//! | `M` | Mass | kg |
|
|
19
|
+
//! | `Th` | Thermodynamic temperature| K |
|
|
20
|
+
//! | `I` | Electric current | A |
|
|
21
|
+
//! | `N` | Amount of substance | mol |
|
|
22
|
+
//! | `J` | Luminous intensity | cd |
|
|
23
|
+
//! | `A` | Plane angle (auxiliary) | rad/deg |
|
|
24
|
+
|
|
25
|
+
use core::marker::PhantomData;
|
|
26
|
+
use core::ops::{Add, Sub};
|
|
27
|
+
use typenum::Integer;
|
|
28
|
+
|
|
29
|
+
/// Marker trait for **dimensions**.
|
|
30
|
+
///
|
|
31
|
+
/// Implemented automatically for every [`Dim<L,T,M,Th,I,N,J,A>`] whose type
|
|
32
|
+
/// parameters satisfy the required bounds.
|
|
33
|
+
pub trait Dimension: 'static {}
|
|
34
|
+
|
|
35
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
// Core dimension struct
|
|
37
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/// A physical dimension encoded as eight typenum integer exponents.
|
|
40
|
+
///
|
|
41
|
+
/// This is a zero-sized type: no runtime cost.
|
|
42
|
+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
43
|
+
pub struct Dim<L, T, M, Th, I, N, J, A>(
|
|
44
|
+
PhantomData<L>,
|
|
45
|
+
PhantomData<T>,
|
|
46
|
+
PhantomData<M>,
|
|
47
|
+
PhantomData<Th>,
|
|
48
|
+
PhantomData<I>,
|
|
49
|
+
PhantomData<N>,
|
|
50
|
+
PhantomData<J>,
|
|
51
|
+
PhantomData<A>,
|
|
52
|
+
)
|
|
53
|
+
where
|
|
54
|
+
L: Integer,
|
|
55
|
+
T: Integer,
|
|
56
|
+
M: Integer,
|
|
57
|
+
Th: Integer,
|
|
58
|
+
I: Integer,
|
|
59
|
+
N: Integer,
|
|
60
|
+
J: Integer,
|
|
61
|
+
A: Integer;
|
|
62
|
+
|
|
63
|
+
impl<L, T, M, Th, I, N, J, A> Dimension for Dim<L, T, M, Th, I, N, J, A>
|
|
64
|
+
where
|
|
65
|
+
L: Integer + 'static,
|
|
66
|
+
T: Integer + 'static,
|
|
67
|
+
M: Integer + 'static,
|
|
68
|
+
Th: Integer + 'static,
|
|
69
|
+
I: Integer + 'static,
|
|
70
|
+
N: Integer + 'static,
|
|
71
|
+
J: Integer + 'static,
|
|
72
|
+
A: Integer + 'static,
|
|
73
|
+
{
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
77
|
+
// Dimension multiplication (adds exponents)
|
|
78
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
/// Trait for multiplying two dimensions (adds exponents).
|
|
81
|
+
pub trait DimMul<Rhs: Dimension>: Dimension {
|
|
82
|
+
/// The resulting dimension.
|
|
83
|
+
type Output: Dimension;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
impl<L1, T1, M1, Th1, I1, N1, J1, A1, L2, T2, M2, Th2, I2, N2, J2, A2>
|
|
87
|
+
DimMul<Dim<L2, T2, M2, Th2, I2, N2, J2, A2>> for Dim<L1, T1, M1, Th1, I1, N1, J1, A1>
|
|
88
|
+
where
|
|
89
|
+
L1: Integer + Add<L2> + 'static,
|
|
90
|
+
T1: Integer + Add<T2> + 'static,
|
|
91
|
+
M1: Integer + Add<M2> + 'static,
|
|
92
|
+
Th1: Integer + Add<Th2> + 'static,
|
|
93
|
+
I1: Integer + Add<I2> + 'static,
|
|
94
|
+
N1: Integer + Add<N2> + 'static,
|
|
95
|
+
J1: Integer + Add<J2> + 'static,
|
|
96
|
+
A1: Integer + Add<A2> + 'static,
|
|
97
|
+
L2: Integer + 'static,
|
|
98
|
+
T2: Integer + 'static,
|
|
99
|
+
M2: Integer + 'static,
|
|
100
|
+
Th2: Integer + 'static,
|
|
101
|
+
I2: Integer + 'static,
|
|
102
|
+
N2: Integer + 'static,
|
|
103
|
+
J2: Integer + 'static,
|
|
104
|
+
A2: Integer + 'static,
|
|
105
|
+
<L1 as Add<L2>>::Output: Integer + 'static,
|
|
106
|
+
<T1 as Add<T2>>::Output: Integer + 'static,
|
|
107
|
+
<M1 as Add<M2>>::Output: Integer + 'static,
|
|
108
|
+
<Th1 as Add<Th2>>::Output: Integer + 'static,
|
|
109
|
+
<I1 as Add<I2>>::Output: Integer + 'static,
|
|
110
|
+
<N1 as Add<N2>>::Output: Integer + 'static,
|
|
111
|
+
<J1 as Add<J2>>::Output: Integer + 'static,
|
|
112
|
+
<A1 as Add<A2>>::Output: Integer + 'static,
|
|
113
|
+
{
|
|
114
|
+
type Output = Dim<
|
|
115
|
+
<L1 as Add<L2>>::Output,
|
|
116
|
+
<T1 as Add<T2>>::Output,
|
|
117
|
+
<M1 as Add<M2>>::Output,
|
|
118
|
+
<Th1 as Add<Th2>>::Output,
|
|
119
|
+
<I1 as Add<I2>>::Output,
|
|
120
|
+
<N1 as Add<N2>>::Output,
|
|
121
|
+
<J1 as Add<J2>>::Output,
|
|
122
|
+
<A1 as Add<A2>>::Output,
|
|
123
|
+
>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
127
|
+
// Dimension division (subtracts exponents)
|
|
128
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
/// Trait for dividing two dimensions (subtracts exponents).
|
|
131
|
+
pub trait DimDiv<Rhs: Dimension>: Dimension {
|
|
132
|
+
/// The resulting dimension.
|
|
133
|
+
type Output: Dimension;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
impl<L1, T1, M1, Th1, I1, N1, J1, A1, L2, T2, M2, Th2, I2, N2, J2, A2>
|
|
137
|
+
DimDiv<Dim<L2, T2, M2, Th2, I2, N2, J2, A2>> for Dim<L1, T1, M1, Th1, I1, N1, J1, A1>
|
|
138
|
+
where
|
|
139
|
+
L1: Integer + Sub<L2> + 'static,
|
|
140
|
+
T1: Integer + Sub<T2> + 'static,
|
|
141
|
+
M1: Integer + Sub<M2> + 'static,
|
|
142
|
+
Th1: Integer + Sub<Th2> + 'static,
|
|
143
|
+
I1: Integer + Sub<I2> + 'static,
|
|
144
|
+
N1: Integer + Sub<N2> + 'static,
|
|
145
|
+
J1: Integer + Sub<J2> + 'static,
|
|
146
|
+
A1: Integer + Sub<A2> + 'static,
|
|
147
|
+
L2: Integer + 'static,
|
|
148
|
+
T2: Integer + 'static,
|
|
149
|
+
M2: Integer + 'static,
|
|
150
|
+
Th2: Integer + 'static,
|
|
151
|
+
I2: Integer + 'static,
|
|
152
|
+
N2: Integer + 'static,
|
|
153
|
+
J2: Integer + 'static,
|
|
154
|
+
A2: Integer + 'static,
|
|
155
|
+
<L1 as Sub<L2>>::Output: Integer + 'static,
|
|
156
|
+
<T1 as Sub<T2>>::Output: Integer + 'static,
|
|
157
|
+
<M1 as Sub<M2>>::Output: Integer + 'static,
|
|
158
|
+
<Th1 as Sub<Th2>>::Output: Integer + 'static,
|
|
159
|
+
<I1 as Sub<I2>>::Output: Integer + 'static,
|
|
160
|
+
<N1 as Sub<N2>>::Output: Integer + 'static,
|
|
161
|
+
<J1 as Sub<J2>>::Output: Integer + 'static,
|
|
162
|
+
<A1 as Sub<A2>>::Output: Integer + 'static,
|
|
163
|
+
{
|
|
164
|
+
type Output = Dim<
|
|
165
|
+
<L1 as Sub<L2>>::Output,
|
|
166
|
+
<T1 as Sub<T2>>::Output,
|
|
167
|
+
<M1 as Sub<M2>>::Output,
|
|
168
|
+
<Th1 as Sub<Th2>>::Output,
|
|
169
|
+
<I1 as Sub<I2>>::Output,
|
|
170
|
+
<N1 as Sub<N2>>::Output,
|
|
171
|
+
<J1 as Sub<J2>>::Output,
|
|
172
|
+
<A1 as Sub<A2>>::Output,
|
|
173
|
+
>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
177
|
+
// Base dimension aliases
|
|
178
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
use typenum::{N1, N2, N3, P1, P2, P3, Z0};
|
|
181
|
+
|
|
182
|
+
/// Dimensionless (all exponents zero).
|
|
183
|
+
pub type Dimensionless = Dim<Z0, Z0, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
184
|
+
|
|
185
|
+
/// Length (L¹).
|
|
186
|
+
pub type Length = Dim<P1, Z0, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
187
|
+
|
|
188
|
+
/// Time (T¹).
|
|
189
|
+
pub type Time = Dim<Z0, P1, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
190
|
+
|
|
191
|
+
/// Mass (M¹).
|
|
192
|
+
pub type Mass = Dim<Z0, Z0, P1, Z0, Z0, Z0, Z0, Z0>;
|
|
193
|
+
|
|
194
|
+
/// Thermodynamic temperature (Θ¹).
|
|
195
|
+
pub type Temperature = Dim<Z0, Z0, Z0, P1, Z0, Z0, Z0, Z0>;
|
|
196
|
+
|
|
197
|
+
/// Electric current (I¹).
|
|
198
|
+
pub type Current = Dim<Z0, Z0, Z0, Z0, P1, Z0, Z0, Z0>;
|
|
199
|
+
|
|
200
|
+
/// Amount of substance (N¹).
|
|
201
|
+
pub type AmountOfSubstance = Dim<Z0, Z0, Z0, Z0, Z0, P1, Z0, Z0>;
|
|
202
|
+
|
|
203
|
+
/// Luminous intensity (J¹).
|
|
204
|
+
pub type LuminousIntensity = Dim<Z0, Z0, Z0, Z0, Z0, Z0, P1, Z0>;
|
|
205
|
+
|
|
206
|
+
/// Plane angle (A¹) — treated as an independent dimension for type safety.
|
|
207
|
+
pub type Angular = Dim<Z0, Z0, Z0, Z0, Z0, Z0, Z0, P1>;
|
|
208
|
+
|
|
209
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
210
|
+
// Derived dimension aliases
|
|
211
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
212
|
+
|
|
213
|
+
/// Area (L²).
|
|
214
|
+
pub type Area = Dim<P2, Z0, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
215
|
+
|
|
216
|
+
/// Volume (L³).
|
|
217
|
+
pub type Volume = Dim<P3, Z0, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
218
|
+
|
|
219
|
+
/// Velocity (L¹ · T⁻¹).
|
|
220
|
+
pub type VelocityDim = Dim<P1, N1, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
221
|
+
|
|
222
|
+
/// Acceleration (L¹ · T⁻²).
|
|
223
|
+
pub type Acceleration = Dim<P1, N2, Z0, Z0, Z0, Z0, Z0, Z0>;
|
|
224
|
+
|
|
225
|
+
/// Force (M¹ · L¹ · T⁻²).
|
|
226
|
+
pub type Force = Dim<P1, N2, P1, Z0, Z0, Z0, Z0, Z0>;
|
|
227
|
+
|
|
228
|
+
/// Energy (M¹ · L² · T⁻²).
|
|
229
|
+
pub type Energy = Dim<P2, N2, P1, Z0, Z0, Z0, Z0, Z0>;
|
|
230
|
+
|
|
231
|
+
/// Power (M¹ · L² · T⁻³).
|
|
232
|
+
pub type Power = Dim<P2, N3, P1, Z0, Z0, Z0, Z0, Z0>;
|
|
233
|
+
|
|
234
|
+
/// Frequency — angular per time (A¹ · T⁻¹).
|
|
235
|
+
pub type FrequencyDim = Dim<Z0, N1, Z0, Z0, Z0, Z0, Z0, P1>;
|
|
236
|
+
|
|
237
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
238
|
+
// Legacy compatibility alias
|
|
239
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
240
|
+
|
|
241
|
+
/// Backward-compatible alias: `DivDim<N, D>` resolves to `<N as DimDiv<D>>::Output`.
|
|
242
|
+
///
|
|
243
|
+
/// This preserves source compatibility for code that previously used `DivDim<Length, Time>`.
|
|
244
|
+
/// It now resolves to the same concrete type as the `Velocity` alias, since typenum
|
|
245
|
+
/// arithmetic produces the identical `Dim<P1, N1, …>`.
|
|
246
|
+
pub type DivDim<N, D> = <N as DimDiv<D>>::Output;
|
|
247
|
+
|
|
248
|
+
/// Backward-compatible alias: `MulDim<A, B>` resolves to `<A as DimMul<B>>::Output`.
|
|
249
|
+
pub type MulDim<A, B> = <A as DimMul<B>>::Output;
|