use crate::{Quantity, Unit};
use qtty_derive::Unit;
pub use crate::dimension::Force;
pub trait ForceUnit: Unit<Dim = Force> {}
impl<T: Unit<Dim = Force>> ForceUnit for T {}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "N", dimension = Force, ratio = 1.0)]
pub struct Newton;
pub type N = Newton;
pub type Newtons = Quantity<N>;
pub const NEWTON: Newtons = Newtons::new(1.0);
macro_rules! si_newton {
($name:ident, $sym:literal, $ratio:expr, $alias:ident, $qty:ident, $one:ident) => {
#[doc = concat!("SI-prefixed newton unit (", stringify!($ratio), " N).")]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = $sym, dimension = Force, ratio = $ratio)]
pub struct $name;
#[doc = concat!("Type alias shorthand for [`", stringify!($name), "`].")]
pub type $alias = $name;
#[doc = concat!("A quantity measured in ", stringify!($name), "s.")]
pub type $qty = Quantity<$alias>;
#[doc = concat!("One ", stringify!($name), ".")]
pub const $one: $qty = $qty::new(1.0);
};
}
si_newton!(Micronewton, "µN", 1e-6, Un, Micronewtons, MICRONEWTON);
si_newton!(Millinewton, "mN", 1e-3, Mn, Millinewtons, MILLINEWTON);
si_newton!(Kilonewton, "kN", 1e3, Kn, Kilonewtons, KILONEWTON);
si_newton!(Meganewton, "MN", 1e6, MN, Meganewtons, MEGANEWTON);
si_newton!(Giganewton, "GN", 1e9, GN, Giganewtons, GIGANEWTON);
#[cfg(feature = "fundamental-physics")]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "dyn", dimension = Force, ratio = 1e-5)]
pub struct Dyne;
#[cfg(feature = "fundamental-physics")]
pub type Dynes = Quantity<Dyne>;
#[cfg(feature = "customary")]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "lbf", dimension = Force, ratio = 4.448_221_615_260_5)]
pub struct PoundForce;
#[cfg(feature = "customary")]
pub type PoundsForce = Quantity<PoundForce>;
#[macro_export]
#[doc(hidden)]
macro_rules! force_units {
($cb:path) => {
$cb!(
Newton,
Micronewton,
Millinewton,
Kilonewton,
Meganewton,
Giganewton
);
};
}
force_units!(crate::impl_unit_from_conversions);
#[cfg(feature = "cross-unit-ops")]
force_units!(crate::impl_unit_cross_unit_ops);
#[cfg(all(feature = "customary", feature = "fundamental-physics"))]
crate::__impl_from_each_extra_to_bases!(
{PoundForce}
Dyne
);
#[cfg(all(
feature = "customary",
feature = "fundamental-physics",
feature = "cross-unit-ops"
))]
crate::__impl_cross_ops_each_extra_to_bases!(
{PoundForce}
Dyne
);
#[cfg(test)]
force_units!(crate::assert_units_are_builtin);
#[cfg(feature = "fundamental-physics")]
#[macro_export]
#[doc(hidden)]
macro_rules! force_fundamental_physics_units {
($cb:path) => {
$cb!(Dyne);
};
}
#[cfg(feature = "customary")]
#[macro_export]
#[doc(hidden)]
macro_rules! force_customary_units {
($cb:path) => {
$cb!(PoundForce);
};
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
use approx::assert_abs_diff_eq;
#[test]
fn kilonewton_to_newton() {
let kn = Kilonewtons::new(1.0);
let n: Newtons = kn.to();
assert_abs_diff_eq!(n.value(), 1_000.0, epsilon = 1e-12);
}
#[test]
fn newton_to_millinewton() {
let n = Newtons::new(1.0);
let mn: Millinewtons = n.to();
assert_abs_diff_eq!(mn.value(), 1_000.0, epsilon = 1e-12);
}
#[test]
#[cfg(feature = "fundamental-physics")]
fn newton_to_dyne() {
let n = Newtons::new(1.0);
let d: Dynes = n.to();
assert_abs_diff_eq!(d.value(), 1e5, epsilon = 1e-7);
}
#[test]
#[cfg(feature = "customary")]
fn newton_to_lbf() {
let n = Newtons::new(4.448_221_615_260_5);
let lbf: PoundsForce = n.to();
assert_abs_diff_eq!(lbf.value(), 1.0, epsilon = 1e-9);
}
}