Skip to content

Commit ab25c79

Browse files
committed
Documentation for range
1 parent c5e2afd commit ab25c79

2 files changed

Lines changed: 44 additions & 11 deletions

File tree

tests.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -389,26 +389,25 @@ fn test_int8range_params() {
389389
test_range!("INT8RANGE", i64, 100i64, "100", 200i64, "200")
390390
}
391391
392-
#[test]
393-
#[cfg(not(travis))]
394-
fn test_tsrange_params() {
392+
fn test_timespec_range_params(sql_type: &str) {
395393
fn t(time: &str) -> Timespec {
396394
time::strptime(time, "%Y-%m-%d").unwrap().to_timespec()
397395
}
398396
let low = "1970-01-01";
399397
let high = "1980-01-01";
400-
test_range!("TSRANGE", Timespec, t(low), low, t(high), high);
398+
test_range!(sql_type, Timespec, t(low), low, t(high), high);
399+
}
400+
401+
#[test]
402+
#[cfg(not(travis))]
403+
fn test_tsrange_params() {
404+
test_timespec_range_params("TSRANGE");
401405
}
402406
403407
#[test]
404408
#[cfg(not(travis))]
405409
fn test_tstzrange_params() {
406-
fn t(time: &str) -> Timespec {
407-
time::strptime(time, "%Y-%m-%d").unwrap().to_timespec()
408-
}
409-
let low = "1970-01-01";
410-
let high = "1980-01-01";
411-
test_range!("TSTZRANGE", Timespec, t(low), low, t(high), high);
410+
test_timespec_range_params("TSTZRANGE");
412411
}
413412
414413
fn test_nan_param<T: Float+ToSql+FromSql>(sql_type: &str) {

types/range.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
#[allow(missing_doc)];
1+
//! Types dealing with ranges of values
22
33
extern mod extra;
44

55
use extra::time::Timespec;
66

7+
/// A trait that normalizes a range bound for a type
78
pub trait Normalizable {
9+
/// Given a range bound, returns the normalized version of that bound. For
10+
/// discrete types such as i32, the normalized lower bound is always
11+
/// inclusive and the normalized upper bound is always exclusive. Other
12+
/// types, such as Timespec, have no normalization process so their
13+
/// implementation is a no-op.
14+
///
15+
/// The logic here should match the logic performed by the equivalent
16+
/// Postgres type.
817
fn normalize<S: BoundSided>(bound: RangeBound<S, Self>)
918
-> RangeBound<S, Self>;
1019
}
@@ -50,8 +59,11 @@ trait BoundSided {
5059
fn side(_: Option<Self>) -> BoundSide;
5160
}
5261

62+
/// A tag type representing an upper bound
5363
#[deriving(Eq,Clone)]
5464
pub struct UpperBound;
65+
66+
/// A tag type representing a lower bound
5567
#[deriving(Eq,Clone)]
5668
pub struct LowerBound;
5769

@@ -67,15 +79,23 @@ impl BoundSided for LowerBound {
6779
}
6880
}
6981

82+
/// The type of a range bound
7083
#[deriving(Eq,Clone)]
7184
pub enum BoundType {
85+
/// The bound includes its value
7286
Inclusive,
87+
/// The bound excludes its value
7388
Exclusive
7489
}
7590

91+
/// Represents a one-sided bound.
92+
///
93+
/// The side is determined by the `S` phantom parameter.
7694
#[deriving(Eq,Clone)]
7795
pub struct RangeBound<S, T> {
96+
/// The value of the bound
7897
value: T,
98+
/// The type of the bound
7999
type_: BoundType
80100
}
81101

@@ -90,10 +110,12 @@ impl<S: BoundSided, T: Ord> Ord for RangeBound<S, T> {
90110
}
91111

92112
impl<S: BoundSided, T: Ord> RangeBound<S, T> {
113+
/// Constructs a new range bound
93114
pub fn new(value: T, type_: BoundType) -> RangeBound<S, T> {
94115
RangeBound { value: value, type_: type_ }
95116
}
96117

118+
/// Determines if a value lies within the range specified by this bound.
97119
pub fn in_bounds(&self, value: &T) -> bool {
98120
match (self.type_, BoundSided::side(None::<S>)) {
99121
(Inclusive, Upper) if value <= &self.value => true,
@@ -105,20 +127,28 @@ impl<S: BoundSided, T: Ord> RangeBound<S, T> {
105127
}
106128
}
107129

130+
/// The relation of a value to a range
108131
#[deriving(Eq)]
109132
pub enum RangeComparison {
133+
/// The value lies above the range
110134
Above,
135+
/// The value lies within the range
111136
Within,
137+
/// The value lies below the range
112138
Below
113139
}
114140

141+
/// Represents a range of values.
115142
#[deriving(Eq,Clone)]
116143
pub struct Range<T> {
117144
priv lower: Option<RangeBound<LowerBound, T>>,
118145
priv upper: Option<RangeBound<UpperBound, T>>,
119146
}
120147

121148
impl<T: Ord+Normalizable> Range<T> {
149+
/// Creates a new range.
150+
///
151+
/// If a bound is `None`, the range is unbounded in that direction.
122152
pub fn new(lower: Option<RangeBound<LowerBound, T>>,
123153
upper: Option<RangeBound<UpperBound, T>>) -> Range<T> {
124154
let lower = lower.map(|bound| { Normalizable::normalize(bound) });
@@ -133,14 +163,17 @@ impl<T: Ord+Normalizable> Range<T> {
133163
Range { lower: lower, upper: upper }
134164
}
135165

166+
/// Returns the lower bound if it exists.
136167
pub fn lower<'a>(&'a self) -> &'a Option<RangeBound<LowerBound, T>> {
137168
&self.lower
138169
}
139170

171+
/// Returns the upper bound if it exists.
140172
pub fn upper<'a>(&'a self) -> &'a Option<RangeBound<UpperBound, T>> {
141173
&self.upper
142174
}
143175

176+
/// Compares a value to this range.
144177
pub fn cmp(&self, value: &T) -> RangeComparison {
145178
let lower = do self.lower.as_ref().map_default(true) |b| {
146179
b.in_bounds(value)
@@ -157,6 +190,7 @@ impl<T: Ord+Normalizable> Range<T> {
157190
}
158191
}
159192

193+
/// Determines if a value lies within this range.
160194
pub fn contains(&self, value: &T) -> bool {
161195
self.cmp(value) == Within
162196
}

0 commit comments

Comments
 (0)