From e8a35373f2a781466c06116bf46f1e3678d47bd8 Mon Sep 17 00:00:00 2001 From: Ruslan Fadeev Date: Fri, 24 Oct 2025 23:53:27 +0300 Subject: [PATCH] replace panics with no-ops on empty ranges --- src/inclusive_map.rs | 33 ++++++++++----------------------- src/inclusive_set.rs | 8 ++------ src/lib.rs | 5 +++++ src/map.rs | 23 ++++++++++------------- src/set.rs | 8 ++------ 5 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/inclusive_map.rs b/src/inclusive_map.rs index ae9c89e..7b8a5a6 100644 --- a/src/inclusive_map.rs +++ b/src/inclusive_map.rs @@ -238,20 +238,14 @@ where /// any existing range _mapping to the same value_, then the ranges /// will be coalesced into a single contiguous range. /// - /// # Panics - /// - /// Panics if range `start > end`. + /// Inserting an empty range is a no-op. pub fn insert(&mut self, range: RangeInclusive, value: V) { use core::ops::Bound; - // Backwards ranges don't make sense. - // `RangeInclusive` doesn't enforce this, - // and we don't want weird explosions further down - // if someone gives us such a range. - assert!( - range.start() <= range.end(), - "Range start can not be after range end" - ); + // Inserting an empty range is a no-op. + if range.is_empty() { + return; + } // Wrap up the given range so that we can "borrow" // it as a wrapper reference to either its start or end. @@ -374,21 +368,14 @@ where /// in the map, then those ranges will be contracted to no /// longer cover the removed range. /// - /// - /// # Panics - /// - /// Panics if range `start > end`. + /// Removing an empty range is a no-op. pub fn remove(&mut self, range: RangeInclusive) { use core::ops::Bound; - // Backwards ranges don't make sense. - // `RangeInclusive` doesn't enforce this, - // and we don't want weird explosions further down - // if someone gives us such a range. - assert!( - range.start() <= range.end(), - "Range start can not be after range end" - ); + // Removing an empty range is a no-op. + if range.is_empty() { + return; + } let range_start_wrapper: RangeInclusiveStartWrapper = RangeInclusiveStartWrapper::new(range); diff --git a/src/inclusive_set.rs b/src/inclusive_set.rs index 7772899..974d64c 100644 --- a/src/inclusive_set.rs +++ b/src/inclusive_set.rs @@ -140,9 +140,7 @@ where /// any existing range, then the ranges will be coalesced into /// a single contiguous range. /// - /// # Panics - /// - /// Panics if range `start > end`. + /// Inserting an empty range is a no-op. pub fn insert(&mut self, range: RangeInclusive) { self.rm.insert(range, ()); } @@ -153,9 +151,7 @@ where /// in the set, then those ranges will be contracted to no /// longer cover the removed range. /// - /// # Panics - /// - /// Panics if range `start > end`. + /// Removing an empty range is a no-op. pub fn remove(&mut self, range: RangeInclusive) { self.rm.remove(range); } diff --git a/src/lib.rs b/src/lib.rs index e4a4af3..ebb2aec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,6 +85,11 @@ for (range, person) in roster.iter() { // 2019-03-04UTC (P7D): Carol ``` +## Empty ranges + +Insert and remove operations in this crate change a subset of the data structure, +defined by the passed range. When the passed range is empty, the operation +results in a no-op, similar to adding 0 to a number. ## Crate features diff --git a/src/map.rs b/src/map.rs index 7296c5b..bab3705 100644 --- a/src/map.rs +++ b/src/map.rs @@ -255,13 +255,12 @@ where /// any existing range _mapping to the same value_, then the ranges /// will be coalesced into a single contiguous range. /// - /// # Panics - /// - /// Panics if range `start >= end`. + /// Inserting an empty range is a no-op. pub fn insert(&mut self, range: Range, value: V) { - // We don't want to have to make empty ranges make sense; - // they don't represent anything meaningful in this structure. - assert!(range.start < range.end); + // Inserting an empty range is a no-op. + if range.is_empty() { + return; + } // Wrap up the given range so that we can "borrow" // it as a wrapper reference to either its start or end. @@ -368,14 +367,12 @@ where /// in the map, then those ranges will be contracted to no /// longer cover the removed range. /// - /// - /// # Panics - /// - /// Panics if range `start >= end`. + /// Removing an empty range is a no-op. pub fn remove(&mut self, range: Range) { - // We don't want to have to make empty ranges make sense; - // they don't represent anything meaningful in this structure. - assert!(range.start < range.end); + // Removing an empty range is a no-op. + if range.is_empty() { + return; + } let start_wrapper: RangeStartWrapper = RangeStartWrapper::new(range); let range = &start_wrapper.end_wrapper.range; diff --git a/src/set.rs b/src/set.rs index d68b182..e7bc10d 100644 --- a/src/set.rs +++ b/src/set.rs @@ -120,9 +120,7 @@ where /// any existing range, then the ranges will be coalesced into /// a single contiguous range. /// - /// # Panics - /// - /// Panics if range `start >= end`. + /// Inserting an empty range is a no-op. pub fn insert(&mut self, range: Range) { self.rm.insert(range, ()); } @@ -133,9 +131,7 @@ where /// in the set, then those ranges will be contracted to no /// longer cover the removed range. /// - /// # Panics - /// - /// Panics if range `start >= end`. + /// Removing an empty range is a no-op. pub fn remove(&mut self, range: Range) { self.rm.remove(range); }