Skip to content

Commit

Permalink
Updated and restructured Ch16.5, 16.6
Browse files Browse the repository at this point in the history
Readability and grammar changes
Renamed "Result as an alias" to "aliases for Result"
Made "map for Result" and "aliases for Result" into children of "Result"
  • Loading branch information
Xmasreturns committed May 4, 2016
1 parent 82d29fb commit 659c6cf
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 69 deletions.
23 changes: 23 additions & 0 deletions examples/error/result/result_alias/alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::num::ParseIntError;
use std::result;

// Define a generic alias for a `Result` of type `ParseIntError`.
type AliasedResult<T> = result::Result<T, ParseIntError>;

// Use the alias defined above to refer to our specific `Result` type.
fn double_number(number_str: &str) -> AliasedResult<i32> {
number_str.parse::<i32>().map(|n| 2 * n)
}

// Here, the alias again allows us to save some space.
fn print(result: AliasedResult<i32>) {
match result {
Ok(n) => println!("n is {}", n),
Err(e) => println!("Error: {}", e),
}
}

fn main() {
print(double_number("10"));
print(double_number("t"));
}
18 changes: 18 additions & 0 deletions examples/error/result/result_alias/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
How about when we want to reuse a specific `Result` type many times?
It quickly becomes tedious to write out the full type name, but recall that Rust allows
us to create [aliases][alias]. A generic alias may conveniently be defined for the
specific `Result` in question:

{alias.play}

At a module level, creating aliases can be particularly helpful. Errors
found in a specific module often have the same `Err` type, so a single alias can succinctly
define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`!

### See also:

[`Result`][result] and [`io::Result`][io_result]

[alias]: /cast/alias.html
[result]: http://doc.rust-lang.org/std/result/enum.Result.html
[io_result]: http://doc.rust-lang.org/std/io/type.Result.html
24 changes: 24 additions & 0 deletions examples/error/result/result_map/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Panicking on `unwrap()` in the previous example gave us an unhelpful error message.
To avoid that, we need to be more specific about the return type. In that example,
recall that the regular element is of type `i32`. To determine the `Err` type, we
look to `parse()`. `parse()` is implemented with the [`FromStr trait`][from_str]
for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error].

In the example below, note that using the straightforward `match` statement leads to
more cumbersome code. As it turns out, the `map` method we used with `Option`
is also implemented for `Result`.

{result.play}

Much like `Option`, `Result` implements combinators besides `map`, such as `and_then`
and `unwrap_or`. This even includes those that specifically handle errors, like `map_err`.
[`Result`][result] contains the complete listing.

### See also:

[`i32`][i32], [`FromStr`][from_str], and [`ParseIntErr`][parse_int_error]

[result]: http://doc.rust-lang.org/std/result/enum.Result.html
[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html
[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html
[i32]: http://doc.rust-lang.org/std/primitive.i32.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use std::num::ParseIntError;

// With the return type rewritten, we proceed to use pattern matching without
// `unwrap()` but it is tedious. Couldn't a combinator like in the `Option`
// example also be used here? Yes.
// `unwrap()`, but it is tedious.
fn double_number(number_str: &str) -> Result<i32, ParseIntError> {
match number_str.parse::<i32>() {
Ok(n) => Ok(2 * n),
Err(e) => Err(e),
}
}

// The exact same but written with `map()`. Modify if the value is valid,
// otherwise pass the error on.
// As with `Option`, we can use combinators such as `map()`.
// This function is otherwise identical to the one above and reads:
// Modify n if the value is valid, otherwise pass on the error.
fn double_number_map(number_str: &str) -> Result<i32, ParseIntError> {
number_str.parse::<i32>().map(|n| 2 * n)
}
Expand All @@ -24,11 +24,11 @@ fn print(result: Result<i32, ParseIntError>) {
}

fn main() {
// Still presents a reasonable answer.
// This still presents a reasonable answer.
let twenty = double_number("10");
print(twenty);

// This is now much better than before with the messy `panic`.
// The following now provides a much more useful error message
let tt = double_number_map("t");
print(tt);
}
23 changes: 0 additions & 23 deletions examples/error/result_alias/alias.rs

This file was deleted.

16 changes: 0 additions & 16 deletions examples/error/result_alias/input.md

This file was deleted.

21 changes: 0 additions & 21 deletions examples/error/result_map/input.md

This file was deleted.

7 changes: 4 additions & 3 deletions examples/structure.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@
{ "id": "unwrap", "title": "Option & unwrap", "children": null },
{ "id": "map", "title": "map", "children": null },
{ "id": "and_then", "title": "and_then", "children": null },
{ "id": "result", "title": "Result", "children": null },
{ "id": "result_map", "title": "map for Result", "children": null },
{ "id": "result_alias", "title": "Result as an alias", "children": null },
{ "id": "result", "title": "Result", "children": [
{ "id": "result_map", "title": "map for Result", "children": null },
{ "id": "result_alias", "title": "aliases for Result", "children": null },
] },
{ "id": "option_with_result", "title": "Options with Results", "children": [
{ "id": "result_string_errors", "title": "Errors as strings", "children": null },
{ "id": "combinator_combinations", "title": "Combining separate combinators", "children": null },
Expand Down

0 comments on commit 659c6cf

Please sign in to comment.