Skip to content

Commit

Permalink
Merge pull request #64 from telus-agcg/feature/NAUM-4-derive-missing-…
Browse files Browse the repository at this point in the history
…standard-traits

NAUM-4 Derive missing standard traits
  • Loading branch information
turboladen authored May 10, 2024
2 parents 4f3458e + c6c7f3d commit c876b4f
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 9 deletions.
6 changes: 5 additions & 1 deletion crates/api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- PLCC-287: `impl num_traits::NumCast for Measurement`.
- PLCC-287: `impl num_traits::Pow<i32> for Measurement`, `Unit`, `Term`.
- PLCC-287: `impl std::ops::Neg for Measurement`.
- NAUM-5: Added `crate::Term::as_cow_str()`.
- NAUM-4: Derive `PartialOrd` for `Composition`
- NAUM-4: `impl From<Dimension> for Composition`
- NAUM-4: Derive `Hash` for `Property`
- NAUM-4: `impl PartialOrd for Term`
- Added `Unit::into_terms()` for cases where you only need the `Term`s of the `Unit`.
- Added `unit` constant: `UNITY`
- Added `term` constants: `UNITY`, `UNITY_ARRAY`, and `UNITY_ARRAY_REF`.
- Added `measurement!()` macro for wrapping `Measurement::try_new().unwrap()`.
- Added `crate::term::Factor` type alias for `u32`.
- Added `crate::term::Exponent` type alias for `i32`.
- NAUM-5: Added `crate::Term::as_cow_str()`.
- (Internal) Added constants for many but not all internal `Definition`s.

### Changed
Expand Down
50 changes: 47 additions & 3 deletions crates/api/src/composition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub const SPECIFIC_HEAT: Composition =
///
/// For more info, see [https://en.wikipedia.org/wiki/Dimensional_analysis](https://en.wikipedia.org/wiki/Dimensional_analysis).
///
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Hash, Default)]
pub struct Composition {
electric_charge: Option<Exponent>,
length: Option<Exponent>,
Expand Down Expand Up @@ -314,7 +314,9 @@ impl Composition {
}
}

// impl Display
// ╭──────────────╮
// │ impl Display │
// ╰──────────────╯
impl fmt::Display for Composition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_empty() {
Expand Down Expand Up @@ -349,7 +351,9 @@ fn push_display_expression(
}
}

// impl Mul
// ╭──────────╮
// │ impl Mul │
// ╰──────────╯
/// Used for combining two `Compositions`.
///
#[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
Expand Down Expand Up @@ -435,6 +439,20 @@ const fn set_exponent(exponent: Exponent) -> Option<Exponent> {
}
}

impl From<Dimension> for Composition {
fn from(value: Dimension) -> Self {
match value {
Dimension::ElectricCharge => Self::new_electric_charge(1),
Dimension::Length => Self::new_length(1),
Dimension::LuminousIntensity => Self::new_luminous_intensity(1),
Dimension::Mass => Self::new_mass(1),
Dimension::PlaneAngle => Self::new_plane_angle(1),
Dimension::Temperature => Self::new_temperature(1),
Dimension::Time => Self::new_time(1),
}
}
}

#[cfg(test)]
mod tests {
use super::{super::Dimension, Composition};
Expand Down Expand Up @@ -718,4 +736,30 @@ mod tests {
let product = subject * -2;
assert_eq!(product.mass, Some(-4));
}

#[test]
fn from_dimension_test() {
assert_eq!(
Composition::from(Dimension::ElectricCharge),
Composition::new_electric_charge(1)
);
assert_eq!(
Composition::from(Dimension::Length),
Composition::new_length(1)
);
assert_eq!(
Composition::from(Dimension::LuminousIntensity),
Composition::new_luminous_intensity(1)
);
assert_eq!(Composition::from(Dimension::Mass), Composition::new_mass(1));
assert_eq!(
Composition::from(Dimension::PlaneAngle),
Composition::new_plane_angle(1)
);
assert_eq!(
Composition::from(Dimension::Temperature),
Composition::new_temperature(1)
);
assert_eq!(Composition::from(Dimension::Time), Composition::new_time(1));
}
}
2 changes: 1 addition & 1 deletion crates/api/src/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::fmt;
/// HTML spec, but is used throughout the
/// [XML description](http://unitsofmeasure.org/ucum-essence.xml).
///
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Property {
Acceleration,
Acidity,
Expand Down
1 change: 1 addition & 0 deletions crates/api/src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod invert;
mod is_compatible_with;
pub(crate) mod num_traits;
mod partial_eq;
mod partial_ord;
mod reducible;
mod ucum_unit;

Expand Down
6 changes: 2 additions & 4 deletions crates/api/src/term/partial_eq.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::{is_compatible_with::IsCompatibleWith, ucum_unit::UcumUnit, Term};
use approx::ulps_eq;

//-----------------------------------------------------------------------------
// impl PartialEq
//-----------------------------------------------------------------------------
use crate::{is_compatible_with::IsCompatibleWith, ucum_unit::UcumUnit, Term};

/// `Term`s are `PartialEq` if
///
/// a) they are compatible
Expand Down
69 changes: 69 additions & 0 deletions crates/api/src/term/partial_ord.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::{is_compatible_with::IsCompatibleWith, ucum_unit::UcumUnit, Term};

/// `Term`s are `PartialOrd` if
///
/// a) they are compatible
/// b) their `scalar()` values are comparable
///
/// ```rust
/// use std::cmp::Ordering;
/// use wise_units::{Atom, Prefix, Term};
///
/// let lhs = Term {
/// factor: Some(1000),
/// prefix: None,
/// atom: Some(Atom::Meter),
/// exponent: None,
/// annotation: None
/// };
/// let rhs = Term {
/// factor: None,
/// prefix: Some(Prefix::Kilo),
/// atom: Some(Atom::Meter),
/// exponent: None,
/// annotation: None
/// };
/// assert_eq!(lhs.partial_cmp(&rhs), Some(Ordering::Equal));
///
/// let lhs = Term {
/// factor: None,
/// prefix: None,
/// atom: Some(Atom::Meter),
/// exponent: None,
/// annotation: None
/// };
/// let rhs = Term {
/// factor: None,
/// prefix: Some(Prefix::Kilo),
/// atom: Some(Atom::Meter),
/// exponent: None,
/// annotation: None
/// };
/// assert_eq!(lhs.partial_cmp(&rhs), Some(Ordering::Less));
///
/// let lhs = Term {
/// factor: None,
/// prefix: None,
/// atom: Some(Atom::Meter),
/// exponent: None,
/// annotation: None
/// };
/// let rhs = Term {
/// factor: None,
/// prefix: None,
/// atom: Some(Atom::Gram),
/// exponent: None,
/// annotation: None
/// };
/// assert_eq!(lhs.partial_cmp(&rhs), None);
/// ```
///
impl PartialOrd for Term {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if !self.is_compatible_with(other) {
return None;
}

self.scalar().partial_cmp(&other.scalar())
}
}

0 comments on commit c876b4f

Please sign in to comment.