Skip to content

Commit

Permalink
Add new Measurement mul/div test & fix reduction impl
Browse files Browse the repository at this point in the history
  • Loading branch information
turboladen committed Aug 27, 2024
1 parent f05968e commit eb24192
Show file tree
Hide file tree
Showing 28 changed files with 1,682 additions and 846 deletions.
64 changes: 63 additions & 1 deletion crates/api/src/annotation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use std::fmt;

use crate::{Composable, IsCompatibleWith, Term};
use crate::{
composable::ComposablyEq,
term::{
variants::{FactorAnnotation, FactorExponentAnnotation},
Exponent,
},
Composable, IsCompatibleWith, Term,
};

#[derive(Default, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Annotation(String);
Expand Down Expand Up @@ -33,6 +40,47 @@ where
}
}

impl ComposablyEq<Term> for Annotation {
fn composably_eq(&self, rhs: &Term) -> Option<Exponent> {
match rhs {
Term::Annotation(inner) => self.composably_eq(inner),
Term::FactorAnnotation(inner) => self.composably_eq(inner),
Term::FactorExponentAnnotation(inner) => self.composably_eq(inner),
_ => None,
}
}
}

impl ComposablyEq<Self> for Annotation {
fn composably_eq(&self, rhs: &Self) -> Option<Exponent> {
if self == rhs {
Some(2)
} else {
None
}
}
}

impl ComposablyEq<FactorAnnotation> for Annotation {
fn composably_eq(&self, rhs: &FactorAnnotation) -> Option<Exponent> {
if rhs.factor == 1 && self == &rhs.annotation {
Some(2)
} else {
None
}
}
}

impl ComposablyEq<FactorExponentAnnotation> for Annotation {
fn composably_eq(&self, rhs: &FactorExponentAnnotation) -> Option<Exponent> {
if rhs.factor == 1 && self == &rhs.annotation {
Some(1 + rhs.exponent)
} else {
None
}
}
}

