#![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(
feature = "cargo-clippy",
allow(clippy::deprecated_cfg_attr, clippy::excessive_precision, clippy::inline_always)
)]
#![cfg_attr(
all(feature = "cargo-clippy", test),
allow(clippy::op_ref, clippy::clone_on_copy, clippy::float_cmp)
)]
#[cfg_attr(rustfmt, 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 = "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 = "serde")]
pub extern crate serde;
#[doc(hidden)]
pub extern crate typenum;
#[cfg(all(test, any(feature = "f32", feature = "f64")))]
#[macro_use]
extern crate approx;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(all(test, feature = "serde"))]
extern crate serde_json;
#[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::*;
}
}
#[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 use num_rational::Rational;
#[cfg(feature = "bigint-support")]
pub use num_rational::BigRational;
#[cfg(any(feature = "rational-support", feature = "bigint-support"))]
pub mod rational {
pub use num_rational::*;
}
}
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;
#[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>;
#[inline(always)]
fn coefficient() -> Self::T {
<Self::T as num::One>::one()
}
#[inline(always)]
#[allow(unused_variables)]
fn constant(op: ConstantOp) -> Self::T {
<Self::T as num::Zero>::zero()
}
#[inline(always)]
fn into_conversion(&self) -> Self::T
where
Self: Sized,
{
Self::coefficient()
}
}
pub trait ConversionFactor<V>:
lib::ops::Add<Self, Output = Self>
+ lib::ops::Sub<Self, Output = Self>
+ lib::ops::Mul<Self, Output = Self>
+ lib::ops::Div<Self, Output = Self>
+ num::Zero
+ num::One
{
fn powi(self, e: i32) -> Self;
fn value(self) -> V;
}
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 ::Conversion<V> for V {
type T = V;
#[inline(always)]
fn constant(op: ::ConstantOp) -> Self::T {
match op {
::ConstantOp::Add => -<Self::T as ::num::Zero>::zero(),
::ConstantOp::Sub => <Self::T as ::num::Zero>::zero(),
}
}
#[inline(always)]
fn into_conversion(&self) -> Self::T {
*self
}
}
impl ::ConversionFactor<V> for V {
#[inline(always)]
fn powi(self, e: i32) -> Self {
<V as ::num::Float>::powi(self, e)
}
#[inline(always)]
fn value(self) -> V {
self
}
}
}
storage_types! {
types: PrimInt;
impl ::Conversion<V> for V {
type T = ::num::rational::Ratio<V>;
#[inline(always)]
fn into_conversion(&self) -> Self::T {
(*self).into()
}
}
impl ::ConversionFactor<V> for ::num::rational::Ratio<V> {
#[inline(always)]
fn powi(self, e: i32) -> Self {
self.pow(e)
}
#[inline(always)]
fn value(self) -> V {
self.to_integer()
}
}
}
storage_types! {
types: BigInt, BigUint;
impl ::Conversion<V> for V {
type T = ::num::rational::Ratio<V>;
#[inline(always)]
fn into_conversion(&self) -> Self::T {
self.clone().into()
}
}
impl ::ConversionFactor<V> for ::num::rational::Ratio<V> {
#[inline(always)]
fn powi(self, e: i32) -> Self {
match e.cmp(&0) {
::lib::cmp::Ordering::Equal => <Self as ::num::One>::one(),
::lib::cmp::Ordering::Less => ::num::pow::pow(self.recip(), (-e) as usize),
::lib::cmp::Ordering::Greater => ::num::pow::pow(self, e as usize),
}
}
#[inline(always)]
fn value(self) -> V {
self.to_integer()
}
}
}
storage_types! {
types: Rational, Rational32, Rational64;
impl ::Conversion<V> for V {
type T = V;
#[inline(always)]
fn into_conversion(&self) -> Self::T {
*self
}
}
impl ::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 ::Conversion<V> for V {
type T = V;
#[inline(always)]
fn into_conversion(&self) -> Self::T {
self.clone()
}
}
impl ::ConversionFactor<V> for V {
#[inline(always)]
fn powi(self, e: i32) -> Self {
match e.cmp(&0) {
::lib::cmp::Ordering::Equal => <Self as ::num::One>::one(),
::lib::cmp::Ordering::Less => ::num::pow::pow(self.recip(), (-e) as usize),
::lib::cmp::Ordering::Greater => ::num::pow::pow(self, e as usize),
}
}
#[inline(always)]
fn value(self) -> V {
self
}
}
}
pub mod fmt {
#[derive(Clone, Copy, Debug)]
pub enum DisplayStyle {
Abbreviation,
Description,
}
}
pub mod str {
#[allow(missing_copy_implementations)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ParseQuantityError {
NoSeparator,
ValueParseError,
UnknownUnit,
}
}