Skip to content

Commit e45ed32

Browse files
committed
Add methods iter, iter_err, map, map_err to the result type.
1 parent 46173e9 commit e45ed32

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

src/libcore/result.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,79 @@ fn chain_err<T: copy, U: copy, V: copy>(
107107
}
108108
}
109109

110+
#[doc = "
111+
Call a function based on a previous result
112+
113+
If `res` is `ok` then the value is extracted and passed to `op` whereupon
114+
`op`s result is returned. if `res` is `err` then it is immediately returned.
115+
This function can be used to compose the results of two functions.
116+
117+
Example:
118+
119+
iter(read_file(file)) { |buf|
120+
print_buf(buf)
121+
}
122+
"]
123+
fn iter<T, E>(res: result<T, E>, f: fn(T)) {
124+
alt res {
125+
ok(t) { f(t) }
126+
err(_) { }
127+
}
128+
}
129+
130+
#[doc = "
131+
Call a function based on a previous result
132+
133+
If `res` is `err` then the value is extracted and passed to `op` whereupon
134+
`op`s result is returned. if `res` is `ok` then it is immediately returned.
135+
This function can be used to pass through a successful result while handling
136+
an error.
137+
"]
138+
fn iter_err<T, E>(res: result<T, E>, f: fn(E)) {
139+
alt res {
140+
ok(_) { }
141+
err(e) { f(e) }
142+
}
143+
}
144+
145+
#[doc = "
146+
Call a function based on a previous result
147+
148+
If `res` is `ok` then the value is extracted and passed to `op` whereupon
149+
`op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
150+
immediately returned. This function can be used to compose the results of two
151+
functions.
152+
153+
Example:
154+
155+
let res = map(read_file(file)) { |buf|
156+
parse_buf(buf)
157+
}
158+
"]
159+
fn map<T, E: copy, U: copy>(res: result<T, E>, op: fn(T) -> U)
160+
-> result<U, E> {
161+
alt res {
162+
ok(t) { ok(op(t)) }
163+
err(e) { err(e) }
164+
}
165+
}
166+
167+
#[doc = "
168+
Call a function based on a previous result
169+
170+
If `res` is `err` then the value is extracted and passed to `op` whereupon
171+
`op`s result is wrapped in an `err` and returned. if `res` is `ok` then it is
172+
immediately returned. This function can be used to pass through a successful
173+
result while handling an error.
174+
"]
175+
fn map_err<T: copy, E, F: copy>(res: result<T, E>, op: fn(E) -> F)
176+
-> result<T, F> {
177+
alt res {
178+
ok(t) { ok(t) }
179+
err(e) { err(op(e)) }
180+
}
181+
}
182+
110183
impl extensions<T:copy, E:copy> for result<T,E> {
111184
fn get() -> T { get(self) }
112185

@@ -123,6 +196,34 @@ impl extensions<T:copy, E:copy> for result<T,E> {
123196
fn chain_err<F:copy>(op: fn(E) -> result<T,F>) -> result<T,F> {
124197
chain_err(self, op)
125198
}
199+
200+
fn iter(f: fn(T)) {
201+
alt self {
202+
ok(t) { f(t) }
203+
err(_) { }
204+
}
205+
}
206+
207+
fn iter_err(f: fn(E)) {
208+
alt self {
209+
ok(_) { }
210+
err(e) { f(e) }
211+
}
212+
}
213+
214+
fn map<U:copy>(op: fn(T) -> U) -> result<U,E> {
215+
alt self {
216+
ok(t) { ok(op(t)) }
217+
err(e) { err(e) }
218+
}
219+
}
220+
221+
fn map_err<F:copy>(op: fn(E) -> F) -> result<T,F> {
222+
alt self {
223+
ok(t) { ok(t) }
224+
err(e) { err(op(e)) }
225+
}
226+
}
126227
}
127228

128229
#[doc = "
@@ -248,4 +349,37 @@ mod tests {
248349
fn chain_failure() {
249350
assert get_err(chain(op3(), op2)) == "sadface";
250351
}
352+
353+
#[test]
354+
fn test_impl_iter() {
355+
let mut valid = false;
356+
ok::<str, str>("a").iter { |_x| valid = true; };
357+
assert valid;
358+
359+
err::<str, str>("b").iter { |_x| valid = false; };
360+
assert valid;
361+
}
362+
363+
#[test]
364+
fn test_impl_iter_err() {
365+
let mut valid = true;
366+
ok::<str, str>("a").iter_err { |_x| valid = false; };
367+
assert valid;
368+
369+
valid = false;
370+
err::<str, str>("b").iter_err { |_x| valid = true; };
371+
assert valid;
372+
}
373+
374+
#[test]
375+
fn test_impl_map() {
376+
assert ok::<str, str>("a").map { |_x| "b" } == ok("b");
377+
assert err::<str, str>("a").map { |_x| "b" } == err("a");
378+
}
379+
380+
#[test]
381+
fn test_impl_map_err() {
382+
assert ok::<str, str>("a").map_err { |_x| "b" } == ok("a");
383+
assert err::<str, str>("a").map_err { |_x| "b" } == err("b");
384+
}
251385
}

0 commit comments

Comments
 (0)