impl Composable for Annotation {
fn composition(&self) -> crate::Composition {
crate::Composition::new_dimless()
Expand All @@ -44,3 +92,17 @@ impl IsCompatibleWith<Term> for Annotation {
self.composition() == rhs.composition() && Some(self.as_str()) == rhs.annotation()
}
}

impl crate::term::term_reduce::TermReduce for Annotation {
fn build(&self, exponent: Exponent) -> Term {
if exponent == 1 {
Term::Annotation(self.clone())
} else {
Term::FactorExponentAnnotation(FactorExponentAnnotation {
factor: 1,
exponent,
annotation: self.clone(),
})
}
}
}
61 changes: 60 additions & 1 deletion crates/api/src/atom/composable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use crate::{Atom, Composable, Composition, Dimension};
use crate::{
composable::ComposablyEq,
term::{
variants::{AtomExponent, FactorAtom, FactorAtomExponent},
Exponent,
},
Atom, Composable, Composition, Dimension, Term,
};

impl Composable for Atom {
fn composition(&self) -> Composition {
Expand All @@ -14,3 +21,55 @@ impl Composable for Atom {
}
}
}

impl ComposablyEq<Term> for Atom {
fn composably_eq(&self, rhs: &Term) -> Option<Exponent> {
match rhs {
Term::Atom(inner) => self.composably_eq(inner),
Term::AtomExponent(inner) => self.composably_eq(inner),
Term::FactorAtom(inner) => self.composably_eq(inner),
Term::FactorAtomExponent(inner) => self.composably_eq(inner),
_ => None,
}
}
}

impl ComposablyEq<Self> for Atom {
fn composably_eq(&self, rhs: &Self) -> Option<Exponent> {
if self == rhs {
Some(2)
} else {
None
}
}
}

impl ComposablyEq<AtomExponent> for Atom {
fn composably_eq(&self, rhs: &AtomExponent) -> Option<Exponent> {
if *self == rhs.atom {
Some(1 + rhs.exponent)
} else {
None
}
}
}

impl ComposablyEq<FactorAtom> for Atom {
fn composably_eq(&self, rhs: &FactorAtom) -> Option<Exponent> {
if rhs.factor == 1 && *self == rhs.atom {
Some(2)
} else {
None
}
}
}

impl ComposablyEq<FactorAtomExponent> for Atom {
fn composably_eq(&self, rhs: &FactorAtomExponent) -> Option<Exponent> {
if rhs.factor == 1 && *self == rhs.atom {
Some(1 + rhs.exponent)
} else {
None
}
}
}
4 changes: 2 additions & 2 deletions crates/api/src/composable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ pub trait Composable {
/// - `m2{foo}` and `m2` are _not_ `ComposablyEq`.
/// - `km{foo}` and `km` are _not_ `ComposablyEq`.
///
pub(crate) trait ComposablyEq {
fn composably_eq(&self, rhs: &crate::Term) -> bool;
pub(crate) trait ComposablyEq<T> {
fn composably_eq(&self, rhs: &T) -> Option<crate::term::Exponent>;
}
52 changes: 37 additions & 15 deletions crates/api/src/measurement/ops/mul_div.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ mod tests {
validate_same_unit!(
parse_unit!("{tree}"),
mul_unit: unit!(term!(factor: 1, exponent: 2, annotation: "tree")),
div_unit: parse_unit!("{tree}")
div_unit: UNITY
);

// TODO: https://telusagriculture.atlassian.net/browse/NAUM-122
Expand Down Expand Up @@ -496,14 +496,14 @@ mod tests {
validate_same_unit!(
parse_unit!("m{foo}"),
mul_unit: parse_unit!("m2{foo}"),
div_unit: parse_unit!("{foo}")
div_unit: UNITY
);

validate_same_unit!(
validate_same_dimless,
parse_unit!("[ppth]{foo}"),
mul_unit: parse_unit!("[ppth]2{foo}"),
div_unit: parse_unit!("{foo}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -562,14 +562,14 @@ mod tests {
validate_same_unit!(
parse_unit!("m2{dirt}"),
mul_unit: parse_unit!("m4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);

validate_same_unit!(
validate_same_dimless,
parse_unit!("[ppth]2{dirt}"),
mul_unit: parse_unit!("[ppth]4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -616,7 +616,7 @@ mod tests {
validate_same_unit!(
parse_unit!("km{dirt}"),
mul_unit: parse_unit!("km2{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);
}

Expand All @@ -643,7 +643,7 @@ mod tests {
validate_same_unit!(
parse_unit!("km2{dirt}"),
mul_unit: parse_unit!("km4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);
}

Expand Down Expand Up @@ -675,7 +675,7 @@ mod tests {
validate_same_unit!(
parse_unit!("2{rabbit}"),
mul_unit: unit!(term!(factor: 2, exponent: 2, annotation: "rabbit")),
div_unit: parse_unit!("{rabbit}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -727,7 +727,7 @@ mod tests {
validate_same_unit!(
unit!(term!(factor: 2, exponent: 2, annotation: "rabbit")),
mul_unit: unit!(term!(factor: 2, exponent: 4, annotation: "rabbit")),
div_unit: parse_unit!("{rabbit}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -804,14 +804,14 @@ mod tests {
validate_same_unit!(
parse_unit!("2m{raisin}"),
mul_unit: parse_unit!("2m2{raisin}"),
div_unit: parse_unit!("{raisin}")
div_unit: UNITY
);

validate_same_unit!(
validate_same_dimless,
parse_unit!("2[ppth]{foo}"),
mul_unit: parse_unit!("2[ppth]2{foo}"),
div_unit: parse_unit!("{foo}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -870,14 +870,14 @@ mod tests {
validate_same_unit!(
parse_unit!("2m2{dirt}"),
mul_unit: parse_unit!("2m4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);

validate_same_unit!(
validate_same_dimless,
parse_unit!("2[ppth]2{dirt}"),
mul_unit: parse_unit!("2[ppth]4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);

validate_dim_and_dimless!(
Expand Down Expand Up @@ -924,7 +924,7 @@ mod tests {
validate_same_unit!(
parse_unit!("2km{string}"),
mul_unit: parse_unit!("2km2{string}"),
div_unit: parse_unit!("{string}")
div_unit: UNITY
);
}

Expand All @@ -951,7 +951,29 @@ mod tests {
validate_same_unit!(
parse_unit!("2km2{dirt}"),
mul_unit: parse_unit!("2km4{dirt}"),
div_unit: parse_unit!("{dirt}")
div_unit: UNITY
);
}

mod combinations {
use super::*;

validate_ok!(
same_annotation_in_numerator_and_denominator,
parse_unit!("{meow}/m2"), parse_unit!("g/{meow}"),
mul_values: 2.0, 2.0,
mul_unit: parse_unit!("g/m2"),
div_values: 0.5, 2.0,
div_unit1: unit!(
term!(factor: 1, exponent: 2, annotation: "meow"),
term!(Gram, exponent: -1),
term!(Meter, exponent: -2)
),
div_unit2: unit!(
term!(factor: 1, exponent: -2, annotation: "meow"),
term!(Gram),
term!(Meter, exponent: 2)
)
);
}
}
2 changes: 1 addition & 1 deletion crates/api/src/term.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
mod annotation_composable;
mod builder;
mod composable;
mod composably_eq;
mod display;
mod field_eq;
mod invert;
Expand All @@ -10,6 +9,7 @@ pub(crate) mod num_traits;
mod partial_eq;
mod partial_ord;
mod reducible;
pub(crate) mod term_reduce;
mod ucum_unit;
#[cfg(feature = "v2")]
mod v2;
Expand Down
48 changes: 46 additions & 2 deletions crates/api/src/term/composable.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::borrow::Cow;

use crate::{Composable, Composition};
use crate::{composable::ComposablyEq, term::variants::FactorExponent, Composable, Composition};

use super::Term;
use super::{Exponent, Term};

impl Composable for Term {
/// Combines the `Composition` from the `Term`'s `Atom` with its own `exponent` to build a
Expand Down Expand Up @@ -45,6 +45,50 @@ impl<'a> Composable for Cow<'a, [Term]> {
}
}

impl ComposablyEq<Self> for Term {
fn composably_eq(&self, rhs: &Self) -> Option<Exponent> {
match self {
Self::Annotation(lhs_annotation) => lhs_annotation.composably_eq(rhs),
Self::Atom(lhs_atom) => lhs_atom.composably_eq(rhs),
Self::AtomAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::AtomExponent(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::AtomExponentAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::PrefixAtom(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::PrefixAtomAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::PrefixAtomExponent(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::PrefixAtomExponentAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::Factor(lhs_factor) => match rhs {
Self::Factor(factor) => {
if lhs_factor == factor {
Some(2)
} else {
None
}
}
Self::FactorExponent(FactorExponent { factor, exponent }) => {
if lhs_factor == factor {
Some(exponent + 1)
} else {
None
}
}
_ => None,
},
Self::FactorAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorExponent(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorExponentAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorAtom(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorAtomAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorAtomExponent(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorAtomExponentAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorPrefixAtom(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorPrefixAtomAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorPrefixAtomExponent(lhs_inner) => lhs_inner.composably_eq(rhs),
Self::FactorPrefixAtomExponentAnnotation(lhs_inner) => lhs_inner.composably_eq(rhs),
}
}
}

#[cfg(test)]
mod tests {
use crate::Dimension;
Expand Down
Loading

0 comments on commit eb24192

Please sign in to comment.