#![cfg_attr(all(feature = "si", feature = "f32"), doc = " ```rust")]
#![cfg_attr(not(all(feature = "si", feature = "f32")), doc = " ```rust,ignore")]
#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(unsafe_code)]
#![warn(
bare_trait_objects,
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_import_braces,
unused_qualifications,
unused_results
)]
#![cfg_attr(
clippy,
warn(clippy::must_use_candidate, clippy::return_self_not_must_use,),
allow(clippy::deprecated_cfg_attr, clippy::excessive_precision, clippy::inline_always,)
)]
#![cfg_attr(all(clippy, test), allow(clippy::op_ref, clippy::clone_on_copy, clippy::float_cmp))]
#[rustfmt::skip]
#[cfg(not(any(
feature = "usize", feature = "u8", feature = "u16", feature = "u32", feature = "u64",
feature = "u128",
feature = "isize", feature = "i8", feature = "i16", feature = "i32", feature = "i64",
feature = "i128",
feature = "bigint", feature = "biguint",
feature = "rational", feature = "rational32", feature = "rational64", feature = "bigrational",
feature = "complex32", feature = "complex64",
feature = "f32", feature = "f64", )))]
compile_error!("A least one underlying storage type must be enabled. See the features section of \
uom documentation for available underlying storage type options.");
#[doc(hidden)]
pub extern crate num_traits;
#[doc(hidden)]
#[cfg(feature = "bigint-support")]
pub extern crate num_bigint;
#[doc(hidden)]
#[cfg(any(feature = "rational-support", feature = "bigint-support"))]
pub extern crate num_rational;
#[doc(hidden)]
#[cfg(feature = "complex-support")]
pub extern crate num_complex;
#[doc(hidden)]
#[cfg(feature = "serde")]
pub extern crate serde_core as serde;
#[doc(hidden)]
pub extern crate typenum;
#[cfg(all(
test,
any(feature = "f32", feature = "f64", feature = "complex32", feature = "complex64")
))]
#[macro_use]
extern crate approx;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(test)]
#[macro_use]
extern crate static_assertions;
#[doc(hidden)]
pub mod lib {
#[cfg(not(feature = "std"))]
pub use core::*;
#[cfg(feature = "std")]
pub use std::*;
pub mod ops {
#[cfg(not(feature = "std"))]
pub use core::ops::*;
#[cfg(feature = "std")]
pub use std::ops::*;
pub use typenum::type_operators::*;
}
#[cfg(not(feature = "std"))]
pub mod panic {
pub trait RefUnwindSafe {}
pub trait UnwindSafe {}
}
}
#[doc(hidden)]
pub mod num {
#[cfg(feature = "std")]
pub use num_traits::float::Float;
#[cfg(not(feature = "std"))]
pub use num_traits::float::FloatCore as Float;
pub use num_traits::{pow, FromPrimitive, Num, One, Saturating, Signed, ToPrimitive, Zero};
#[cfg(feature = "bigint-support")]
pub use num_bigint::{BigInt, BigUint};
#[cfg(feature = "rational-support")]
pub type Rational = num_rational::Ratio<isize>;
#[cfg(feature = "bigint-support")]
pub use num_rational::BigRational;
#[cfg(any(feature = "rational-support", feature = "bigint-support"))]
pub mod rational {
pub use num_rational::*;
}
#[cfg(feature = "complex-support")]
pub mod complex {
pub use num_complex::*;
}
}
pub mod marker {
pub trait Add {}
pub trait AddAssign {}
pub trait Sub {}
pub trait SubAssign {}
pub trait Mul {}
pub trait MulAssign {}
pub trait Div {}
pub trait DivAssign {}
pub trait Neg {}
pub trait Rem {}
pub trait RemAssign {}
pub trait Saturating {}
}
#[macro_use]
mod features;
#[macro_use]
mod storage_types;
#[macro_use]
mod system;
#[macro_use]
mod quantity;
#[macro_use]
mod unit;
#[cfg(feature = "si")]
#[macro_use]
pub mod si;
#[cfg(test)]
mod tests;
#[derive(Clone, Copy, Debug)]
pub enum ConstantOp {
Add,
Sub,
}
pub trait Conversion<V> {
type T: ConversionFactor<V>;
#[must_use = "method returns a new number and does not mutate the original value"]
#[inline(always)]
fn coefficient() -> Self::T {
<Self::T as num::One>::one()
}
#[must_use = "method returns a new number and does not mutate the original value"]
#[inline(always)]
#[allow(unused_variables)]
fn constant(op: ConstantOp) -> Self::T {
<Self::T as num::Zero>::zero()
}
#[must_use = "method returns a new number and does not mutate the original value"]
#[inline(always)]
fn conversion(&self) -> Self::T
where
Self: Sized,
{
Self::coefficient()
}
}
#[allow(unused_qualifications)] pub trait ConversionFactor<V>:
lib::cmp::PartialOrd
+ lib::ops::Add<Self, Output = Self>
+ lib::ops::Sub<Self, Output = Self>
+ lib::ops::Mul<Self, Output = Self>
+ lib::ops::Div<Self, Output = Self>
+ crate::num::Zero
+ crate::num::One
{
#[must_use = "method returns a new number and does not mutate the original value"]
fn powi(self, e: i32) -> Self;
#[must_use = "method returns a new number and does not mutate the original value"]
fn value(self) -> V;
}
#[cfg_attr(all(feature = "si", feature = "f32"), doc = " ```rust")]
#[cfg_attr(not(all(feature = "si", feature = "f32")), doc = " ```rust,ignore")]
pub trait ConstZero {
const ZERO: Self;
}
pub trait Kind:
marker::Add
+ marker::AddAssign
+ marker::Sub
+ marker::SubAssign
+ marker::Mul
+ marker::MulAssign
+ marker::Div
+ marker::DivAssign
+ marker::Rem
+ marker::RemAssign
+ marker::Neg
+ marker::Saturating
{
}
storage_types! {
types: Float;
impl crate::Conversion<Self> for V {
type T = Self;
#[inline(always)]
fn constant(op: crate::ConstantOp) -> Self::T {
match op {
crate::ConstantOp::Add => -<Self::T as crate::num::Zero>::zero(),
crate::ConstantOp::Sub => <Self::T as crate::num::Zero>::zero(),
}
}
#[inline(always)]
fn conversion(&self) -> Self::T {
*self
}
}
impl crate::ConversionFactor<Self> for V {
#[inline(always)]
fn powi(self, e: i32) -> Self {
<Self as crate::num::Float>::powi(self, e)
}
#[inline(always)]
fn value(self) -> Self {
self
}
}
impl crate::ConstZero for V {
const ZERO: Self = 0.0;
}
}
storage_types! {
types: PrimInt;
impl crate::Conversion<V> for V {
type T = crate::num::rational::Ratio<V>;
#[inline(always)]
fn conversion(&self) -> Self::T {
(*self).into()
}
}
impl crate::ConversionFactor<V> for crate::num::rational::Ratio<V> {
#[inline(always)]
fn powi(self, e: i32) -> Self {
self.pow(e)
}
#[inline(always)]
fn value(self) -> V {
self.to_integer()
}
}
impl crate::ConstZero for V {
const ZERO: Self = 0;
}
}
storage_types! {
types: BigInt, BigUint;
impl crate::Conversion<V> for V {
type T = crate::num::rational::Ratio<V>;
#[inline(always)]
fn conversion(&self) -> Self::T {
self.clone().into()
}
}
impl crate::ConversionFactor<V> for crate::num::rational::Ratio<V> {
#[inline(always)]
fn powi(self, e: i32) -> Self {
match e.cmp(&0) {
crate::lib::cmp::Ordering::Equal => <Self as crate::num::One>::one(),
crate::lib::cmp::Ordering::Less => crate::num::pow::pow(self.recip(), (-e) as usize),
crate::lib::cmp::Ordering::Greater => crate::num::pow::pow(self, e as usize),
}
}
#[inline(always)]
fn value(self) -> V {
self.to_integer()
}
}
}
storage_types! {
types: Rational, Rational32, Rational64;
impl crate::Conversion<V> for V {
type T = V;
#[inline(always)]
fn conversion(&self) -> Self::T {
*self
}
}
impl crate::ConversionFactor<V> for V {
#[inline(always)]
fn powi(self, e: i32) -> Self {
self.pow(e)
}
#[inline(always)]
fn value(self) -> V {
self
}
}
}
storage_types! {
types: BigRational;
impl crate::Conversion<V> for V {
type T = V;
#[inline(always)]
fn conversion(&self) -> Self::T {
self.clone()
}
}
impl crate::ConversionFactor<V> for V {
#[inline(always)]
fn powi(self, e: i32) -> Self {
match e.cmp(&0) {
crate::lib::cmp::Ordering::Equal => <Self as crate::num::One>::one(),
crate::lib::cmp::Ordering::Less => crate::num::pow::pow(self.recip(), (-e) as usize),
crate::lib::cmp::Ordering::Greater => crate::num::pow::pow(self, e as usize),
}
}
#[inline(always)]
fn value(self) -> V {
self
}
}
}
storage_types! {
types: Complex;
impl crate::Conversion<V> for V {
type T = VV;
#[inline(always)]
fn constant(op: crate::ConstantOp) -> Self::T {
match op {
crate::ConstantOp::Add => -<Self::T as crate::num::Zero>::zero(),
crate::ConstantOp::Sub => <Self::T as crate::num::Zero>::zero(),
}
}
#[inline(always)]
fn conversion(&self) -> Self::T {
self.norm()
}
}
impl crate::ConversionFactor<V> for VV {
#[inline(always)]
fn powi(self, e: i32) -> Self {
self.powi(e)
}
#[inline(always)]
fn value(self) -> V {
V::new(self, 0.0)
}
}
}
pub mod fmt {
#[derive(Clone, Copy, Debug)]
pub enum DisplayStyle {
Abbreviation,
Description,
}
}
pub mod str {
use crate::lib::fmt::{self, Display, Formatter};
#[allow(missing_copy_implementations)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ParseQuantityError {
NoSeparator,
ValueParseError,
UnknownUnit,
}
impl Display for ParseQuantityError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
use ParseQuantityError::{NoSeparator, UnknownUnit, ValueParseError};
match *self {
NoSeparator => write!(f, "no space between quantity and units"),
ValueParseError => write!(f, "error parsing unit quantity"),
UnknownUnit => write!(f, "unrecognized unit of measure"),
}
}
}
#[cfg(feature = "std")]
impl crate::lib::error::Error for ParseQuantityError {}
}