Skip to content

Commit d625d4a

Browse files
committed
std: Add Option.{and,and_then,or,or_else}
1 parent 7380b1c commit d625d4a

File tree

2 files changed

+83
-10
lines changed

2 files changed

+83
-10
lines changed

src/libextra/num/bigint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ impl BigUint {
635635

636636
// Converts this BigUint into an int, unless it would overflow.
637637
pub fn to_int_opt(&self) -> Option<int> {
638-
self.to_uint_opt().chain(|n| {
638+
self.to_uint_opt().and_then(|n| {
639639
// If top bit of uint is set, it's too large to convert to
640640
// int.
641641
if (n >> (2*BigDigit::bits - 1) != 0) {
@@ -1221,7 +1221,7 @@ impl BigInt {
12211221
match self.sign {
12221222
Plus => self.data.to_int_opt(),
12231223
Zero => Some(0),
1224-
Minus => self.data.to_uint_opt().chain(|n| {
1224+
Minus => self.data.to_uint_opt().and_then(|n| {
12251225
let m: uint = 1 << (2*BigDigit::bits-1);
12261226
if (n > m) {
12271227
None

src/libstd/option.rs

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,22 +127,51 @@ impl<T> Option<T> {
127127
#[inline]
128128
pub fn is_some(&self) -> bool { !self.is_none() }
129129

130-
/// Update an optional value by optionally running its content through a
131-
/// function that returns an option.
130+
/// Returns `None` if the option is `None`, otherwise returns `optb`.
132131
#[inline]
133-
pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
132+
pub fn and(self, optb: Option<T>) -> Option<T> {
134133
match self {
135-
Some(t) => f(t),
136-
None => None
134+
Some(_) => optb,
135+
None => None,
136+
}
137+
}
138+
139+
/// Returns `None` if the option is `None`, otherwise calls and returns the
140+
/// value of `f`.
141+
#[inline]
142+
pub fn and_then(self, f: &fn() -> Option<T>) -> Option<T> {
143+
match self {
144+
Some(_) => f(),
145+
None => None,
137146
}
138147
}
139148

140-
/// Returns the leftmost Some() value, or None if both are None.
149+
/// Returns the option if it contains a value, otherwise returns `optb`.
141150
#[inline]
142151
pub fn or(self, optb: Option<T>) -> Option<T> {
143152
match self {
144-
Some(opta) => Some(opta),
145-
_ => optb
153+
Some(_) => self,
154+
None => optb
155+
}
156+
}
157+
158+
/// Returns the option if it contains a value, otherwise calls and returns the
159+
/// value of `f`.
160+
#[inline]
161+
pub fn or_else(self, f: &fn() -> Option<T>) -> Option<T> {
162+
match self {
163+
Some(_) => self,
164+
None => f(),
165+
}
166+
}
167+
168+
/// Update an optional value by optionally running its content through a
169+
/// function that returns an option.
170+
#[inline]
171+
pub fn chain<U>(self, f: &fn(T) -> Option<U>) -> Option<U> {
172+
match self {
173+
Some(t) => f(t),
174+
None => None
146175
}
147176
}
148177

@@ -509,6 +538,50 @@ mod tests {
509538
let _y3 = y.take_unwrap();
510539
}
511540

541+
#[test]
542+
fn test_and() {
543+
let x: Option<int> = Some(1);
544+
assert_eq!(x.and(Some(2)), Some(2));
545+
assert_eq!(x.and(None), None);
546+
547+
let x: Option<int> = None;
548+
assert_eq!(x.and(Some(2)), None);
549+
assert_eq!(x.and(None), None);
550+
}
551+
552+
#[test]
553+
fn test_and_then() {
554+
let x: Option<int> = Some(1);
555+
assert_eq!(x.and_then(|| Some(2)), Some(2));
556+
assert_eq!(x.and_then(|| None), None);
557+
558+
let x: Option<int> = None;
559+
assert_eq!(x.and_then(|| Some(2)), None);
560+
assert_eq!(x.and_then(|| None), None);
561+
}
562+
563+
#[test]
564+
fn test_or() {
565+
let x: Option<int> = Some(1);
566+
assert_eq!(x.or(Some(2)), Some(1));
567+
assert_eq!(x.or(None), Some(1));
568+
569+
let x: Option<int> = None;
570+
assert_eq!(x.or(Some(2)), Some(2));
571+
assert_eq!(x.or(None), None);
572+
}
573+
574+
#[test]
575+
fn test_or_else() {
576+
let x: Option<int> = Some(1);
577+
assert_eq!(x.or_else(|| Some(2)), Some(1));
578+
assert_eq!(x.or_else(|| None), Some(1));
579+
580+
let x: Option<int> = None;
581+
assert_eq!(x.or_else(|| Some(2)), Some(2));
582+
assert_eq!(x.or_else(|| None), None);
583+
}
584+
512585
#[test]
513586
fn test_option_while_some() {
514587
let mut i = 0;

0 commit comments

Comments
 (0)