From 3ef45da755694ed56ed6e7d6c3114f19fd1f29d0 Mon Sep 17 00:00:00 2001 From: Paho Lurie-Gregg Date: Sun, 24 Jun 2018 17:03:47 -0700 Subject: [PATCH] Run rustfmt and disable clippy in Travis (#39) Builds that fail for issues unrelated to pull requests are useless. This PR gets the build passing again and hopefully it will stay that way. One caveat is that clippy is now disabled in Travis builds. It is giving me trouble running locally at the moment; I think the best approach is to keep it disabled until it is incorporated into rustup. --- .travis.yml | 33 ++++--- Cargo.toml | 12 +-- README.md | 2 +- examples/readme-example.rs | 10 +- src/array.rs | 27 +++-- src/build/cgs.rs | 8 +- src/build/fps.rs | 6 +- src/build/mks.rs | 11 +-- src/build/mod.rs | 198 +++++++++++++++++++++++++++---------- src/build/si.rs | 24 +++-- src/build/ucum.rs | 7 +- src/conversion.rs | 159 +++++++++++++++++------------ src/fmt.rs | 1 - src/lib.rs | 47 +++++---- src/make_units.rs | 89 +++++++++++++---- src/traits.rs | 30 ++---- tests/consts.rs | 1 - tests/derived.rs | 2 +- tests/tests.rs | 93 +++++++++-------- 19 files changed, 476 insertions(+), 284 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40716b0c..4f0b682a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,32 +1,33 @@ language: rust +cache: cargo sudo: false rust: - stable - beta - - nightly -cache: cargo notifications: email: recipients: paho@paholg.com -# fixme: re-enable rustfmt when it works -before_script: - - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH - - export TRAVIS_CARGO_NIGHTLY_FEATURE="" - # - test -x $HOME/.cargo/bin/rustfmt || cargo install rustfmt # Only install rustfmt if it's not there +matrix: + include: + - rust: nightly + before_script: + - rustup component add rustfmt-preview + script: | + cargo fmt --version && + cargo fmt --all -- --check && + cargo test --all-features -script: - # PATH=$PATH:~/.cargo/bin cargo fmt -- --write-mode=diff && - - | - travis-cargo --only stable test && - travis-cargo --only beta test && - travis-cargo --only nightly test -- --features "test" && - travis-cargo --only stable doc +script: | + cargo build && + cargo test --features "approx quickcheck serde serde_test" && + cargo doc after_success: - - travis-cargo doc-upload - - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && cargo publish --token ${CRATESIO_TOKEN} + - test $TRAVIS_PULL_REQUEST == "false" && + test $TRAVIS_BRANCH == "master" && + cargo publish --token ${CRATESIO_TOKEN} env: global: diff --git a/Cargo.toml b/Cargo.toml index 5ed21b78..843314d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "dimensioned" version = "0.6.0" authors = ["Paho Lurie-Gregg "] - documentation = "http://paholg.com/dimensioned" + documentation = "https://docs.rs/dimensioned" repository = "https://github.com/paholg/dimensioned" readme = "README.md" license = "MIT/Apache-2.0" @@ -24,14 +24,12 @@ Never again should you need to specify units in a comment!""" default = [] oibit = [] spec = [] - test = ["clippy", "quickcheck", "quickcheck_macros", "approx", "oibit", "spec", "serde", "serde_test"] + test = ["quickcheck", "approx", "oibit", "spec", "serde", "serde_test"] [dependencies] - typenum = "1.6.0" + approx = { version = "0.1.1", optional = true, features = [] } generic-array = "0.5.1" - clippy = { version = "0.0.135", optional = true } - quickcheck = { version = "0.4.1", optional = true } - quickcheck_macros = { version = "0.4.1", optional = true } - approx = { version = "0.1.1", optional = true, features = ["no_std"] } + quickcheck = { version = "0.6.2", optional = true } serde = { version = "1.0.0", optional = true } serde_test = { version = "1.0.0", optional = true } + typenum = "1.6.0" diff --git a/README.md b/README.md index 31b21067..95508e6b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![crates.io](https://img.shields.io/crates/v/dimensioned.svg)](https://crates.io/crates/dimensioned) [![Build Status](https://travis-ci.org/paholg/dimensioned.svg?branch=master)](https://travis-ci.org/paholg/dimensioned) -[Documentation](http://paholg.com/dimensioned/) +[Documentation](https://docs.rs/dimensioned/) Dimensioned ===== diff --git a/examples/readme-example.rs b/examples/readme-example.rs index b58e31f6..8474ba31 100644 --- a/examples/readme-example.rs +++ b/examples/readme-example.rs @@ -1,19 +1,21 @@ extern crate dimensioned as dim; -use dim::{si, cgs}; +use dim::{cgs, si}; // Calculates speed given a distance and time. Only works for SI units. fn speed(dist: si::Meter, time: si::Second) -> si::MeterPerSecond { dist / time } -use std::ops::Div; use dim::dimensions::{Length, Time}; use dim::typenum::Quot; +use std::ops::Div; // Calculates speed as before, but now we can use *any* unit system. fn generic_speed(dist: L, time: T) -> Quot - where L: Length + Div, T: Time, +where + L: Length + Div, + T: Time, { dist / time } @@ -21,7 +23,7 @@ fn generic_speed(dist: L, time: T) -> Quot fn main() { let x = 6.0 * si::M; let t = 3.0 * si::S; - let v = 2.0 * si::M/si::S; + let v = 2.0 * si::M / si::S; let v2 = speed(x, t); assert_eq!(v, v2); diff --git a/src/array.rs b/src/array.rs index 7eabda2d..474ef472 100644 --- a/src/array.rs +++ b/src/array.rs @@ -4,9 +4,9 @@ //! //! Consider this module **unstable**. -use typenum::{Add1, B1, Length, TArr, ATerm, Len, Integer, Unsigned, U0}; +use typenum::{ATerm, Add1, B1, Integer, Len, Length, TArr, U0, Unsigned}; -use generic_array::{GenericArray, ArrayLength}; +use generic_array::{ArrayLength, GenericArray}; use core::ops::Add; @@ -31,7 +31,6 @@ use core::ops::Add; /// } /// ``` pub trait ToGA { - /// The type of the `GenericArray` to which we've converted type Output; @@ -39,7 +38,6 @@ pub trait ToGA { fn to_ga() -> Self::Output; } - impl ToGA for ATerm { type Output = GenericArray; fn to_ga() -> Self::Output { @@ -47,13 +45,13 @@ impl ToGA for ATerm { } } - impl ToGA for TArr - where V: Integer, - A: Len + ToGA, - ::Output: AppendFront, - Length: Add, - Add1>: Unsigned + ArrayLength +where + V: Integer, + A: Len + ToGA, + ::Output: AppendFront, + Length: Add, + Add1>: Unsigned + ArrayLength, { type Output = <::Output as AppendFront>::Output; fn to_ga() -> Self::Output { @@ -61,7 +59,6 @@ impl ToGA for TArr } } - /// Implemented for `GenericArray`, this allows growable `GenericArray`s by appending elements to the front. /// /// # Example @@ -80,7 +77,6 @@ impl ToGA for TArr /// } pub trait AppendFront { - /// The resulting type after performing the append type Output; @@ -89,9 +85,10 @@ pub trait AppendFront { } impl AppendFront for GenericArray - where T: Default, - N: Add + ArrayLength, - Add1: ArrayLength +where + T: Default, + N: Add + ArrayLength, + Add1: ArrayLength, { type Output = GenericArray>; fn append_front(self, element: T) -> Self::Output { diff --git a/src/build/cgs.rs b/src/build/cgs.rs index a0d2008d..4c30705d 100644 --- a/src/build/cgs.rs +++ b/src/build/cgs.rs @@ -2,7 +2,8 @@ use super::*; pub fn new() -> System { System { - name: "CGS", module: "cgs", + name: "CGS", + module: "cgs", doc_prelude: "The Gaussian CGS unit system Note: this system is incomplete. More derived units and constants are coming. @@ -53,10 +54,7 @@ Note: this system is incomplete. More derived units and constants are coming. M: Centimeter = HECTO * CM.value_unsafe, "Meter"; ), fmt: false, - from: vec![ - "SI", - "MKS", - ], + from: vec!["SI", "MKS"], refl_blacklist: Vec::new(), } } diff --git a/src/build/fps.rs b/src/build/fps.rs index ae810957..405d76c9 100644 --- a/src/build/fps.rs +++ b/src/build/fps.rs @@ -2,7 +2,8 @@ use super::*; pub fn new() -> System { System { - name: "FPS", module: "fps", + name: "FPS", + module: "fps", doc_prelude: "The foot, pound, second system, using the mass pound as a base unit. Note: this system is incomplete. More derived units and constants are coming. @@ -17,8 +18,7 @@ Note: this system is incomplete. More derived units and constants are coming. FT: Foot = SqrtFoot * SqrtFoot, Length; LB: Pound = SqrtPound * SqrtPound, Mass; ), - constants: constants!( - ), + constants: constants!(), fmt: false, from: vec![ // "SI", diff --git a/src/build/mks.rs b/src/build/mks.rs index ee34f55e..03e06d23 100644 --- a/src/build/mks.rs +++ b/src/build/mks.rs @@ -2,7 +2,8 @@ use super::*; pub fn new() -> System { System { - name: "MKS", module: "mks", + name: "MKS", + module: "mks", doc_prelude: "The Gaussian MKS unit system Note: this system is incomplete. More derived units and constants are coming. @@ -19,13 +20,9 @@ Note: this system is incomplete. More derived units and constants are coming. MPS: MeterPerSecond = Meter / Second, Velocity; ), - constants: constants!( - ), + constants: constants!(), fmt: false, - from: vec![ - "SI", - "CGS", - ], + from: vec!["SI", "CGS"], refl_blacklist: Vec::new(), } } diff --git a/src/build/mod.rs b/src/build/mod.rs index 47bb21eb..8729c183 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -55,13 +55,14 @@ pub struct System { impl System { fn unit_tables(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - - write!(f, " + write!( + f, + " Following, we list all of the [base units](#base-units), [derived units](#derived-units), and [constants](#constants) that are defined in this unit system. -")?; - +" + )?; write!(f, "# Base Units\n")?; write!(f, "Constant | Unit | Print Token | Dimensionn\n")?; @@ -74,7 +75,11 @@ Following, we list all of the [base units](#base-units), [derived units](#derive write!(f, "Constant | Unit | Unit Definition | Dimension\n")?; write!(f, "---|---|---|---\n")?; for d in &self.derived { - write!(f, "{} | {} | {} | {}\n", d.constant, d.name, d.expression, d.dim)?; + write!( + f, + "{} | {} | {} | {}\n", + d.constant, d.name, d.expression, d.dim + )?; } write!(f, "# Constants\n")?; @@ -83,7 +88,15 @@ Following, we list all of the [base units](#base-units), [derived units](#derive for b in &self.base { let mut newline = false; for c in self.constants.iter().filter(|c| c.unit == b.name) { - write!(f, "{} | {} | {} | {} | {}\n", c.name, c.constant, c.nice_value(), c.unit, b.dim)?; + write!( + f, + "{} | {} | {} | {} | {}\n", + c.name, + c.constant, + c.nice_value(), + c.unit, + b.dim + )?; newline = true; } @@ -95,7 +108,15 @@ Following, we list all of the [base units](#base-units), [derived units](#derive for d in &self.derived { let mut newline = false; for c in self.constants.iter().filter(|c| c.unit == d.name) { - write!(f, "{} | {} | {} | {} | {}\n", c.name, c.constant, c.nice_value(), c.unit, d.dim)?; + write!( + f, + "{} | {} | {} | {} | {}\n", + c.name, + c.constant, + c.nice_value(), + c.unit, + d.dim + )?; newline = true; } if newline { @@ -115,42 +136,62 @@ impl fmt::Display for System { write!(f, "*/")?; - write!(f, " + write!( + f, + " pub mod {} {{ make_units! {{ {}; ONE: Unitless; - base {{\n", self.module, self.name)?; + base {{\n", + self.module, self.name + )?; for unit in &self.base { let dim = match unit.dim { "" => String::new(), d => format!(", {}", d), }; - write!(f, " {}: {}, \"{}\"{};\n", unit.constant, unit.name, unit.token, dim)?; + write!( + f, + " {}: {}, \"{}\"{};\n", + unit.constant, unit.name, unit.token, dim + )?; } - write!(f, " }} + write!( + f, + " }} - derived {{\n")?; + derived {{\n" + )?; for unit in &self.derived { let dim = match unit.dim { "" => String::new(), d => format!(", {}", d), }; - write!(f, " {}: {} = ({}){};\n", unit.constant, unit.name, unit.expression, dim)?; + write!( + f, + " {}: {} = ({}){};\n", + unit.constant, unit.name, unit.expression, dim + )?; } - write!(f, " }} + write!( + f, + " }} - constants {{\n")?; + constants {{\n" + )?; for c in &self.constants { write!(f, " {}: {} = {};\n", c.constant, c.unit, c.value)?; } - write!(f, " }} + write!( + f, + " }} fmt = {}; }} @@ -160,41 +201,66 @@ pub mod {} {{ pub use self::f64consts::*; -", self.fmt, self.name)?; +", + self.fmt, self.name + )?; - write!(f, " + write!( + f, + " #[test] fn test_{}_constants() {{ #[allow(unused_imports)] use f64prefixes::*; #[allow(unused_imports)] use core::f64::consts; -", self.module)?; +", + self.module + )?; for c in &self.constants { - write!(f, " - assert_eq!({}, {});", c.constant, c.nice_value())?; + write!( + f, + " + assert_eq!({}, {});", + c.constant, + c.nice_value() + )?; } - write!(f, " - }}")?; - - write!(f, " + write!( + f, + " + }}" + )?; + + write!( + f, + " /// Test that serializing/deserializing values with units is /// equivalent to doing so with raw numeric types. #[cfg(feature = \"serde\")] #[test] fn test_{}_serde() {{ use ::serde_test::{{assert_tokens, Token}}; -", self.module)?; +", + self.module + )?; for base in &self.base { - write!(f, " + write!( + f, + " let value = 1.0 * {}; assert_tokens(&value, &[Token::F64(1.0)]); -", base.constant)?; +", + base.constant + )?; } - write!(f, " + write!( + f, + " }} -}}")?; +}}" + )?; Ok(()) } @@ -243,11 +309,11 @@ fn make_system(s: &System) { write!(f, "{}", s).unwrap(); } -mod si; -mod ucum; -mod mks; mod cgs; mod fps; +mod mks; +mod si; +mod ucum; use std::io::Write; @@ -262,7 +328,8 @@ fn main() { let dest = std::path::Path::new(&out_dir).join("unit_systems.rs"); let mut f = std::fs::File::create(&dest).unwrap(); - f.write(r#"/** + f.write( + r#"/** Predefined unit systems When it makes sense, conversions are defined between unit systems. See the `conversion` module for @@ -329,15 +396,23 @@ more information. */ -pub mod unit_systems {"#.as_bytes()).unwrap(); +pub mod unit_systems {"#.as_bytes(), + ).unwrap(); for s in &systems { - write!(f, " - include!(concat!(env!(\"OUT_DIR\"), \"/{}.rs\"));", s.module).unwrap(); + write!( + f, + " + include!(concat!(env!(\"OUT_DIR\"), \"/{}.rs\"));", + s.module + ).unwrap(); } - write!(f, " -}}").unwrap(); + write!( + f, + " +}}" + ).unwrap(); #[cfg(feature = "test")] make_conversion_tests(&systems, &out_dir).unwrap(); @@ -349,7 +424,9 @@ fn make_conversion_tests(systems: &[System], out_dir: &str) -> Result<(), std::i let dest = std::path::Path::new(&out_dir).join("test_consts.rs"); let mut f = std::fs::File::create(&dest).unwrap(); - write!(f, " + write!( + f, + " extern crate dimensioned as dim; #[macro_use] extern crate approx; @@ -360,48 +437,65 @@ mod test; mod constant_conversion {{ use dim::unit_systems::*; use test::CmpConsts; -")?; +" + )?; for s in systems { use std::collections::HashSet; - let constants1: HashSet<_> = - s.base.iter().map(|b| b.constant) + let constants1: HashSet<_> = s + .base + .iter() + .map(|b| b.constant) .chain(s.derived.iter().map(|d| d.constant)) .chain(s.constants.iter().map(|c| c.constant)) .collect(); for s2 in systems.iter().filter(|s2| s2.name != s.name) { if s.from.iter().any(|&f| f == s2.name) && s2.from.iter().any(|&f| f == s.name) { - for c in constants1.iter().filter(|&c| !s.refl_blacklist.iter().any(|b| c == b)) { - write!(f, " + for c in constants1 + .iter() + .filter(|&c| !s.refl_blacklist.iter().any(|b| c == b)) + { + write!(f, " #[test] #[allow(non_snake_case)] fn reflexivity_of_{c}_from_{mod1}_to_{mod2}() {{ let a = {mod1}::{c}; let b = {mod1}::{sys1}::from({mod2}::{sys2}::from({mod1}::{c})); - a + b; // ensure type hasn't changed for {c} from {mod1} to {mod2} + let _ = a + b; // ensure type hasn't changed for {c} from {mod1} to {mod2} assert_ulps_eq!(a.value_unsafe, b.value_unsafe, epsilon = 0.0, max_ulps = 2); // ensures value hasn't changed assert_relative_eq!(a.value_unsafe, b.value_unsafe, epsilon = 0.0); // ensures value hasn't changed }}", mod1=s.module, mod2=s2.module, c=c, sys1=s.name, sys2=s2.name)?; } } - let constants2: HashSet<_> = - s2.base.iter().map(|b| b.constant) + let constants2: HashSet<_> = s2 + .base + .iter() + .map(|b| b.constant) .chain(s2.derived.iter().map(|d| d.constant)) .chain(s2.constants.iter().map(|c| c.constant)) .collect(); for c in constants1.intersection(&constants2) { - write!(f, " + write!( + f, + " #[test] #[allow(non_snake_case)] fn cmp_of_{c}_from_{mod2}_to_{mod1}() {{ {mod1}::{c}.test_eq({mod2}::{c}); - }}", mod1=s.module, mod2=s2.module, c=c)?; + }}", + mod1 = s.module, + mod2 = s2.module, + c = c + )?; } } } - write!(f, " -}}")?; + write!( + f, + " +}}" + )?; Ok(()) } diff --git a/src/build/si.rs b/src/build/si.rs index 9236d638..7d87dd08 100644 --- a/src/build/si.rs +++ b/src/build/si.rs @@ -2,7 +2,8 @@ use super::*; pub fn new() -> System { System { - name: "SI", module: "si", + name: "SI", + module: "si", doc_prelude: "The International System of Units (SI) Where experimental values are used for constants, the values are obtained from the 2014 values from @@ -185,11 +186,22 @@ Where experimental values are used for constants, the values are obtained from t LBF: Newton = 4.4482216152605 * N.value_unsafe, "Pound force"; ), fmt: true, - from: vec![ - "UCUM", + from: vec!["UCUM"], + refl_blacklist: vec![ + "MOL", + "KAT", + "MOLPM", + "MPMOL", + "MOLPKG", + "KGPMOL", + "M2PMOL", + "M3PMOL", + "SIEM2PMOL", + "JPKMOL", + "JPMOL", + "MOLPM2", + "MOLPM3", + "M3PMOLS", ], - refl_blacklist: vec! - ["MOL", "KAT", "MOLPM", "MPMOL", "MOLPKG", "KGPMOL", "M2PMOL", "M3PMOL", - "SIEM2PMOL", "JPKMOL", "JPMOL", "MOLPM2", "MOLPM3", "M3PMOLS"], } } diff --git a/src/build/ucum.rs b/src/build/ucum.rs index eed9dbb8..da62d207 100644 --- a/src/build/ucum.rs +++ b/src/build/ucum.rs @@ -2,7 +2,8 @@ use super::*; pub fn new() -> System { System { - name: "UCUM", module: "ucum", + name: "UCUM", + module: "ucum", doc_prelude: " The Unified Code for Units of Measure (UCUM) @@ -369,9 +370,7 @@ in function signatures), this is something to bear in mind. SMOOT: Meter = 67.0 * IN_I.value_unsafe, "Smoot"; ), fmt: true, - from: vec![ - "SI", - ], + from: vec!["SI"], refl_blacklist: vec!["RAD", "SR", "GON", "DEG", "CIRC", "LM", "SPH", "PHT", "LX"], } } diff --git a/src/conversion.rs b/src/conversion.rs index 0cdbbcef..f36e5ff1 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -27,50 +27,69 @@ mod to_si { // From UCUM - use si::SI; - use typenum::{Integer, Sum, Prod, Z0}; use core::convert::From; - use core::ops::{Mul, Add}; - use ucum; + use core::ops::{Add, Mul}; use f64prefixes::*; + use si::SI; + use typenum::{Integer, Prod, Sum, Z0}; + use ucum; - impl From< - ucum::UCUM> - for SI, tarr![Meter, Gram, Sum, Coulomb, Kelvin, Candela, Z0]> where - Meter: Integer, Second: Integer + Add, Gram: Integer, Kelvin: Integer, Coulomb: Integer, Candela: Integer, + impl + From> + for SI, tarr![Meter, Gram, Sum, Coulomb, Kelvin, Candela, Z0]> + where + Meter: Integer, + Second: Integer + Add, + Gram: Integer, + Kelvin: Integer, + Coulomb: Integer, + Candela: Integer, V: Mul, { - fn from(other: ucum::UCUM) -> Self { + fn from( + other: ucum::UCUM, + ) -> Self { let gfac = MILLI.powi(Gram::to_i32()); let fac = gfac; - SI::new( other.value_unsafe * fac ) + SI::new(other.value_unsafe * fac) } } } mod to_ucum { // From SI - use ucum::UCUM; - use typenum::{Integer, Diff, Prod, Z0}; use core::convert::From; use core::ops::{Mul, Sub}; - use si; use f64prefixes::*; + use si; + use typenum::{Diff, Integer, Prod, Z0}; + use ucum::UCUM; - impl From< - si::SI> - for UCUM, tarr![Meter, Diff, Kilogram, Z0, Kelvin, Ampere, Candela]> where - Meter: Integer, Kilogram: Integer, Second: Integer + Sub, Ampere: Integer, Kelvin: Integer, Candela: Integer, + impl + From> + for UCUM< + Prod, + tarr![Meter, Diff, Kilogram, Z0, Kelvin, Ampere, Candela], + > + where + Meter: Integer, + Kilogram: Integer, + Second: Integer + Sub, + Ampere: Integer, + Kelvin: Integer, + Candela: Integer, V: Mul, { - fn from(other: si::SI) -> Self { + fn from( + other: si::SI, + ) -> Self { let kgfac = KILO.powi(Kilogram::to_i32()); let fac = kgfac; - UCUM::new( other.value_unsafe * fac ) + UCUM::new(other.value_unsafe * fac) } } } @@ -78,14 +97,18 @@ mod to_ucum { mod to_cgs { use cgs::CGS; // From MKS - use typenum::{Integer, Prod, Sum}; use core::convert::From; - use core::ops::{Mul, Add}; - use mks; + use core::ops::{Add, Mul}; use f64prefixes::*; - impl From> - for CGS, tarr![SqrtMeter, SqrtKilogram, Second]> where - SqrtMeter: Integer, SqrtKilogram: Integer, Second: Integer, + use mks; + use typenum::{Integer, Prod, Sum}; + impl + From> + for CGS, tarr![SqrtMeter, SqrtKilogram, Second]> + where + SqrtMeter: Integer, + SqrtKilogram: Integer, + Second: Integer, V: Mul, { fn from(other: mks::MKS) -> Self { @@ -100,30 +123,35 @@ mod to_cgs { let fac = mfac * kgfac; - CGS::new( other.value_unsafe * fac ) + CGS::new(other.value_unsafe * fac) } } // From SI use si; - use typenum::{Z0, P2, P3}; - impl From< - si::SI> - for CGS, f64>, tarr![ + use typenum::{P2, P3, Z0}; + impl + From> + for CGS< + Prod, f64>, + tarr![ Sum, Prod>, Sum, Ampere>, Sum> - ]> where V: Mul, - Meter: Integer + Mul, - Kilogram: Integer + Mul, - Second: Integer + Add>, - Ampere: Integer + Mul + Mul, - Prod: Add>, - Prod: Add, - Sum, Prod>: Integer, - Sum, Ampere>: Integer, - Sum>: Integer, - Prod: Mul, + ], + > + where + V: Mul, + Meter: Integer + Mul, + Kilogram: Integer + Mul, + Second: Integer + Add>, + Ampere: Integer + Mul + Mul, + Prod: Add>, + Prod: Add, + Sum, Prod>: Integer, + Sum, Ampere>: Integer, + Sum>: Integer, + Prod: Mul, { fn from(other: si::SI) -> Self { CGS::from(mks::MKS::from(other)) @@ -132,21 +160,25 @@ mod to_cgs { } mod to_mks { - use mks::MKS; - use typenum::{Integer, Prod, Sum}; use core::convert::From; - use core::ops::{Mul, Add}; + use core::ops::{Add, Mul}; use f64prefixes::*; + use mks::MKS; + use typenum::{Integer, Prod, Sum}; // From CGS use cgs; - impl From> - for MKS, tarr![SqrtCentimeter, SqrtGram, Second]> where - SqrtCentimeter: Integer, SqrtGram: Integer, Second: Integer, + impl + From> + for MKS, tarr![SqrtCentimeter, SqrtGram, Second]> + where + SqrtCentimeter: Integer, + SqrtGram: Integer, + Second: Integer, V: Mul, { fn from(other: cgs::CGS) -> Self { let cmfac = match SqrtCentimeter::to_i32() { - e if e % 2 == 0 => CENTI.powi(e/2), + e if e % 2 == 0 => CENTI.powi(e / 2), e => CENTI.sqrt().powi(e), }; let gfac = match SqrtGram::to_i32() { @@ -156,29 +188,34 @@ mod to_mks { let fac = cmfac * gfac; - MKS::new( other.value_unsafe * fac ) + MKS::new(other.value_unsafe * fac) } } // From SI use si; - use typenum::{Z0, P2, P3}; - impl From< - si::SI> - for MKS, tarr![ + use typenum::{P2, P3, Z0}; + impl + From> + for MKS< + Prod, + tarr![ Sum, Prod>, Sum, Ampere>, Sum> - ]> where V: Mul, - Meter: Integer + Mul, - Kilogram: Integer + Mul, - Second: Integer + Add>, - Ampere: Integer + Mul + Mul, - Prod: Add>, - Prod: Add, + ], + > + where + V: Mul, + Meter: Integer + Mul, + Kilogram: Integer + Mul, + Second: Integer + Add>, + Ampere: Integer + Mul + Mul, + Prod: Add>, + Prod: Add, { fn from(other: si::SI) -> Self { - MKS::new( other.value_unsafe * 1.0 ) + MKS::new(other.value_unsafe * 1.0) } } } diff --git a/src/fmt.rs b/src/fmt.rs index dc0fc202..9bf80a7b 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -49,4 +49,3 @@ format_cgs_like!(MKS; ["m", "k", "s"]; Display Octal LowerHex UpperHex Pointer B use unit_systems::fps::FPS; format_cgs_like!(FPS; ["ft", "lb", "s"]; Display Octal LowerHex UpperHex Pointer Binary LowerExp UpperExp); - diff --git a/src/lib.rs b/src/lib.rs index 95651e67..e129fff6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,12 +52,19 @@ order is the order in which the base units were defined, and the values of the t power to which each unit is raised. For example, the first three SI units, in order, are `Meter`, `Kilogram`, `Second`, so the following aliases exist: -```ignore +```rust +#[macro_use] +extern crate dimensioned as dim; +use dim::si::SI; +use dim::typenum::{P1, Z0, N1, N2}; + type Meter = SI; type Kilogram = SI; type Second = SI; type Newton = SI; -... +// ... + +fn main() {} ``` In addition to creating the unit system struct, `SI`, the type aliases, and constants for each, @@ -91,23 +98,23 @@ crate. Pretty much everything else is for ergonomics. */ -#![doc(html_logo_url = "https://raw.githubusercontent.com/paholg/dimensioned/master/favicon.png", - html_favicon_url = "https://raw.githubusercontent.com/paholg/dimensioned/master/favicon.png", - html_root_url = "http://paholg.com/dimensioned")] - +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paholg/dimensioned/master/favicon.png", + html_favicon_url = "https://raw.githubusercontent.com/paholg/dimensioned/master/favicon.png", + html_root_url = "http://paholg.com/dimensioned" +)] #![no_std] - #![warn(missing_docs)] - #![cfg_attr(feature = "oibit", feature(optin_builtin_traits))] #![cfg_attr(feature = "spec", feature(specialization))] - -#![cfg_attr(feature="clippy", feature(plugin))] -#![cfg_attr(feature="clippy", plugin(clippy))] - +#![cfg_attr(feature = "clippy", feature(plugin))] +#![cfg_attr(feature = "clippy", plugin(clippy))] #![allow(unknown_lints)] #![deny(clippy)] #![allow(type_complexity, float_cmp, useless_attribute, doc_markdown)] +#![cfg_attr( + feature = "cargo-clippy", allow(type_complexity, float_cmp, useless_attribute, doc_markdown) +)] // Macro debugging // #![feature(trace_macros)] @@ -159,25 +166,23 @@ pub extern crate serde; #[cfg(feature = "serde_test")] extern crate serde_test; -#[macro_use] mod make_units; +#[macro_use] +mod make_units; mod fmt; - include!(concat!(env!("OUT_DIR"), "/unit_systems.rs")); -pub mod traits; -pub mod dimensions; -pub mod conversion; pub mod array; +pub mod conversion; +pub mod dimensions; pub mod f32prefixes; pub mod f64prefixes; - +pub mod traits; pub use traits::*; -pub use unit_systems::{si, ucum, cgs, mks, fps}; - +pub use unit_systems::{cgs, fps, mks, si, ucum}; // Used for the make_units macro #[doc(hidden)] pub mod dimcore { - pub use core::{marker, fmt, ops, mem, f32, f64}; + pub use core::{f32, f64, fmt, marker, mem, ops}; } diff --git a/src/make_units.rs b/src/make_units.rs index 0e373000..260fb8de 100644 --- a/src/make_units.rs +++ b/src/make_units.rs @@ -228,7 +228,9 @@ macro_rules! make_units { } use $crate::MapUnsafe; - impl MapUnsafe for $System { + impl MapUnsafe + for $System + { type Output = $System; #[inline] fn map_unsafe ValueOut>(self, f: F) -> Self::Output { @@ -261,7 +263,8 @@ macro_rules! make_units { #[allow(unused_imports)] use $crate::typenum::consts::*; __make_units_internal!(@base_arrays $Unitless $($Unit)*); - $(#[allow(missing_docs)] pub type $Derived = __derived_internal!(@mu commas $($derived_rhs)+);)* + $(#[allow(missing_docs)] pub type $Derived = + __derived_internal!(@mu commas $($derived_rhs)+);)* } #[allow(missing_docs)] @@ -293,13 +296,17 @@ macro_rules! make_units { #[allow(unused_imports)] use $crate::dimcore::$t::consts; #[allow(unused_imports)] use $crate::$prefixes::*; #[allow(dead_code, missing_docs)] - pub const $one: $Unitless<$t> = $System { value_unsafe: 1.0, _marker: PhantomData }; + pub const $one: $Unitless<$t> = + $System { value_unsafe: 1.0, _marker: PhantomData }; $(#[allow(dead_code, missing_docs)] - pub const $base: $Unit<$t> = $System { value_unsafe: 1.0, _marker: PhantomData };)* + pub const $base: $Unit<$t> = + $System { value_unsafe: 1.0, _marker: PhantomData };)* $(#[allow(dead_code, missing_docs)] - pub const $derived_const: $Derived<$t> = $System { value_unsafe: 1.0, _marker: PhantomData };)* + pub const $derived_const: $Derived<$t> = + $System { value_unsafe: 1.0, _marker: PhantomData };)* $(#[allow(dead_code, missing_docs)] - pub const $constant: $ConstantUnit<$t> = $System { value_unsafe: $constant_value, _marker: PhantomData };)* + pub const $constant: $ConstantUnit<$t> = + $System { value_unsafe: $constant_value, _marker: PhantomData };)* } ); } @@ -313,11 +320,14 @@ macro_rules! make_units { use super::*; use $crate::dimcore::marker::PhantomData; #[allow(dead_code, missing_docs)] - pub const $one: $Unitless<$t> = $System { value_unsafe: 1, _marker: PhantomData }; + pub const $one: $Unitless<$t> = + $System { value_unsafe: 1, _marker: PhantomData }; $(#[allow(dead_code, missing_docs)] - pub const $base: $Unit<$t> = $System { value_unsafe: 1, _marker: PhantomData };)* + pub const $base: $Unit<$t> = + $System { value_unsafe: 1, _marker: PhantomData };)* $(#[allow(dead_code, missing_docs)] - pub const $derived_const: $Derived<$t> = $System { value_unsafe: 1, _marker: PhantomData };)* + pub const $derived_const: $Derived<$t> = + $System { value_unsafe: 1, _marker: PhantomData };)* } ); } @@ -354,7 +364,9 @@ macro_rules! make_units { // -------------------------------------------------------------------------------- // Operator traits from this crate - impl $crate::Recip for $System where V: $crate::Recip, U: $crate::dimcore::ops::Neg, { + impl $crate::Recip for $System + where V: $crate::Recip, U: $crate::dimcore::ops::Neg, + { type Output = $System<::Output, $crate::typenum::Negate>; #[inline] fn recip(self) -> Self::Output { $System::new(self.value_unsafe.recip()) } @@ -376,7 +388,10 @@ macro_rules! make_units { where V: $crate::Root, U: $crate::typenum::PartialDiv, { - type Output = $System< >::Output, $crate::typenum::PartialQuot>; + type Output = $System< + >::Output, + $crate::typenum::PartialQuot + >; #[inline] fn root(self, idx: Index) -> Self::Output { $System::new( self.value_unsafe.root(idx) ) @@ -388,7 +403,8 @@ macro_rules! make_units { where V: $crate::Sqrt, U: $crate::typenum::PartialDiv, { - type Output = $System< ::Output, $crate::typenum::PartialQuot>; + type Output = $System< + ::Output, $crate::typenum::PartialQuot>; #[inline] fn sqrt(self) -> Self::Output { $System::new( self.value_unsafe.sqrt() ) @@ -400,7 +416,10 @@ macro_rules! make_units { where V: $crate::Cbrt, U: $crate::typenum::PartialDiv, { - type Output = $System< ::Output, $crate::typenum::PartialQuot>; + type Output = $System< + ::Output, + $crate::typenum::PartialQuot + >; #[inline] fn cbrt(self) -> Self::Output { $System::new( self.value_unsafe.cbrt() ) @@ -477,14 +496,32 @@ macro_rules! make_units { fn default_max_ulps() -> u32 { V::default_max_ulps() } - fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool { - self.value_unsafe.relative_eq(&other.value_unsafe, epsilon.value_unsafe, max_relative.value_unsafe) + fn relative_eq( + &self, + other: &Self, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon + ) -> bool { + self.value_unsafe.relative_eq( + &other.value_unsafe, + epsilon.value_unsafe, + max_relative.value_unsafe, + ) } fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { self.value_unsafe.ulps_eq(&other.value_unsafe, epsilon.value_unsafe, max_ulps) } - fn relative_ne(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool { - self.value_unsafe.relative_ne(&other.value_unsafe, epsilon.value_unsafe, max_relative.value_unsafe) + fn relative_ne( + &self, + other: &Self, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon + ) -> bool { + self.value_unsafe.relative_ne( + &other.value_unsafe, + epsilon.value_unsafe, + max_relative.value_unsafe, + ) } fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { self.value_unsafe.ulps_ne(&other.value_unsafe, epsilon.value_unsafe, max_ulps) @@ -1012,15 +1049,27 @@ macro_rules! __derived_internal { // Both qualify as identifiers (@eval $module:ident, $a:ident, /, $b:ident, $($tail:tt)*) => ( - __derived_internal!(@eval $module, $crate::typenum::Diff<$module::inner::$a, $module::inner::$b>, $($tail)* ) + __derived_internal!( + @eval $module, + $crate::typenum::Diff<$module::inner::$a, $module::inner::$b>, + $($tail)* + ) ); (@eval $module:ident, $a:ident, *, $b:ident, $($tail:tt)*) => ( - __derived_internal!(@eval $module, $crate::typenum::Sum<$module::inner::$a, $module::inner::$b>, $($tail)* ) + __derived_internal!( + @eval $module, + $crate::typenum::Sum<$module::inner::$a, $module::inner::$b>, + $($tail)* + ) ); // $a is an intermediate result: (@eval $module:ident, $a:ty, /, $b:ident, $($tail:tt)*) => ( - __derived_internal!(@eval $module, $crate::typenum::Diff<$a, $module::inner::$b>, $($tail)* ) + __derived_internal!( + @eval $module, + $crate::typenum::Diff<$a, $module::inner::$b>, + $($tail)* + ) ); (@eval $module:ident, $a:ty, *, $b:ident, $($tail:tt)*) => ( __derived_internal!(@eval $module, $crate::typenum::Sum<$a, $module::inner::$b>, $($tail)* ) diff --git a/src/traits.rs b/src/traits.rs index f93ccd91..d6ae6693 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -7,7 +7,6 @@ /// /// It is not recommened to implement this for anything outside this this crate. pub trait Dimensioned { - /// The type of the value of a quantity. E.g. For `si::Meter`, `Value` is `f64`. type Value; @@ -26,7 +25,6 @@ pub trait Dimensioned { /// This trait is implemented for all quantities with no units. The unit systems that come with /// dimensioned use `Unitless` for that type. pub trait Dimensionless: Dimensioned { - /// Extract the value from a quantity with no units. As there are no units to ignore, it is /// dimensionally safe. fn value(&self) -> &Self::Value; @@ -83,7 +81,6 @@ pub trait Dimensionless: Dimensioned { /// } /// ``` pub trait MapUnsafe: Dimensioned { - /// The type to which the input is mapped type Output; @@ -114,7 +111,6 @@ pub trait MapUnsafe: Dimensioned { /// } /// ``` pub trait Map: Dimensionless { - /// The type to which the input is mapped type Output; @@ -124,17 +120,17 @@ pub trait Map: Dimensionless { #[cfg(feature = "oibit")] /// Everything that is not a quantity implements this trait -pub trait NotDim {} -#[cfg(feature = "oibit")] -impl NotDim for .. {} +pub auto trait NotDim {} macro_rules! impl_unary { - ($Type:ty, $Trait:ident, $fun:ident) => ( + ($Type:ty, $Trait:ident, $fun:ident) => { impl $Trait for $Type { type Output = $Type; - fn $fun(self) -> Self::Output { self.$fun() } + fn $fun(self) -> Self::Output { + self.$fun() + } } - ); + }; } /// `Recip` is used for implementing a `recip()` member for types that are not preserved under @@ -154,7 +150,6 @@ macro_rules! impl_unary { /// } /// ``` pub trait Recip { - /// The resulting type after taking the reciprocal type Output; @@ -165,7 +160,6 @@ pub trait Recip { impl_unary!(f32, Recip, recip); impl_unary!(f64, Recip, recip); - /// `Root` is used for implementing general integer roots for types that aren't necessarily /// preserved under root. /// @@ -185,7 +179,6 @@ impl_unary!(f64, Recip, recip); /// } /// ``` pub trait Root { - /// The resulting type after taking the `Index` root type Output; @@ -195,7 +188,7 @@ pub trait Root { use typenum::Integer; macro_rules! impl_root { - ($t: ty, $f: ident) => ( + ($t:ty, $f:ident) => { impl Root for $t { type Output = $t; @@ -204,7 +197,7 @@ macro_rules! impl_root { self.powf(exp) } } - ); + }; } impl_root!(f32, powf32); @@ -223,7 +216,6 @@ fn test_root() { } } - /// `Sqrt` provides a `sqrt` member function for types that are not necessarily preserved under /// square root. /// @@ -242,7 +234,6 @@ fn test_root() { /// } /// ``` pub trait Sqrt { - /// The resulting type after taking the square root type Output; @@ -268,7 +259,6 @@ pub trait Sqrt { /// } /// ``` pub trait Cbrt { - /// The resulting type after taking the cube root type Output; @@ -277,7 +267,7 @@ pub trait Cbrt { } macro_rules! impl_sqcbroot { - ($t: ty) => ( + ($t:ty) => { impl Sqrt for $t { type Output = $t; fn sqrt(self) -> Self::Output { @@ -291,7 +281,7 @@ macro_rules! impl_sqcbroot { self.cbrt() } } - ); + }; } impl_sqcbroot!(f32); diff --git a/tests/consts.rs b/tests/consts.rs index 6984bef3..c9941197 100644 --- a/tests/consts.rs +++ b/tests/consts.rs @@ -1,5 +1,4 @@ #![cfg(feature = "test")] - #![feature(specialization)] include!(concat!(env!("OUT_DIR"), "/test_consts.rs")); diff --git a/tests/derived.rs b/tests/derived.rs index cada2e0f..365cf04c 100644 --- a/tests/derived.rs +++ b/tests/derived.rs @@ -16,5 +16,5 @@ fn derived() { let v = speed(d, t); - assert_eq!(d/t, v); + assert_eq!(d / t, v); } diff --git a/tests/tests.rs b/tests/tests.rs index 553eeea2..815e3f7a 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,8 +1,7 @@ -#![cfg(feature = "qc")] - -#![feature(plugin)] -#![plugin(quickcheck_macros)] +#![cfg(test)] +#![cfg(feature = "quickcheck")] +#[macro_use] extern crate quickcheck; extern crate dimensioned as dim; @@ -12,54 +11,70 @@ mod quickchecking { use quickcheck::TestResult; - #[quickcheck] - fn add(x: f64, y: f64) -> bool { - x*M + y*M == Meter::new(x + y) && - x*S + y*S == Second::new(x + y) && - x*J + y*J == Joule::new(x + y) + quickcheck!{ + fn add(x: f64, y: f64) -> bool { + let m_res = x * M + y * M == Meter::new(x + y); + let s_res = x * S + y * S == Second::new(x + y); + let j_res = x * J + y * J == Joule::new(x + y); + + m_res && s_res && j_res + } } - #[quickcheck] - fn sub(x: f64, y: f64) -> bool { - x*M - y*M == Meter::new(x - y) && - x*S - y*S == Second::new(x - y) && - x*J - y*J == Joule::new(x - y) + quickcheck!{ + fn sub(x: f64, y: f64) -> bool { + let m_res = x * M - y * M == Meter::new(x - y); + let s_res = x * S - y * S == Second::new(x - y); + let j_res = x * J - y * J == Joule::new(x - y); + + m_res && s_res && j_res + } } - #[quickcheck] - fn mul(x: f64, y: f64) -> bool { - (x*M) * y == Meter::new(x * y) && - x * (y*M) == Meter::new(x * y) && - (x*M) * (y*M) == Meter2::new(x * y) + quickcheck!{ + fn mul(x: f64, y: f64) -> bool { + let res1 = (x * M) * y == Meter::new(x * y); + let res2 = x * (y * M) == Meter::new(x * y); + let res3 = (x * M) * (y * M) == Meter2::new(x * y); + + res1 && res2 && res3 + } } - #[quickcheck] - fn div(x: f64, y: f64) -> bool { - (x*M) / y == Meter::new(x / y) && - x / (y*M) == PerMeter::new(x / y) && - (x*M) * (y*M) == Meter2::new(x * y) + quickcheck!{ + fn div(x: f64, y: f64) -> bool { + let res1 = (x * M) / y == Meter::new(x / y); + let res2 = x / (y * M) == PerMeter::new(x / y); + let res3 = (x * M) * (y * M) == Meter2::new(x * y); + + res1 && res2 && res3 + } } use dim::Sqrt; - #[quickcheck] - fn sqrt(x: f64) -> TestResult { - if x < 0. { - return TestResult::discard(); - } + quickcheck!{ + fn sqrt(x: f64) -> TestResult { + if x < 0. { + return TestResult::discard(); + } + + let res1 = *(x * ONE).sqrt() == x.sqrt(); + let res2 = (x * M * M).sqrt() == Meter::new(x.sqrt()); + let res3 = (x * M * M / S / S).sqrt() == MeterPerSecond::new(x.sqrt()); - TestResult::from_bool( - *(x*ONE).sqrt() == x.sqrt() && - (x*M*M).sqrt() == Meter::new(x.sqrt()) && - (x*M*M/S/S).sqrt() == MeterPerSecond::new(x.sqrt()) - ) + TestResult::from_bool(res1 && res2 && res3) + } } use dim::Cbrt; - #[quickcheck] - fn cbrt(x: f64) -> bool { - *(x*ONE).cbrt() == x.cbrt() && - (x*M*M*M).cbrt() == Meter::new(x.cbrt()) && - (x*M*M*M/S/S/S).cbrt() == MeterPerSecond::new(x.cbrt()) + quickcheck!{ + fn cbrt(x: f64) -> bool { + let res1 = *(x * ONE).cbrt() == x.cbrt(); + let res2 = (x * M * M * M).cbrt() == Meter::new(x.cbrt()); + let res3 = (x * M * M * M / S / S / S).cbrt() == MeterPerSecond::new(x.cbrt()); + + res1 && res2 && res3 + } } }