Skip to content

Commit ab2b04d

Browse files
committed
More work on Range
Ranges are normalized at creation so Eq works now.
1 parent 3fcf166 commit ab2b04d

3 files changed

Lines changed: 81 additions & 19 deletions

File tree

tests.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,10 @@ fn test_int4range_params() {
349349
(Some(Range::new(None, Some(RangeBound::new(100i32, Exclusive)))), "'(,100)'"),
350350
(Some(Range::new(Some(RangeBound::new(100i32, Inclusive)), None)), "'[100,)'"),
351351
(Some(Range::new(Some(RangeBound::new(100i32, Inclusive)),
352-
Some(RangeBound::new(200i32, Exclusive)))), "'[100,200)'")]);
352+
Some(RangeBound::new(200i32, Exclusive)))), "'[100,200)'"),
353+
(Some(Range::new(Some(RangeBound::new(10i32, Exclusive)),
354+
Some(RangeBound::new(15i32, Inclusive)))), "'(10,15]'"),
355+
(None, "NULL")]);
353356
}
354357
355358
fn test_nan_param<T: Float+ToSql+FromSql>(sql_type: &str) {

types/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,13 @@ to_option_impl!(PgTimestamp | PgTimestampZ, Timespec)
406406
impl ToSql for Range<i32> {
407407
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
408408
check_types!(PgInt4Range, ty)
409-
let lower = do self.lower.as_ref().map |b| {
409+
let lower = do self.lower().as_ref().map |b| {
410410
match b.type_ {
411411
Inclusive => b.value,
412412
Exclusive => b.value + 1
413413
}
414414
};
415-
let upper = do self.upper.as_ref().map |b| {
415+
let upper = do self.upper().as_ref().map |b| {
416416
match b.type_ {
417417
Inclusive => b.value - 1,
418418
Exclusive => b.value

types/range.rs

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
#[allow(missing_doc)];
22

3+
pub trait Normalizable {
4+
fn normalize<S: BoundSided>(bound: RangeBound<S, Self>)
5+
-> RangeBound<S, Self>;
6+
}
7+
8+
impl Normalizable for i32 {
9+
fn normalize<S: BoundSided>(bound: RangeBound<S, i32>)
10+
-> RangeBound<S, i32> {
11+
match BoundSided::side(None::<S>) {
12+
Upper if bound.type_ == Inclusive => {
13+
assert!(bound.value != Bounded::max_value());
14+
RangeBound::new(bound.value + 1, Exclusive)
15+
}
16+
Lower if bound.type_ == Exclusive => {
17+
assert!(bound.value != Bounded::max_value());
18+
RangeBound::new(bound.value + 1, Inclusive)
19+
}
20+
_ => bound
21+
}
22+
}
23+
}
24+
325
enum BoundSide {
426
Upper,
527
Lower
@@ -74,11 +96,11 @@ pub enum RangeComparison {
7496

7597
#[deriving(Eq)]
7698
pub struct Range<T> {
77-
lower: Option<RangeBound<LowerBound, T>>,
78-
upper: Option<RangeBound<UpperBound, T>>,
99+
priv lower: Option<RangeBound<LowerBound, T>>,
100+
priv upper: Option<RangeBound<UpperBound, T>>,
79101
}
80102

81-
impl<T: Ord> Range<T> {
103+
impl<T: Ord+Normalizable> Range<T> {
82104
pub fn new(lower: Option<RangeBound<LowerBound, T>>,
83105
upper: Option<RangeBound<UpperBound, T>>) -> Range<T> {
84106
match (&lower, &upper) {
@@ -87,7 +109,18 @@ impl<T: Ord> Range<T> {
87109
_ => {}
88110
}
89111

90-
Range { lower: lower, upper: upper }
112+
Range {
113+
lower: lower.map(|bound| { Normalizable::normalize(bound) }),
114+
upper: upper.map(|bound| { Normalizable::normalize(bound) }),
115+
}
116+
}
117+
118+
pub fn lower<'a>(&'a self) -> &'a Option<RangeBound<LowerBound, T>> {
119+
&self.lower
120+
}
121+
122+
pub fn upper<'a>(&'a self) -> &'a Option<RangeBound<UpperBound, T>> {
123+
&self.upper
91124
}
92125

93126
pub fn cmp(&self, value: &T) -> RangeComparison {
@@ -114,7 +147,6 @@ impl<T: Ord> Range<T> {
114147
#[cfg(test)]
115148
mod test {
116149
use super::*;
117-
use std::int;
118150

119151
#[test]
120152
fn test_range_bound_lower_lt() {
@@ -180,35 +212,62 @@ mod test {
180212

181213
#[test]
182214
fn test_range_cmp() {
183-
let r = Range::new(Some(RangeBound::new(1, Inclusive)),
184-
Some(RangeBound::new(3, Inclusive)));
215+
let r = Range::new(Some(RangeBound::new(1i32, Inclusive)),
216+
Some(RangeBound::new(3i32, Inclusive)));
185217
assert_eq!(Above, r.cmp(&4));
186218
assert_eq!(Within, r.cmp(&3));
187219
assert_eq!(Within, r.cmp(&2));
188220
assert_eq!(Within, r.cmp(&1));
189221
assert_eq!(Below, r.cmp(&0));
190222

191-
let r = Range::new(Some(RangeBound::new(1, Exclusive)),
192-
Some(RangeBound::new(3, Exclusive)));
223+
let r = Range::new(Some(RangeBound::new(1i32, Exclusive)),
224+
Some(RangeBound::new(3i32, Exclusive)));
193225
assert_eq!(Above, r.cmp(&4));
194226
assert_eq!(Above, r.cmp(&3));
195227
assert_eq!(Within, r.cmp(&2));
196228
assert_eq!(Below, r.cmp(&1));
197229
assert_eq!(Below, r.cmp(&0));
198230

199-
let r = Range::new(None, Some(RangeBound::new(3, Inclusive)));
231+
let r = Range::new(None, Some(RangeBound::new(3i32, Inclusive)));
200232
assert_eq!(Above, r.cmp(&4));
201233
assert_eq!(Within, r.cmp(&2));
202-
assert_eq!(Within, r.cmp(&int::min_value));
234+
assert_eq!(Within, r.cmp(&Bounded::min_value()));
203235

204-
let r = Range::new(Some(RangeBound::new(1, Inclusive)), None);
205-
assert_eq!(Within, r.cmp(&int::max_value));
236+
let r = Range::new(Some(RangeBound::new(1i32, Inclusive)), None);
237+
assert_eq!(Within, r.cmp(&Bounded::max_value()));
206238
assert_eq!(Within, r.cmp(&4));
207239
assert_eq!(Below, r.cmp(&0));
208240

209241
let r = Range::new(None, None);
210-
assert_eq!(Within, r.cmp(&int::max_value));
211-
assert_eq!(Within, r.cmp(&0));
212-
assert_eq!(Within, r.cmp(&int::min_value));
242+
assert_eq!(Within, r.cmp(&Bounded::max_value()));
243+
assert_eq!(Within, r.cmp(&0i32));
244+
assert_eq!(Within, r.cmp(&Bounded::min_value()));
245+
}
246+
247+
#[test]
248+
fn test_normalize_lower() {
249+
let r: RangeBound<LowerBound, i32> = RangeBound::new(10i32, Inclusive);
250+
assert_eq!(RangeBound::new(10i32, Inclusive), Normalizable::normalize(r));
251+
252+
let r: RangeBound<LowerBound, i32> = RangeBound::new(10i32, Exclusive);
253+
assert_eq!(RangeBound::new(11i32, Inclusive), Normalizable::normalize(r));
254+
}
255+
256+
#[test]
257+
fn test_normalize_upper() {
258+
let r: RangeBound<UpperBound, i32> = RangeBound::new(10i32, Inclusive);
259+
assert_eq!(RangeBound::new(11i32, Exclusive), Normalizable::normalize(r));
260+
261+
let r: RangeBound<UpperBound, i32> = RangeBound::new(10i32, Exclusive);
262+
assert_eq!(RangeBound::new(10i32, Exclusive), Normalizable::normalize(r));
263+
}
264+
265+
#[test]
266+
fn test_range_normalizes() {
267+
let r1 = Range::new(Some(RangeBound::new(10i32, Exclusive)),
268+
Some(RangeBound::new(15i32, Inclusive)));
269+
let r2 = Range::new(Some(RangeBound::new(11i32, Inclusive)),
270+
Some(RangeBound::new(16i32, Exclusive)));
271+
assert_eq!(r1, r2);
213272
}
214273
}

0 commit comments

Comments
 (0)