From e55a83d1a9af68e53287bd344d9c03e7437f8d90 Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Thu, 29 Jan 2026 16:20:06 -0500 Subject: [PATCH 1/6] typo --- rust/bambam-omf/src/graph/segment_split.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/bambam-omf/src/graph/segment_split.rs b/rust/bambam-omf/src/graph/segment_split.rs index 486520a..7895085 100644 --- a/rust/bambam-omf/src/graph/segment_split.rs +++ b/rust/bambam-omf/src/graph/segment_split.rs @@ -222,7 +222,7 @@ impl SegmentSplit { Some(h) if h == heading => true, _ => false, }, - None => false, + None => true, }) .collect_vec(); From 3ac9be4e66a918f8fab86a0508d855d0d4b4aa64 Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Thu, 29 Jan 2026 16:23:00 -0500 Subject: [PATCH 2/6] added WhenVehicle access restriction logic --- rust/bambam-omf/src/collection/filter/mod.rs | 2 +- rust/bambam-omf/src/collection/record/mod.rs | 9 +- .../record/transportation_segment.rs | 93 +++++++++++- rust/bambam-omf/src/graph/segment_ops.rs | 138 +++++++++++++++++- 4 files changed, 229 insertions(+), 13 deletions(-) diff --git a/rust/bambam-omf/src/collection/filter/mod.rs b/rust/bambam-omf/src/collection/filter/mod.rs index d55c5ae..0ed7d66 100644 --- a/rust/bambam-omf/src/collection/filter/mod.rs +++ b/rust/bambam-omf/src/collection/filter/mod.rs @@ -10,4 +10,4 @@ mod travel_mode_filter; pub use bbox::Bbox; pub use row_filter::RowFilter; pub use row_filter_config::RowFilterConfig; -pub use travel_mode_filter::TravelModeFilter; +pub use travel_mode_filter::{MatchBehavior, TravelModeFilter}; diff --git a/rust/bambam-omf/src/collection/record/mod.rs b/rust/bambam-omf/src/collection/record/mod.rs index 6b896f1..25a671d 100644 --- a/rust/bambam-omf/src/collection/record/mod.rs +++ b/rust/bambam-omf/src/collection/record/mod.rs @@ -15,10 +15,11 @@ pub use record_type::OvertureRecordType; pub use transportation_collection::TransportationCollection; pub use transportation_connector::TransportationConnectorRecord; pub use transportation_segment::{ - SegmentAccessRestriction, SegmentAccessRestrictionWhen, SegmentAccessType, SegmentClass, - SegmentDestination, SegmentFullType, SegmentHeading, SegmentMode, SegmentRecognized, - SegmentSpeedLimit, SegmentSpeedUnit, SegmentSubclass, SegmentSubtype, SegmentUsing, - TransportationSegmentRecord, + SegmentAccessRestriction, SegmentAccessRestrictionWhen, SegmentAccessRestrictionWhenVehicle, + SegmentAccessType, SegmentClass, SegmentDestination, SegmentFullType, SegmentHeading, + SegmentLengthUnit, SegmentMode, SegmentRecognized, SegmentSpeedLimit, SegmentSpeedUnit, + SegmentSubclass, SegmentSubtype, SegmentUnit, SegmentUsing, SegmentVehicleComparator, + SegmentVehicleDimension, TransportationSegmentRecord, }; // Common structs and functions for many record types diff --git a/rust/bambam-omf/src/collection/record/transportation_segment.rs b/rust/bambam-omf/src/collection/record/transportation_segment.rs index 196e97f..e1cc0bd 100644 --- a/rust/bambam-omf/src/collection/record/transportation_segment.rs +++ b/rust/bambam-omf/src/collection/record/transportation_segment.rs @@ -1,7 +1,7 @@ use std::fmt::{self, Debug}; use geo::{Coord, Geometry, Haversine, InterpolatableLine, Length, LineString}; -use routee_compass_core::model::unit::SpeedUnit; +use routee_compass_core::model::unit::{DistanceUnit, SpeedUnit, WeightUnit}; use serde::{Deserialize, Serialize}; use uom::si::f64::Velocity; @@ -421,6 +421,18 @@ pub enum SegmentVehicleComparator { LessThanEqual, } +impl SegmentVehicleComparator { + pub fn apply(&self, value: f64, restriction: f64) -> bool { + match self { + SegmentVehicleComparator::GreaterThan => value > restriction, + SegmentVehicleComparator::GreaterThanEqual => value >= restriction, + SegmentVehicleComparator::Equal => value == restriction, + SegmentVehicleComparator::LessThan => value < restriction, + SegmentVehicleComparator::LessThanEqual => value <= restriction, + } + } +} + /// units in vehicle restrictions which may be length or weight units. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[serde(untagged)] @@ -447,6 +459,20 @@ pub enum SegmentLengthUnit { Kilometer, } +impl SegmentLengthUnit { + pub fn to_uom(&self, value: f64) -> uom::si::f64::Length { + match self { + SegmentLengthUnit::Inches => DistanceUnit::Inches.to_uom(value), + SegmentLengthUnit::Feet => DistanceUnit::Feet.to_uom(value), + SegmentLengthUnit::Yard => DistanceUnit::Meters.to_uom(value * 0.9144), + SegmentLengthUnit::Mile => DistanceUnit::Miles.to_uom(value), + SegmentLengthUnit::Centimeter => DistanceUnit::Meters.to_uom(value / 100.), + SegmentLengthUnit::Meter => DistanceUnit::Meters.to_uom(value), + SegmentLengthUnit::Kilometer => DistanceUnit::Kilometers.to_uom(value), + } + } +} + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[serde(untagged)] pub enum SegmentWeightUnit { @@ -454,6 +480,28 @@ pub enum SegmentWeightUnit { Metric(SegmentMetricWeightUnit), } +impl SegmentWeightUnit { + pub fn to_uom(&self, value: f64) -> uom::si::f64::Mass { + match self { + SegmentWeightUnit::Imperial(segment_imperial_weight_unit) => { + match segment_imperial_weight_unit { + SegmentImperialWeightUnit::Ounce => WeightUnit::Kg.to_uom(value * 0.0283495), + SegmentImperialWeightUnit::Pound => WeightUnit::Pounds.to_uom(value * 0.453592), + SegmentImperialWeightUnit::Stone => WeightUnit::Kg.to_uom(value * 6.350288), + SegmentImperialWeightUnit::LongTon => WeightUnit::Kg.to_uom(value * 1016.05), + } + } + SegmentWeightUnit::Metric(segment_metric_weight_unit) => { + match segment_metric_weight_unit { + SegmentMetricWeightUnit::Gram => WeightUnit::Kg.to_uom(value * 0.001), + SegmentMetricWeightUnit::Kilogram => WeightUnit::Kg.to_uom(value), + SegmentMetricWeightUnit::MetricTon => WeightUnit::Kg.to_uom(value * 1000.), + } + } + } + } +} + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] pub enum SegmentImperialWeightUnit { @@ -625,11 +673,44 @@ impl SegmentAccessRestrictionWhen { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct SegmentAccessRestrictionWhenVehicle { - dimension: SegmentVehicleDimension, - comparison: SegmentVehicleComparator, - value: f64, - #[serde(skip_serializing_if = "Option::is_none", default)] - unit: Option, + pub dimension: SegmentVehicleDimension, + pub comparison: SegmentVehicleComparator, + pub value: f64, + #[serde(skip_serializing_if = "Option::is_none", default)] + pub unit: Option, +} + +impl SegmentAccessRestrictionWhenVehicle { + /// returns true if the value and unit provided would pass the restriction + /// based on the comparison logic + pub fn is_valid(&self, value: f64, unit: Option<&SegmentUnit>) -> bool { + match (&self.unit, unit) { + (Some(this_unit), Some(other_unit)) => { + let this_value_f64 = match this_unit { + SegmentUnit::Length(segment_length_unit) => segment_length_unit + .to_uom(self.value) + .get::(), + SegmentUnit::Weight(segment_weight_unit) => segment_weight_unit + .to_uom(self.value) + .get::(), + }; + + let other_value_f64 = match other_unit { + SegmentUnit::Length(segment_length_unit) => segment_length_unit + .to_uom(value) + .get::(), + SegmentUnit::Weight(segment_weight_unit) => segment_weight_unit + .to_uom(value) + .get::(), + }; + + self.comparison.apply(other_value_f64, this_value_f64) + } + + // If we miss any unit, check the raw values + _ => self.comparison.apply(value, self.value), + } + } } /// Describes objects that can be reached by following a transportation diff --git a/rust/bambam-omf/src/graph/segment_ops.rs b/rust/bambam-omf/src/graph/segment_ops.rs index 74b2bbd..70fbdd2 100644 --- a/rust/bambam-omf/src/graph/segment_ops.rs +++ b/rust/bambam-omf/src/graph/segment_ops.rs @@ -219,6 +219,23 @@ fn when_is_compatible( } } + // Check vehicle dimension filters + if let Some(restrictions_vehicle) = &restrictions.vehicle { + let all_restrictions_apply_to_all_vehicles = restrictions_vehicle.iter().all(|r_vehicle| { + if let Some(when_vehicles) = &when.vehicle { + when_vehicles + .iter() + .all(|w_vehicle| r_vehicle.is_valid(w_vehicle.value, w_vehicle.unit.as_ref())) + } else { + false + } + }); + + if !all_restrictions_apply_to_all_vehicles { + return false; + } + } + // If we got here, all specified fields in when are compatible true } @@ -226,8 +243,14 @@ fn when_is_compatible( #[cfg(test)] mod tests { use super::*; - use crate::collection::record::{ - OvertureMapsBbox, SegmentAccessType, SegmentMode, SegmentRecognized, SegmentUsing, + use crate::collection::{ + filter::{MatchBehavior, TravelModeFilter}, + record::{ + OvertureMapsBbox, SegmentAccessRestrictionWhenVehicle, SegmentAccessType, + SegmentLengthUnit, SegmentMode, SegmentRecognized, SegmentUnit, SegmentUsing, + SegmentVehicleComparator, SegmentVehicleDimension, + }, + SegmentClass, }; #[test] @@ -576,6 +599,98 @@ mod tests { assert_eq!(result2.len(), 0); } + #[test] + fn test_from_data_3() { + let access_restrictions = vec![ + create_restriction_mode(SegmentAccessType::Designated, vec![SegmentMode::Hgv]), + create_restriction_when_vehicle( + SegmentAccessType::Denied, + SegmentAccessRestrictionWhenVehicle { + dimension: SegmentVehicleDimension::Height, + comparison: SegmentVehicleComparator::GreaterThan, + value: 13.0, + unit: Some(SegmentUnit::Length(SegmentLengthUnit::Feet)), + }, + ), + ]; + + let segment = create_test_segment(Some(access_restrictions)); + + // Should pass simple drive filter + let filter1 = create_simple_drive_filter(); + assert!(filter1.matches_filter(&segment)); + + // Should be denied when vehicle height is greater than 13 ft + let when1 = SegmentAccessRestrictionWhen { + during: None, + heading: Some(SegmentHeading::Forward), + using: None, + recognized: None, + mode: None, + vehicle: Some(vec![SegmentAccessRestrictionWhenVehicle { + dimension: SegmentVehicleDimension::Height, + comparison: SegmentVehicleComparator::GreaterThan, + value: 100.0, + unit: Some(SegmentUnit::Length(SegmentLengthUnit::Feet)), + }]), + }; + let result1 = get_headings(&segment, Some(&when1)).unwrap(); + assert_eq!(result1.len(), 0); + + // But should be allowed in any other case + let when2 = SegmentAccessRestrictionWhen { + during: None, + heading: Some(SegmentHeading::Forward), + using: None, + recognized: None, + mode: None, + vehicle: Some(vec![SegmentAccessRestrictionWhenVehicle { + dimension: SegmentVehicleDimension::Height, + comparison: SegmentVehicleComparator::GreaterThan, + value: 10., + unit: Some(SegmentUnit::Length(SegmentLengthUnit::Feet)), + }]), + }; + let result2 = get_headings(&segment, Some(&when2)).unwrap(); + assert_eq!(result2, vec![SegmentHeading::Forward]); + + // also when no vehicle is specified + let when3 = SegmentAccessRestrictionWhen { + during: None, + heading: Some(SegmentHeading::Forward), + using: None, + recognized: None, + mode: None, + vehicle: None, + }; + let result3 = get_headings(&segment, Some(&when3)).unwrap(); + assert_eq!(result3, vec![SegmentHeading::Forward]); + } + + // Helper to represent a typical drive mode filter + fn create_simple_drive_filter() -> TravelModeFilter { + let classes = vec![ + SegmentClass::Motorway, + SegmentClass::Trunk, + SegmentClass::Primary, + SegmentClass::Secondary, + SegmentClass::Tertiary, + SegmentClass::Residential, + SegmentClass::LivingStreet, + SegmentClass::Unclassified, + SegmentClass::Service, + SegmentClass::Unknown, + ] + .into_iter() + .collect(); + + TravelModeFilter::MatchesClasses { + classes: classes, + behavior: MatchBehavior::Include, + allow_unset: true, + } + } + /// Helper to create a minimal segment for testing fn create_test_segment( access_restrictions: Option>, @@ -648,6 +763,25 @@ mod tests { } } + /// Helpter to create a simple access restriction with vehicle detail + fn create_restriction_when_vehicle( + access_type: SegmentAccessType, + vehicle: SegmentAccessRestrictionWhenVehicle, + ) -> SegmentAccessRestriction { + SegmentAccessRestriction { + access_type, + when: Some(SegmentAccessRestrictionWhen { + during: None, + heading: None, + using: None, + recognized: None, + mode: None, + vehicle: Some(vec![vehicle]), + }), + vehicle: None, + } + } + /// Helper to create "Denied all + Allowed specific" pattern for a heading fn create_denied_all_allowed_specific( heading: SegmentHeading, From e7885be6641ce25593e6eb8276210dad19fb3637 Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Thu, 29 Jan 2026 16:31:38 -0500 Subject: [PATCH 3/6] add logic to handle incompatible dimension queries (height vs weight for example) --- .../collection/record/transportation_segment.rs | 16 ++++++++++------ rust/bambam-omf/src/graph/segment_ops.rs | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/rust/bambam-omf/src/collection/record/transportation_segment.rs b/rust/bambam-omf/src/collection/record/transportation_segment.rs index e1cc0bd..f579fd7 100644 --- a/rust/bambam-omf/src/collection/record/transportation_segment.rs +++ b/rust/bambam-omf/src/collection/record/transportation_segment.rs @@ -681,10 +681,14 @@ pub struct SegmentAccessRestrictionWhenVehicle { } impl SegmentAccessRestrictionWhenVehicle { - /// returns true if the value and unit provided would pass the restriction + /// returns true if the when provided would pass the restriction /// based on the comparison logic - pub fn is_valid(&self, value: f64, unit: Option<&SegmentUnit>) -> bool { - match (&self.unit, unit) { + pub fn is_valid(&self, when: &SegmentAccessRestrictionWhenVehicle) -> bool { + if when.dimension != self.dimension { + return false; + } + + match (&self.unit, &when.unit) { (Some(this_unit), Some(other_unit)) => { let this_value_f64 = match this_unit { SegmentUnit::Length(segment_length_unit) => segment_length_unit @@ -697,10 +701,10 @@ impl SegmentAccessRestrictionWhenVehicle { let other_value_f64 = match other_unit { SegmentUnit::Length(segment_length_unit) => segment_length_unit - .to_uom(value) + .to_uom(when.value) .get::(), SegmentUnit::Weight(segment_weight_unit) => segment_weight_unit - .to_uom(value) + .to_uom(when.value) .get::(), }; @@ -708,7 +712,7 @@ impl SegmentAccessRestrictionWhenVehicle { } // If we miss any unit, check the raw values - _ => self.comparison.apply(value, self.value), + _ => self.comparison.apply(when.value, self.value), } } } diff --git a/rust/bambam-omf/src/graph/segment_ops.rs b/rust/bambam-omf/src/graph/segment_ops.rs index 70fbdd2..2f9e6b6 100644 --- a/rust/bambam-omf/src/graph/segment_ops.rs +++ b/rust/bambam-omf/src/graph/segment_ops.rs @@ -225,7 +225,7 @@ fn when_is_compatible( if let Some(when_vehicles) = &when.vehicle { when_vehicles .iter() - .all(|w_vehicle| r_vehicle.is_valid(w_vehicle.value, w_vehicle.unit.as_ref())) + .all(|w_vehicle| r_vehicle.is_valid(w_vehicle)) } else { false } @@ -685,7 +685,7 @@ mod tests { .collect(); TravelModeFilter::MatchesClasses { - classes: classes, + classes, behavior: MatchBehavior::Include, allow_unset: true, } From b816e21326d9eab8460a9fb348b296b0398d5705 Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Thu, 29 Jan 2026 16:33:05 -0500 Subject: [PATCH 4/6] fix pounds value --- rust/bambam-omf/src/collection/record/transportation_segment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/bambam-omf/src/collection/record/transportation_segment.rs b/rust/bambam-omf/src/collection/record/transportation_segment.rs index f579fd7..0df4ece 100644 --- a/rust/bambam-omf/src/collection/record/transportation_segment.rs +++ b/rust/bambam-omf/src/collection/record/transportation_segment.rs @@ -486,7 +486,7 @@ impl SegmentWeightUnit { SegmentWeightUnit::Imperial(segment_imperial_weight_unit) => { match segment_imperial_weight_unit { SegmentImperialWeightUnit::Ounce => WeightUnit::Kg.to_uom(value * 0.0283495), - SegmentImperialWeightUnit::Pound => WeightUnit::Pounds.to_uom(value * 0.453592), + SegmentImperialWeightUnit::Pound => WeightUnit::Pounds.to_uom(value), SegmentImperialWeightUnit::Stone => WeightUnit::Kg.to_uom(value * 6.350288), SegmentImperialWeightUnit::LongTon => WeightUnit::Kg.to_uom(value * 1016.05), } From ad0826771b218fd1fbbadcfa3c04a6bc23fbfb8e Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Thu, 29 Jan 2026 16:33:35 -0500 Subject: [PATCH 5/6] typo --- rust/bambam-omf/src/graph/segment_ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/bambam-omf/src/graph/segment_ops.rs b/rust/bambam-omf/src/graph/segment_ops.rs index 2f9e6b6..daa659a 100644 --- a/rust/bambam-omf/src/graph/segment_ops.rs +++ b/rust/bambam-omf/src/graph/segment_ops.rs @@ -763,7 +763,7 @@ mod tests { } } - /// Helpter to create a simple access restriction with vehicle detail + /// Helper to create a simple access restriction with vehicle detail fn create_restriction_when_vehicle( access_type: SegmentAccessType, vehicle: SegmentAccessRestrictionWhenVehicle, From 3bb555091ff923904b29ffe5c99af53bc723fc61 Mon Sep 17 00:00:00 2001 From: Yamil Essus Date: Fri, 30 Jan 2026 12:07:48 -0500 Subject: [PATCH 6/6] PR feedback --- .../record/transportation_segment.rs | 87 ++++++++++--------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/rust/bambam-omf/src/collection/record/transportation_segment.rs b/rust/bambam-omf/src/collection/record/transportation_segment.rs index 0df4ece..06a40c6 100644 --- a/rust/bambam-omf/src/collection/record/transportation_segment.rs +++ b/rust/bambam-omf/src/collection/record/transportation_segment.rs @@ -1,7 +1,7 @@ use std::fmt::{self, Debug}; use geo::{Coord, Geometry, Haversine, InterpolatableLine, Length, LineString}; -use routee_compass_core::model::unit::{DistanceUnit, SpeedUnit, WeightUnit}; +use routee_compass_core::model::unit::SpeedUnit; use serde::{Deserialize, Serialize}; use uom::si::f64::Velocity; @@ -462,13 +462,17 @@ pub enum SegmentLengthUnit { impl SegmentLengthUnit { pub fn to_uom(&self, value: f64) -> uom::si::f64::Length { match self { - SegmentLengthUnit::Inches => DistanceUnit::Inches.to_uom(value), - SegmentLengthUnit::Feet => DistanceUnit::Feet.to_uom(value), - SegmentLengthUnit::Yard => DistanceUnit::Meters.to_uom(value * 0.9144), - SegmentLengthUnit::Mile => DistanceUnit::Miles.to_uom(value), - SegmentLengthUnit::Centimeter => DistanceUnit::Meters.to_uom(value / 100.), - SegmentLengthUnit::Meter => DistanceUnit::Meters.to_uom(value), - SegmentLengthUnit::Kilometer => DistanceUnit::Kilometers.to_uom(value), + SegmentLengthUnit::Inches => uom::si::f64::Length::new::(value), + SegmentLengthUnit::Feet => uom::si::f64::Length::new::(value), + SegmentLengthUnit::Yard => uom::si::f64::Length::new::(value), + SegmentLengthUnit::Mile => uom::si::f64::Length::new::(value), + SegmentLengthUnit::Centimeter => { + uom::si::f64::Length::new::(value) + } + SegmentLengthUnit::Meter => uom::si::f64::Length::new::(value), + SegmentLengthUnit::Kilometer => { + uom::si::f64::Length::new::(value) + } } } } @@ -482,22 +486,21 @@ pub enum SegmentWeightUnit { impl SegmentWeightUnit { pub fn to_uom(&self, value: f64) -> uom::si::f64::Mass { + use SegmentImperialWeightUnit as I; + use SegmentMetricWeightUnit as M; + use SegmentWeightUnit as SWU; + match self { - SegmentWeightUnit::Imperial(segment_imperial_weight_unit) => { - match segment_imperial_weight_unit { - SegmentImperialWeightUnit::Ounce => WeightUnit::Kg.to_uom(value * 0.0283495), - SegmentImperialWeightUnit::Pound => WeightUnit::Pounds.to_uom(value), - SegmentImperialWeightUnit::Stone => WeightUnit::Kg.to_uom(value * 6.350288), - SegmentImperialWeightUnit::LongTon => WeightUnit::Kg.to_uom(value * 1016.05), - } - } - SegmentWeightUnit::Metric(segment_metric_weight_unit) => { - match segment_metric_weight_unit { - SegmentMetricWeightUnit::Gram => WeightUnit::Kg.to_uom(value * 0.001), - SegmentMetricWeightUnit::Kilogram => WeightUnit::Kg.to_uom(value), - SegmentMetricWeightUnit::MetricTon => WeightUnit::Kg.to_uom(value * 1000.), - } + SWU::Imperial(I::Ounce) => uom::si::f64::Mass::new::(value), + SWU::Imperial(I::Pound) => uom::si::f64::Mass::new::(value), + // Couldn't find "Stone" so we use the transformation to Kg + SWU::Imperial(I::Stone) => { + uom::si::f64::Mass::new::(value * 6.350288) } + SWU::Imperial(I::LongTon) => uom::si::f64::Mass::new::(value), + SWU::Metric(M::Kilogram) => uom::si::f64::Mass::new::(value), + SWU::Metric(M::Gram) => uom::si::f64::Mass::new::(value), + SWU::Metric(M::MetricTon) => uom::si::f64::Mass::new::(value), } } } @@ -684,33 +687,35 @@ impl SegmentAccessRestrictionWhenVehicle { /// returns true if the when provided would pass the restriction /// based on the comparison logic pub fn is_valid(&self, when: &SegmentAccessRestrictionWhenVehicle) -> bool { + use SegmentUnit as SU; + if when.dimension != self.dimension { return false; } match (&self.unit, &when.unit) { - (Some(this_unit), Some(other_unit)) => { - let this_value_f64 = match this_unit { - SegmentUnit::Length(segment_length_unit) => segment_length_unit - .to_uom(self.value) - .get::(), - SegmentUnit::Weight(segment_weight_unit) => segment_weight_unit - .to_uom(self.value) - .get::(), - }; - - let other_value_f64 = match other_unit { - SegmentUnit::Length(segment_length_unit) => segment_length_unit - .to_uom(when.value) - .get::(), - SegmentUnit::Weight(segment_weight_unit) => segment_weight_unit - .to_uom(when.value) - .get::(), - }; - + (Some(SU::Length(this_unit)), Some(SU::Length(other_unit))) => { + let this_value_f64 = this_unit.to_uom(self.value).get::(); + let other_value_f64 = other_unit + .to_uom(when.value) + .get::(); + self.comparison.apply(other_value_f64, this_value_f64) + } + (Some(SU::Weight(this_unit)), Some(SU::Weight(other_unit))) => { + let this_value_f64 = this_unit + .to_uom(self.value) + .get::(); + let other_value_f64 = other_unit + .to_uom(when.value) + .get::(); self.comparison.apply(other_value_f64, this_value_f64) } + // Should be handled by the if statement checking the dimension but + // just to be sure + (Some(SU::Weight(_)), Some(SU::Length(_))) => false, + (Some(SU::Length(_)), Some(SU::Weight(_))) => false, + // If we miss any unit, check the raw values _ => self.comparison.apply(when.value, self.value), }