diff --git a/src/custom_ord_wrapper.rs b/src/custom_ord_wrapper.rs index 2e92406..d58afa6 100644 --- a/src/custom_ord_wrapper.rs +++ b/src/custom_ord_wrapper.rs @@ -18,47 +18,84 @@ along with range_bounds_map. If not, see . */ use std::cmp::Ordering; +use std::ops::RangeBounds; -pub enum CustomOrdWrapper { - CustomOrd(C), - Value(T), +use crate::bound_ord::BoundOrd; + +pub enum CustomRangeBoundsOrdWrapper { + //non real + BoundOrd(BoundOrd), + + //real + RangeBounds(K), } -impl Ord for CustomOrdWrapper +impl Ord for CustomRangeBoundsOrdWrapper where - C: Fn(&T) -> Ordering, + I: Ord + Clone, + K: RangeBounds, { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { ( - CustomOrdWrapper::CustomOrd(custom_ord), - CustomOrdWrapper::Value(value), - ) => custom_ord(value), + CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds), + CustomRangeBoundsOrdWrapper::BoundOrd(bound_ord), + ) => cmp_range_bounds_with_bound_ord(range_bounds, bound_ord), ( - CustomOrdWrapper::Value(value), - CustomOrdWrapper::CustomOrd(custom_ord), - ) => custom_ord(value), - _ => panic!( - "You must have exactly ONE Value and ONE CustomOrd when comparing CustomOrdWrapper's" - ), + CustomRangeBoundsOrdWrapper::BoundOrd(bound_ord), + CustomRangeBoundsOrdWrapper::RangeBounds(range_bounds), + ) => cmp_range_bounds_with_bound_ord(range_bounds, bound_ord) + .reverse(), + _ => { + panic!( + "You cannot compare a Non-Real CustomOrdWrapper with another Non-Real CustomOrdWrapper!" + ); + } } } } -impl PartialOrd for CustomOrdWrapper +fn cmp_range_bounds_with_bound_ord( + range_bounds: &K, + bound_ord: &BoundOrd, +) -> Ordering where - C: Fn(&T) -> Ordering, + I: Ord + Clone, + K: RangeBounds, +{ + let start_bound_ord = BoundOrd::start(range_bounds.start_bound().cloned()); + let end_bound_ord = BoundOrd::end(range_bounds.end_bound().cloned()); + + if bound_ord < &start_bound_ord { + Ordering::Greater + } else if bound_ord > &end_bound_ord { + Ordering::Less + } else { + Ordering::Equal + } +} + +impl PartialOrd for CustomRangeBoundsOrdWrapper +where + I: Ord + Clone, + K: RangeBounds, { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Eq for CustomOrdWrapper where C: Fn(&T) -> Ordering {} - -impl PartialEq for CustomOrdWrapper +impl Eq for CustomRangeBoundsOrdWrapper where - C: Fn(&T) -> Ordering, + I: Ord + Clone, + K: RangeBounds, +{ +} + +impl PartialEq for CustomRangeBoundsOrdWrapper +where + I: Ord + Clone, + K: RangeBounds, { fn eq(&self, other: &Self) -> bool { self.cmp(other).is_eq() diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index ccc0c22..4ab0b08 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -17,6 +17,7 @@ You should have received a copy of the GNU Affero General Public License along with range_bounds_map. If not, see . */ +use std::cmp::Ordering; use std::collections::btree_map::{Cursor, IntoValues}; use std::collections::BTreeMap; use std::fmt::{self, Debug}; @@ -32,6 +33,7 @@ use serde::ser::SerializeMap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::bound_ord::BoundOrd; +use crate::custom_ord_wrapper::CustomOrdWrapper; use crate::TryFromBounds; /// An ordered map of non-overlapping [`RangeBounds`] based on [`BTreeMap`]. @@ -445,6 +447,14 @@ where panic!("Invalid range_bounds!"); } + let start_bound_ord = BoundOrd::start(range_bounds.start_bound()); + let end_bound_ord = BoundOrd::end(range_bounds.end_bound()); + + let start_bound_custom_ord = + CustomOrdWrapper::CustomOrd(|other_range_bounds| { + overlapping_comparison(start_bound_ord, other_range_bounds) + }); + let start = BoundOrd::start(range_bounds.start_bound().cloned()); let end = BoundOrd::end(range_bounds.end_bound().cloned());