Skip to content

Commit 21feed4

Browse files
committed
Correctly implement {,Total}Ord for types::range
1 parent 01d8352 commit 21feed4

File tree

1 file changed

+97
-18
lines changed

1 file changed

+97
-18
lines changed

src/types/range.rs

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,8 @@ impl<S: BoundSided, T: fmt::Show> fmt::Show for RangeBound<S, T> {
191191
};
192192

193193
match BoundSided::side(None::<S>) {
194-
Lower => {
195-
write!(fmt, "{}{}", chars[0], self.value)
196-
}
197-
Upper => {
198-
write!(fmt, "{}{}", self.value, chars[1])
199-
}
194+
Lower => write!(fmt, "{}{}", chars[0], self.value),
195+
Upper => write!(fmt, "{}{}", self.value, chars[1]),
200196
}
201197
}
202198
}
@@ -205,16 +201,62 @@ impl<S: BoundSided, T: PartialEq> PartialEq for RangeBound<S, T> {
205201
fn eq(&self, other: &RangeBound<S, T>) -> bool {
206202
self.value == other.value && self.type_ == other.type_
207203
}
204+
205+
fn ne(&self, other: &RangeBound<S, T>) -> bool {
206+
self.value != other.value || self.type_ != other.type_
207+
}
208208
}
209209

210210
impl<S: BoundSided, T: Eq> Eq for RangeBound<S, T> {}
211211

212+
fn partial_cmp<T: PartialOrd>(a: &T, b: &T) -> Option<Ordering> {
213+
match (a <= b, a >= b) {
214+
(false, false) => None,
215+
(false, true) => Some(Greater),
216+
(true, false) => Some(Less),
217+
(true, true) => Some(Equal),
218+
}
219+
}
220+
221+
impl<S: BoundSided, T: PartialOrd> RangeBound<S, T> {
222+
fn partial_cmp(&self, other: &RangeBound<S, T>) -> Option<Ordering> {
223+
match (BoundSided::side(None::<S>), self.type_, other.type_,
224+
partial_cmp(&self.value, &other.value)) {
225+
(Upper, Exclusive, Inclusive, Some(Equal))
226+
| (Lower, Inclusive, Exclusive, Some(Equal)) => Some(Less),
227+
(Upper, Inclusive, Exclusive, Some(Equal))
228+
| (Lower, Exclusive, Inclusive, Some(Equal)) => Some(Greater),
229+
(_, _, _, cmp) => cmp,
230+
}
231+
}
232+
}
233+
212234
impl<S: BoundSided, T: PartialOrd> PartialOrd for RangeBound<S, T> {
213235
fn lt(&self, other: &RangeBound<S, T>) -> bool {
214-
match (BoundSided::side(None::<S>), self.type_, other.type_) {
215-
(Upper, Exclusive, Inclusive)
216-
| (Lower, Inclusive, Exclusive) => self.value <= other.value,
217-
_ => self.value < other.value
236+
match self.partial_cmp(other) {
237+
Some(Less) => true,
238+
_ => false,
239+
}
240+
}
241+
242+
fn le(&self, other: &RangeBound<S, T>) -> bool {
243+
match self.partial_cmp(other) {
244+
Some(Less) | Some(Equal) => true,
245+
_ => false,
246+
}
247+
}
248+
249+
fn gt(&self, other: &RangeBound<S, T>) -> bool {
250+
match self.partial_cmp(other) {
251+
Some(Greater) => true,
252+
_ => false,
253+
}
254+
}
255+
256+
fn ge(&self, other: &RangeBound<S, T>) -> bool {
257+
match self.partial_cmp(other) {
258+
Some(Greater) | Some(Equal) => true,
259+
_ => false,
218260
}
219261
}
220262
}
@@ -223,8 +265,10 @@ impl<S: BoundSided, T: Ord> Ord for RangeBound<S, T> {
223265
fn cmp(&self, other: &RangeBound<S, T>) -> Ordering {
224266
match (BoundSided::side(None::<S>), self.type_, other.type_,
225267
self.value.cmp(&other.value)) {
226-
(Upper, Exclusive, Inclusive, Equal) => Less,
227-
(Lower, Inclusive, Exclusive, Equal) => Greater,
268+
(Upper, Exclusive, Inclusive, Equal)
269+
| (Lower, Inclusive, Exclusive, Equal) => Less,
270+
(Upper, Inclusive, Exclusive, Equal)
271+
| (Lower, Exclusive, Inclusive, Equal) => Greater,
228272
(_, _, _, ord) => ord,
229273
}
230274
}
@@ -254,17 +298,52 @@ impl<'a, S: BoundSided, T: PartialEq> PartialEq for OptBound<'a, S, T> {
254298
let &OptBound(ref self_) = self;
255299
self_ == other
256300
}
301+
302+
fn ne(&self, &OptBound(ref other): &OptBound<'a, S, T>) -> bool {
303+
let &OptBound(ref self_) = self;
304+
self_ != other
305+
}
257306
}
258307

259-
impl<'a, S: BoundSided, T: Eq> Eq for OptBound<'a, S, T> {}
308+
impl<'a, S: BoundSided, T: PartialOrd> OptBound<'a, S, T> {
309+
fn partial_cmp(&self, other: &OptBound<'a, S, T>) -> Option<Ordering> {
310+
match (*self, *other, BoundSided::side(None::<S>)) {
311+
(OptBound(None), OptBound(None), _) => Some(Equal),
312+
(OptBound(None), _, Lower)
313+
| (_, OptBound(None), Upper) => Some(Less),
314+
(OptBound(None), _, Upper)
315+
| (_, OptBound(None), Lower) => Some(Greater),
316+
(OptBound(Some(a)), OptBound(Some(b)), _) => partial_cmp(a, b)
317+
}
318+
}
319+
}
260320

261321
impl<'a, S: BoundSided, T: PartialOrd> PartialOrd for OptBound<'a, S, T> {
262322
fn lt(&self, other: &OptBound<'a, S, T>) -> bool {
263-
match (*self, *other) {
264-
(OptBound(None), OptBound(None)) => false,
265-
(OptBound(None), _) => BoundSided::side(None::<S>) == Lower,
266-
(_, OptBound(None)) => BoundSided::side(None::<S>) == Upper,
267-
(OptBound(Some(a)), OptBound(Some(b))) => a < b
323+
match self.partial_cmp(other) {
324+
Some(Less) => true,
325+
_ => false,
326+
}
327+
}
328+
329+
fn le(&self, other: &OptBound<'a, S, T>) -> bool {
330+
match self.partial_cmp(other) {
331+
Some(Less) | Some(Equal) => true,
332+
_ => false,
333+
}
334+
}
335+
336+
fn gt(&self, other: &OptBound<'a, S, T>) -> bool {
337+
match self.partial_cmp(other) {
338+
Some(Greater) => true,
339+
_ => false,
340+
}
341+
}
342+
343+
fn ge(&self, other: &OptBound<'a, S, T>) -> bool {
344+
match self.partial_cmp(other) {
345+
Some(Greater) | Some(Equal) => true,
346+
_ => false,
268347
}
269348
}
270349
}

0 commit comments

Comments
 (0)