Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update quickcheck #260

Merged
merged 3 commits into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci-full-test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --all --verbose --features "use_serde try-from"
args: --all --verbose --features "use_serde"

- name: Test si
uses: actions-rs/cargo@v1
Expand All @@ -48,16 +48,16 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --no-default-features --features "autoconvert f32 si use_serde try-from"
args: --verbose --no-default-features --features "autoconvert f32 si use_serde"

- name: Test si with underlying storage types
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --no-run --no-default-features --features "autoconvert usize isize bigint bigrational si std use_serde try-from"
args: --verbose --no-run --no-default-features --features "autoconvert usize isize bigint bigrational si std use_serde"

- name: Test all non-si features
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --no-run --no-default-features --features "autoconvert usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 bigint biguint rational rational32 rational64 bigrational f32 f64 std use_serde try-from"
args: --verbose --no-run --no-default-features --features "autoconvert usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 bigint biguint rational rational32 rational64 bigrational f32 f64 std use_serde"
4 changes: 2 additions & 2 deletions .github/workflows/ci-min-test-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- stable
- beta
- nightly
- 1.37.0 # MSRV
- 1.43.0 # MSRV
exclude:
- os: ubuntu-latest
rust: stable
Expand All @@ -42,4 +42,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --all --verbose --features "use_serde try-from"
args: --all --verbose --features "use_serde"
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ autotests = true
autobenches = true

[package.metadata.docs.rs]
features = ["usize", "u32", "u64", "isize", "i32", "i64", "bigint", "biguint", "rational", "rational32", "rational64", "bigrational", "try-from", "use_serde"]
features = ["usize", "u32", "u64", "isize", "i32", "i64", "bigint", "biguint", "rational", "rational32", "rational64", "bigrational", "use_serde"]

[package.metadata]
msrv = "1.43.0"

[badges]
maintenance = { status = "actively-developed" }
Expand All @@ -38,7 +41,7 @@ typenum = "1.13"

[dev-dependencies]
approx = "0.5"
quickcheck = "0.9.2"
quickcheck = "1.0"
serde_json = "1.0"
static_assertions = "1.1"

