Skip to content

Commit

Permalink
Merge branch 'release/0.22.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
turboladen committed Mar 23, 2022
2 parents dff74d7 + 88ddea0 commit e0574a6
Show file tree
Hide file tree
Showing 26 changed files with 244 additions and 110 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ members = [
"definition_fetcher",
"ffi",
]
resolver = "2"
22 changes: 3 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,11 @@ terms. It's similar to Ruby's [unitwise](https://github.com/joshwlewis/unitwise)

## Prerequisites

* Rust 1.31
* Get it [here](https://rustup.rs/)
- Rust 1.56
- Get it [here](https://rustup.rs/)

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
wise_units = "0.14"
```

and this to your crate root:

```
extern crate wise_units;
```

_Note_: wise_units depends on the [pest](https://github.com/pest-parser/pest)
parser, which depends on Rust 1.23.

### Feature `serde`

wise_units provides the ability to (de)serialize `Measurement`s and its children
Expand All @@ -47,7 +31,7 @@ This feature is disabled by default. To enable it:
```toml
[dependencies]
wise_units = { version = "0.10", features = ["serde"] }
wise_units = { version = "0.22", features = ["serde"] }
```
## Examples
Expand Down
20 changes: 20 additions & 0 deletions api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.22.0] - 2022-03-23

### Added

- Implemented `AsRef<Self>` for `Measurement` and `Unit`. Allows for downstream wrapper types to
implement other functionality for all types via the `AsRef` implementation.
- Implemented `TryFrom<&str> for Unit` (which just calls `from_str()`) to allow for downstream
wrapper implementations around `Unit`.
- New `const` `Composition` methods: `new_dimless()`, `new_any()`.
- New `composition` `const`s for common dimensional compositions.

### Changed

- Exported `parser::composition` from the crate root.
- `Measurement::try_new()` now takes `unit: U`, `where Unit: TryFrom<U, crate::Error>`. This still
allows for passing in a unit expression as a `&str`, but also allows for any other
implementations of type conversions to `Unit`.
- Changed `AsFraction` trait definition to allow for non-optional `Numerator` and `Denominator`.
- Updated to Rust edition `2021`.

## [0.21.1] - 2021-11-19

### Changed
Expand Down
8 changes: 5 additions & 3 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "wise_units"
version = "0.21.1"
version = "0.22.0"
description = "Measure things using UCUM units"
repository = "https://github.com/agrian-inc/wise_units"
license = "MIT"
authors = ["Steve Loveless <steve@agrian.com>"]
edition = "2018"
edition = "2021"
publish = ["agrian-registry"]

[dependencies]
Expand All @@ -20,10 +20,12 @@ thiserror = "1.0"
bincode = "1.3"
criterion = "0.3"
lazy_static = "1.4"
rmp-serde = "0.15"
rmp-serde = "1.0"
serde_json = "1.0"

[features]
default = []

# Enables the C foreign function interface. Some types may become repr(C) under this flag, and an
# additional ffi module will be generated for each supported resource type.
cffi = ["ffi_common"]
Expand Down
6 changes: 3 additions & 3 deletions api/src/as_fraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ pub trait AsFraction {
type Denominator;
type Numerator;

fn as_fraction(&self) -> (Option<Self::Numerator>, Option<Self::Denominator>) {
fn as_fraction(&self) -> (Self::Numerator, Self::Denominator) {
(self.numerator(), self.denominator())
}

fn numerator(&self) -> Option<Self::Numerator>;
fn denominator(&self) -> Option<Self::Denominator>;
fn numerator(&self) -> Self::Numerator;
fn denominator(&self) -> Self::Denominator;
}
4 changes: 2 additions & 2 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub use crate::{
is_compatible_with::IsCompatibleWith,
measurement::Measurement,
parser::{
Atom, Classification, Composable, Composition, Dimension, Prefix, Property, Term,
UcumSymbol,
composition, Atom, Classification, Composable, Composition, Dimension, Prefix, Property,
Term, UcumSymbol,
},
ucum_unit::UcumUnit,
unit::Unit,
Expand Down
56 changes: 45 additions & 11 deletions api/src/measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ mod reducible;
mod to_reduced;
mod ucum_unit;

use crate::{error::Error, reducible::Reducible, ucum_unit::UcumUnit, unit::Unit};
use std::str::FromStr;
use crate::{reducible::Reducible, ucum_unit::UcumUnit, unit::Unit};

#[cfg(feature = "cffi")]
use ffi_common::derive::FFI;
Expand Down Expand Up @@ -43,19 +42,24 @@ pub struct Measurement {
}

impl Measurement {
/// Creates a new `Measurement` by parsing `expression` into a `Unit`.
/// Creates a new `Measurement` by converting `value` to an `f64` and `unit` to a `Unit`.
///
/// # Errors
///
/// Returns an `Error` if `expression` isn't one that represents a valid `Unit`.
/// Returns an `Error` if `unit` can't be converted to a `Unit`.
///
#[inline]
pub fn try_new(value: f64, expression: &str) -> Result<Self, Error> {
let unit = Unit::from_str(expression)?;

let m = Self { value, unit };

Ok(m)
pub fn try_new<V, U, E>(value: V, unit: U) -> Result<Self, E>
where
f64: From<V>,
Unit: TryFrom<U, Error = E>,
{
let unit = Unit::try_from(unit)?;

Ok(Self {
value: f64::from(value),
unit,
})
}

/// Standard constructor.
Expand Down Expand Up @@ -107,6 +111,12 @@ impl Measurement {
}
}

impl AsRef<Self> for Measurement {
fn as_ref(&self) -> &Self {
self
}
}

#[cfg(test)]
mod tests {
use super::{
Expand All @@ -115,7 +125,7 @@ mod tests {
};
use crate::unit::Unit;
use approx::{assert_relative_eq, assert_ulps_eq};
use std::str::FromStr;
use std::{convert::Infallible, str::FromStr};

#[test]
fn validate_new() {
Expand All @@ -124,6 +134,30 @@ mod tests {
assert_relative_eq!(m.value, 1.0);
assert_ulps_eq!(m.value, 1.0);
assert_eq!(m.unit, Unit::new(vec![term!(Meter)]));

let m = Measurement::try_new(1.0, Unit::from_str("m").unwrap()).unwrap();

assert_relative_eq!(m.value, 1.0);
assert_ulps_eq!(m.value, 1.0);
assert_eq!(m.unit, Unit::new(vec![term!(Meter)]));

{
struct Meter;

impl TryFrom<Meter> for Unit {
type Error = Infallible;

fn try_from(_value: Meter) -> Result<Self, Self::Error> {
Ok(Self::new(vec![Term::new(None, Some(Atom::Meter))]))
}
}

let m = Measurement::try_new(1.0, Meter).unwrap();

assert_relative_eq!(m.value, 1.0);
assert_ulps_eq!(m.value, 1.0);
assert_eq!(m.unit, Unit::new(vec![term!(Meter)]));
}
}

#[test]
Expand Down
16 changes: 14 additions & 2 deletions api/src/measurement/to_reduced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ mod tests {
use super::*;

macro_rules! validate_reduction {
($test_name:ident, $input_value:expr, $input_unit:expr, $expected_value:expr, $expected_unit:expr) => {
(
$test_name:ident,
$input_value:expr,
$input_unit:expr,
$expected_value:expr,
$expected_unit:expr
) => {
#[test]
fn $test_name() {
let measurement = Measurement::try_new($input_value, $input_unit).unwrap();
Expand Down Expand Up @@ -106,7 +112,13 @@ mod tests {
use crate::reduce::IntoReduced;

macro_rules! validate_reduction {
($test_name:ident, $input_value:expr, $input_unit:expr, $expected_value:expr, $expected_unit:expr) => {
(
$test_name:ident,
$input_value:expr,
$input_unit:expr,
$expected_value:expr,
$expected_unit:expr
) => {
#[test]
fn $test_name() {
let measurement = Measurement::try_new($input_value, $input_unit).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion api/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
)]
pub mod atom;
pub mod classification;
pub mod composition;
#[allow(clippy::non_ascii_literal)]
pub mod property;

Expand All @@ -20,7 +21,6 @@ mod annotation_composition;
#[cfg(test)]
mod atom_test;
mod composable;
mod composition;
mod definition;
mod dimension;
mod error;
Expand Down
16 changes: 8 additions & 8 deletions api/src/parser/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,15 +704,15 @@ impl Atom {
1.0,
"1",
Some(FunctionSet {
convert_from: |value: f64| value.ln(),
convert_to: |value: f64| value.exp(),
convert_from: f64::ln,
convert_to: f64::exp,
}),
),
Self::Bel => Definition::new(
1.0,
"1",
Some(FunctionSet {
convert_from: |value: f64| value.log10(),
convert_from: f64::log10,
convert_to: |value: f64| 10_f64.powf(value),
}),
),
Expand Down Expand Up @@ -760,15 +760,15 @@ impl Atom {
1.0,
"W",
Some(FunctionSet {
convert_from: |value: f64| value.log10(),
convert_from: f64::log10,
convert_to: |value: f64| 10_f64.powf(value),
}),
),
Self::BelKilowatt => Definition::new(
1.0,
"kW",
Some(FunctionSet {
convert_from: |value: f64| value.log10(),
convert_from: f64::log10,
convert_to: |value: f64| 10_f64.powf(value),
}),
),
Expand All @@ -787,16 +787,16 @@ impl Atom {
1.0,
"m2/s4/Hz",
Some(FunctionSet {
convert_from: |value: f64| value.sqrt(),
convert_from: f64::sqrt,
convert_to: |value: f64| value * value,
}),
),
Self::BitLogarithmusDualis => Definition::new(
1.0,
"1",
Some(FunctionSet {
convert_from: |value: f64| value.log2(),
convert_to: |value: f64| value.exp2(),
convert_from: f64::log2,
convert_to: f64::exp2,
}),
),
Self::Bit => Ok(Definition::default()),
Expand Down
Loading

0 comments on commit e0574a6

Please sign in to comment.