An example program that does this task reads like this:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
-
// Path takes a generic by-value, rather than by reference
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
// 1. Iterate over the lines of our file.
In this rewriting, failures are trapped by placing the I/O logic in a sub-task,
and trapping its exit status using `task::try`:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
use std::task;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {
Rewriting the example to use a condition in place of ignoring malformed lines makes it slightly longer,
but similarly clear as the version that used `fail!` in the logic where the error occurs:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {
For example, this version of the program traps the `malformed_line` condition
and replaces bad input lines with the pair `(-1,-1)`:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {
This assumption may not be correct; some callers may wish to skip malformed lines, for example.
Changing the condition's return type from `(int,int)` to `Option<(int,int)>` will suffice to support this type of recovery:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {
In the example, suppose a third possible recovery form arose: reusing the previous value read.
This can be encoded in the handler API by introducing a helper type: `enum MalformedLineFix`.
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {
To make the program robust — or at least flexible — in the face of this potential failure,
a second condition and a helper function will suffice:
-~~~~{.xfail-test}
+~~~~
# #[allow(unused_imports)];
+# extern mod extra;
use std::io::buffered::BufferedReader;
-use std::io::fs::File;
+use std::io::File;
# mod BufferedReader {
-# use std::io::fs::File;
+# use std::io::File;
# use std::io::mem::MemReader;
# use std::io::buffered::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
- let args = std::os::args();
- let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
+# let _g = std::io::ignore_io_error();
+ let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
for line in reader.lines() {