Expand Down Expand Up @@ -67,9 +70,8 @@ f32 = []
f64 = []
si = []
std = ["num-traits/std"]
# The `try-from` feature provides `impl TryFrom<Time> for Duration` and `impl TryFrom<Duration> for
# Time`. The `TryFrom` trait was stabilized in Rust 1.34.0 and will cause uom to fail to compile if
# enabled with an earlier version of Rust.
# The try-from feature is deprecated and will be removed in a future release of uom. Functionality
# previously exposed by the feature is now enabled by default.
try-from = []
# The `use_serde` feature exists so that, in the future, other dependency features like num/serde
# can be added. However, num/serde is currently left out because it has not yet been updated to
Expand Down
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ uom
===
[![Github Actions](https://img.shields.io/github/workflow/status/iliekturtles/uom/CI%20-%20full%20test%20suite/master?label=build)](https://github.com)
[![Codecov.io](https://img.shields.io/codecov/c/github/iliekturtles/uom/master)](https://codecov.io/gh/iliekturtles/uom)
[![Rustup.rs](https://img.shields.io/badge/rustc-1.37.0%2B-orange.svg)](https://rustup.rs/)
[![Rustup.rs](https://img.shields.io/badge/rustc-1.43.0%2B-orange.svg)](https://rustup.rs/)
[![Crates.io](https://img.shields.io/crates/v/uom.svg)](https://crates.io/crates/uom)
[![Crates.io](https://img.shields.io/crates/l/uom.svg)](https://crates.io/crates/uom)
[![Documentation](https://img.shields.io/badge/documentation-docs.rs-blue.svg)](https://docs.rs/uom)
Expand All @@ -23,7 +23,7 @@ Units of measurement is a crate that does automatic type-safe zero-cost
[orbiter]: https://en.wikipedia.org/wiki/Mars_Climate_Orbiter

## Usage
`uom` requires `rustc` 1.37.0 or later. Add this to your `Cargo.toml`:
`uom` requires `rustc` 1.43.0 or later. Add this to your `Cargo.toml`:

```toml
[dependencies]
Expand Down Expand Up @@ -89,7 +89,6 @@ uom = {
"rational", "rational32", "rational64", "bigrational", # Integer ratio storage types.
"f32", "f64", # Floating point storage types.
"si", "std", # Built-in SI system and std library support.
"try-from", # `TryFrom` support between `Time` and `Duration`. Requires `rustc` 1.34.0.
"use_serde", # Serde support.
]
}
Expand All @@ -108,8 +107,6 @@ uom = {
default.
* `std` -- Feature to compile with standard library support. Disabling this feature compiles `uom`
with `no_std`. Enabled by default.
* `try-from` -- Feature to enable `TryFrom` support between `Time` and `Duration`. Requires `rustc`
1.34.0.
* `use_serde` -- Feature to enable support for serialization and deserialization of quantities
with the [Serde][serde] crate. Disabled by default.

Expand Down
9 changes: 4 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//! [orbiter]: https://en.wikipedia.org/wiki/Mars_Climate_Orbiter
//!
//! ## Usage
//! `uom` requires `rustc` 1.37.0 or later. Add this to your `Cargo.toml`:
//! `uom` requires `rustc` 1.43.0 or later. Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
Expand Down Expand Up @@ -76,7 +76,6 @@
//! "rational", "rational32", "rational64", "bigrational", # Integer ratio storage types.
//! "f32", "f64", # Floating point storage types.
//! "si", "std", # Built-in SI system and std library support.
//! "try-from", # `TryFrom` support between `Time` and `Duration`. Requires `rustc` 1.34.0.
//! "use_serde", # Serde support.
//! ]
//! }
Expand All @@ -96,8 +95,6 @@
//! default.
//! * `std` -- Feature to compile with standard library support. Disabling this feature compiles
//! `uom` with `no_std`. Enabled by default.
//! * `try-from` -- Feature to enable `TryFrom` support between `Time` and `Duration`. Requires
//! `rustc` 1.34.0.
//! * `use_serde` -- Feature to enable support for serialization and deserialization of quantities
//! with the [Serde][serde] crate. Disabled by default.
//!
Expand Down Expand Up @@ -441,8 +438,10 @@ pub trait Conversion<V> {
/// * `V`: Underlying storage type trait is implemented for.
///
/// [factor]: https://jcgm.bipm.org/vim/en/1.24.html
#[allow(unused_qualifications)] // lib:cmp::PartialOrder false positive.
pub trait ConversionFactor<V>:
lib::ops::Add<Self, Output = Self>
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>
Expand Down
16 changes: 6 additions & 10 deletions src/si/ratio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,33 +161,29 @@ mod tests {
use crate::si::quantities::*;
use crate::tests::Test;

fn test_nan_or_eq(yl: V, yr: V) -> bool {
(yl.is_nan() && yr.is_nan()) || Test::eq(&yl, &yr)
}

quickcheck! {
fn acos(x: V) -> bool {
test_nan_or_eq(x.acos(), Ratio::from(x).acos().get::<a::radian>())
Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
}

fn acosh(x: V) -> bool {
test_nan_or_eq(x.acosh(), Ratio::from(x).acosh().get::<a::radian>())
Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
}

fn asin(x: V) -> bool {
test_nan_or_eq(x.asin(), Ratio::from(x).asin().get::<a::radian>())
Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
}

fn asinh(x: V) -> bool {
test_nan_or_eq(x.asinh(), Ratio::from(x).asinh().get::<a::radian>())
Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
}

fn atan(x: V) -> bool {
test_nan_or_eq(x.atan(), Ratio::from(x).atan().get::<a::radian>())
Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
}

fn atanh(x: V) -> bool {
test_nan_or_eq(x.atanh(), Ratio::from(x).atanh().get::<a::radian>())
Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
}
}
}
Expand Down
100 changes: 38 additions & 62 deletions src/si/time.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! Time (base unit second, s).

#[cfg(feature = "try-from")]
use crate::lib::time::Duration;
#[cfg(feature = "try-from")]
use crate::num::{FromPrimitive, ToPrimitive, Zero};

quantity! {
Expand Down Expand Up @@ -58,7 +56,6 @@ quantity! {
}

/// An error encountered converting between `Time` and `Duration`.
#[cfg(feature = "try-from")]
#[derive(Debug, Clone, Copy)]
pub enum TryFromError {
/// The given time interval was negative, making conversion to a duration nonsensical.
Expand All @@ -81,7 +78,6 @@ pub enum TryFromError {
/// underlying storage type or avoiding the conversion altogether.
///
/// [TryFromError]: enum.TryFromError.html
#[cfg(feature = "try-from")]
impl<U, V> crate::lib::convert::TryFrom<Time<U, V>> for Duration
where
U: crate::si::Units<V> + ?Sized,
Expand Down Expand Up @@ -117,7 +113,6 @@ where
/// different underlying storage type or avoiding the conversion altogether.
///
/// [TryFromError]: enum.TryFromError.html
#[cfg(feature = "try-from")]
impl<U, V> crate::lib::convert::TryFrom<Duration> for Time<U, V>
where
U: crate::si::Units<V> + ?Sized,
Expand All @@ -129,7 +124,7 @@ where

fn try_from(duration: Duration) -> Result<Self, Self::Error> {
let secs = V::from_u64(duration.as_secs());
let nanos = V::from_u32(duration.subsec_micros());
let nanos = V::from_u32(duration.subsec_nanos());

match (secs, nanos) {
(Some(secs), Some(nanos)) => {
Expand All @@ -140,78 +135,59 @@ where
}
}

#[cfg(all(test, feature = "try-from"))]
#[cfg(test)]
mod tests {
storage_types! {
types: PrimInt, BigInt, BigUint, Float;

use crate::lib::convert::{TryFrom, TryInto};
use crate::ConversionFactor;
use crate::lib::convert::TryFrom;
use crate::lib::time::Duration;
use crate::num::{FromPrimitive, ToPrimitive, Zero};
use crate::num::{FromPrimitive, ToPrimitive, One, Zero};
use crate::si::quantities::*;
use crate::si::time::{TryFromError, nanosecond};
use crate::si::time::{TryFromError, second, nanosecond};
use crate::tests::*;
use quickcheck::TestResult;

quickcheck! {
fn duration_try_from(v: A<V>) -> TestResult {
test_try_from(Duration::try_from(Time::new::<nanosecond>((*v).clone())), v)
}

fn time_try_into(v: A<V>) -> TestResult {
test_try_from(Time::new::<nanosecond>((*v).clone()).try_into(), v)
}

fn time_try_from(v: A<V>) -> TestResult {
match v.to_u64() {
Some(u) => test_try_into(Time::try_from(Duration::from_nanos(u)), v),
None => TestResult::discard(),
fn duration_try_from(v: A<V>) -> bool {
let ns: V = <nanosecond as crate::Conversion<V>>::coefficient().value();
let t = Time::new::<second>((*v).clone());
let d = Duration::try_from(t);
let r = (*v).clone() % V::one();
let s = ((*v).clone() - r.clone()).to_u64();
let n = (r * (V::one() / &ns)).to_u32();

match (d, s, n) {
(Ok(d), Some(s), Some(n)) => d.as_secs() == s && d.subsec_nanos() == n,
(Err(TryFromError::NegativeDuration), _, _) if *v < V::zero() => true,
(Err(TryFromError::Overflow), None, _) => true,
(Err(TryFromError::Overflow), _, None) => true,
_ => false,
}
}

fn duration_try_into(v: A<V>) -> TestResult {
match v.to_u64() {
Some(u) => test_try_into(Duration::from_nanos(u).try_into(), v),
None => TestResult::discard(),
fn time_try_from(v: A<V>) -> TestResult {
if *v < V::zero() {
return TestResult::discard();
}
}
}

fn test_try_from(t: Result<Duration, TryFromError>, v: A<V>) -> TestResult {
if *v < V::zero() {
return TestResult::discard();
let ns: V = <nanosecond as crate::Conversion<V>>::coefficient().value();
let r = (*v).clone() % V::one();
let s = ((*v).clone() - r.clone()).to_u64();
let n = (r * (V::one() / &ns)).to_u32();

return match (s, n) {
(Some(s), Some(n)) => TestResult::from_bool(
match (Time::try_from(Duration::new(s, n)), V::from_u64(s), V::from_u32(n)) {
(Ok(t), Some(s), Some(n)) => t == Time::new::<second>(s) + Time::new::<nanosecond>(n),
(Err(TryFromError::Overflow), None, _) => true,
(Err(TryFromError::Overflow), _, None) => true,
_ => false,
}),
_ => TestResult::discard(),
}
}

let ok = match (t, v.to_u64()) {
(Ok(t), Some(u)) => {
let d = Duration::from_nanos(u);
let r = if d > t { d - t } else { t - d };

Duration::from_nanos(1) >= r
},
(Err(_), None) => true,
_ => false,
};

TestResult::from_bool(ok)
}

fn test_try_into(t: Result<Time<V>, TryFromError>, v: A<V>) -> TestResult {
if *v < V::zero() {
return TestResult::discard();
}

let ok = match t {
Ok(t) => {
let b = Time::new::<nanosecond>((*v).clone());
let d = if t > b { t - b } else { b - t };

d <= Time::new::<nanosecond>(V::from_u8(100).unwrap())
},
_ => false,
};

TestResult::from_bool(ok)
}
}
}
Loading