1- # [ allow ( missing_doc ) ] ;
1+ //! Types dealing with ranges of values
22
33extern mod extra;
44
55use extra:: time:: Timespec ;
66
7+ /// A trait that normalizes a range bound for a type
78pub 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 ) ]
5464pub struct UpperBound ;
65+
66+ /// A tag type representing a lower bound
5567#[ deriving( Eq , Clone ) ]
5668pub 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 ) ]
7184pub 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 ) ]
7795pub 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
92112impl < 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 ) ]
109132pub 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 ) ]
116143pub struct Range < T > {
117144 priv lower : Option < RangeBound < LowerBound , T > > ,
118145 priv upper : Option < RangeBound < UpperBound , T > > ,
119146}
120147
121148impl < 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