Skip to content

Commit 14c24ac

Browse files
committed
auto merge of #11271 : adridu59/rust/patch-io, r=huonw
2 parents 48dc2cb + 95ace50 commit 14c24ac

File tree

2 files changed

+87
-57
lines changed

2 files changed

+87
-57
lines changed

doc/tutorial-conditions.md

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ $ ./example numbers.txt
4343

4444
An example program that does this task reads like this:
4545

46-
~~~~{.xfail-test}
46+
~~~~
4747
# #[allow(unused_imports)];
48+
# extern mod extra;
4849
use std::io::buffered::BufferedReader;
49-
use std::io::fs::File;
50+
use std::io::File;
5051
# mod BufferedReader {
51-
# use std::io::fs::File;
52+
# use std::io::File;
5253
# use std::io::mem::MemReader;
5354
# use std::io::buffered::BufferedReader;
5455
# static s : &'static [u8] = bytes!("1 2\n\
@@ -71,10 +72,9 @@ fn main() {
7172
fn read_int_pairs() -> ~[(int,int)] {
7273
let mut pairs = ~[];
7374
74-
let args = std::os::args();
75-
7675
// Path takes a generic by-value, rather than by reference
77-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
76+
# let _g = std::io::ignore_io_error();
77+
let path = Path::new(&"foo.txt");
7878
let mut reader = BufferedReader::new(File::open(&path));
7979
8080
// 1. Iterate over the lines of our file.
@@ -242,13 +242,14 @@ If the example is rewritten to use failure, these error cases can be trapped.
242242
In this rewriting, failures are trapped by placing the I/O logic in a sub-task,
243243
and trapping its exit status using `task::try`:
244244

245-
~~~~{.xfail-test}
245+
~~~~
246246
# #[allow(unused_imports)];
247+
# extern mod extra;
247248
use std::io::buffered::BufferedReader;
248-
use std::io::fs::File;
249+
use std::io::File;
249250
use std::task;
250251
# mod BufferedReader {
251-
# use std::io::fs::File;
252+
# use std::io::File;
252253
# use std::io::mem::MemReader;
253254
# use std::io::buffered::BufferedReader;
254255
# static s : &'static [u8] = bytes!("1 2\n\
@@ -280,8 +281,8 @@ fn main() {
280281
281282
fn read_int_pairs() -> ~[(int,int)] {
282283
let mut pairs = ~[];
283-
let args = std::os::args();
284-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
284+
# let _g = std::io::ignore_io_error();
285+
let path = Path::new(&"foo.txt");
285286
286287
let mut reader = BufferedReader::new(File::open(&path));
287288
for line in reader.lines() {
@@ -346,12 +347,13 @@ If no handler is found, `Condition::raise` will fail the task with an appropriat
346347
Rewriting the example to use a condition in place of ignoring malformed lines makes it slightly longer,
347348
but similarly clear as the version that used `fail!` in the logic where the error occurs:
348349

349-
~~~~{.xfail-test}
350+
~~~~
350351
# #[allow(unused_imports)];
352+
# extern mod extra;
351353
use std::io::buffered::BufferedReader;
352-
use std::io::fs::File;
354+
use std::io::File;
353355
# mod BufferedReader {
354-
# use std::io::fs::File;
356+
# use std::io::File;
355357
# use std::io::mem::MemReader;
356358
# use std::io::buffered::BufferedReader;
357359
# static s : &'static [u8] = bytes!("1 2\n\
@@ -378,8 +380,8 @@ fn main() {
378380
379381
fn read_int_pairs() -> ~[(int,int)] {
380382
let mut pairs = ~[];
381-
let args = std::os::args();
382-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
383+
# let _g = std::io::ignore_io_error();
384+
let path = Path::new(&"foo.txt");
383385
384386
let mut reader = BufferedReader::new(File::open(&path));
385387
for line in reader.lines() {
@@ -415,12 +417,13 @@ To trap a condition, use `Condition::trap` in some caller of the site that calls
415417
For example, this version of the program traps the `malformed_line` condition
416418
and replaces bad input lines with the pair `(-1,-1)`:
417419

418-
~~~~{.xfail-test}
420+
~~~~
419421
# #[allow(unused_imports)];
422+
# extern mod extra;
420423
use std::io::buffered::BufferedReader;
421-
use std::io::fs::File;
424+
use std::io::File;
422425
# mod BufferedReader {
423-
# use std::io::fs::File;
426+
# use std::io::File;
424427
# use std::io::mem::MemReader;
425428
# use std::io::buffered::BufferedReader;
426429
# static s : &'static [u8] = bytes!("1 2\n\
@@ -452,8 +455,8 @@ fn main() {
452455
453456
fn read_int_pairs() -> ~[(int,int)] {
454457
let mut pairs = ~[];
455-
let args = std::os::args();
456-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
458+
# let _g = std::io::ignore_io_error();
459+
let path = Path::new(&"foo.txt");
457460
458461
let mut reader = BufferedReader::new(File::open(&path));
459462
for line in reader.lines() {
@@ -490,12 +493,13 @@ In the example program, the first form of the `malformed_line` API implicitly as
490493
This assumption may not be correct; some callers may wish to skip malformed lines, for example.
491494
Changing the condition's return type from `(int,int)` to `Option<(int,int)>` will suffice to support this type of recovery:
492495

493-
~~~~{.xfail-test}
496+
~~~~
494497
# #[allow(unused_imports)];
498+
# extern mod extra;
495499
use std::io::buffered::BufferedReader;
496-
use std::io::fs::File;
500+
use std::io::File;
497501
# mod BufferedReader {
498-
# use std::io::fs::File;
502+
# use std::io::File;
499503
# use std::io::mem::MemReader;
500504
# use std::io::buffered::BufferedReader;
501505
# static s : &'static [u8] = bytes!("1 2\n\
@@ -528,8 +532,8 @@ fn main() {
528532
529533
fn read_int_pairs() -> ~[(int,int)] {
530534
let mut pairs = ~[];
531-
let args = std::os::args();
532-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
535+
# let _g = std::io::ignore_io_error();
536+
let path = Path::new(&"foo.txt");
533537
534538
let mut reader = BufferedReader::new(File::open(&path));
535539
for line in reader.lines() {
@@ -575,12 +579,13 @@ until all relevant combinations encountered in practice are encoded.
575579
In the example, suppose a third possible recovery form arose: reusing the previous value read.
576580
This can be encoded in the handler API by introducing a helper type: `enum MalformedLineFix`.
577581

578-
~~~~{.xfail-test}
582+
~~~~
579583
# #[allow(unused_imports)];
584+
# extern mod extra;
580585
use std::io::buffered::BufferedReader;
581-
use std::io::fs::File;
586+
use std::io::File;
582587
# mod BufferedReader {
583-
# use std::io::fs::File;
588+
# use std::io::File;
584589
# use std::io::mem::MemReader;
585590
# use std::io::buffered::BufferedReader;
586591
# static s : &'static [u8] = bytes!("1 2\n\
@@ -622,8 +627,8 @@ fn main() {
622627
623628
fn read_int_pairs() -> ~[(int,int)] {
624629
let mut pairs = ~[];
625-
let args = std::os::args();
626-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
630+
# let _g = std::io::ignore_io_error();
631+
let path = Path::new(&"foo.txt");
627632
628633
let mut reader = BufferedReader::new(File::open(&path));
629634
for line in reader.lines() {
@@ -699,12 +704,13 @@ task <unnamed> failed at 'called `Option::unwrap()` on a `None` value', .../libs
699704
To make the program robust &mdash; or at least flexible &mdash; in the face of this potential failure,
700705
a second condition and a helper function will suffice:
701706

702-
~~~~{.xfail-test}
707+
~~~~
703708
# #[allow(unused_imports)];
709+
# extern mod extra;
704710
use std::io::buffered::BufferedReader;
705-
use std::io::fs::File;
711+
use std::io::File;
706712
# mod BufferedReader {
707-
# use std::io::fs::File;
713+
# use std::io::File;
708714
# use std::io::mem::MemReader;
709715
# use std::io::buffered::BufferedReader;
710716
# static s : &'static [u8] = bytes!("1 2\n\
@@ -760,8 +766,8 @@ fn parse_int(x: &str) -> int {
760766
761767
fn read_int_pairs() -> ~[(int,int)] {
762768
let mut pairs = ~[];
763-
let args = std::os::args();
764-
let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice());
769+
# let _g = std::io::ignore_io_error();
770+
let path = Path::new(&"foo.txt");
765771
766772
let mut reader = BufferedReader::new(File::open(&path));
767773
for line in reader.lines() {

src/libstd/io/mod.rs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -186,23 +186,29 @@ while still providing feedback about errors. The basic strategy:
186186
so that nullable values do not have to be 'unwrapped' before use.
187187
188188
These features combine in the API to allow for expressions like
189-
`File::new("diary.txt").write_line("met a girl")` without having to
190-
worry about whether "diary.txt" exists or whether the write
191-
succeeds. As written, if either `new` or `write_line` encounters
192-
an error the task will fail.
193-
194-
If you wanted to handle the error though you might write
195-
196-
let mut error = None;
197-
do io_error::cond(|e: IoError| {
198-
error = Some(e);
199-
}).in {
200-
File::new("diary.txt").write_line("met a girl");
201-
}
202-
203-
if error.is_some() {
204-
println("failed to write my diary");
205-
}
189+
`File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
190+
without having to worry about whether "diary.txt" exists or whether
191+
the write succeeds. As written, if either `new` or `write_line`
192+
encounters an error the task will fail.
193+
194+
If you wanted to handle the error though you might write:
195+
196+
```rust
197+
use std::io::File;
198+
use std::io::{IoError, io_error};
199+
200+
let mut error = None;
201+
io_error::cond.trap(|e: IoError| {
202+
error = Some(e);
203+
}).inside(|| {
204+
File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"));
205+
});
206+
207+
if error.is_some() {
208+
println("failed to write my diary");
209+
}
210+
# ::std::io::fs::unlink(&Path::new("diary.txt"));
211+
```
206212
207213
XXX: Need better condition handling syntax
208214
@@ -500,10 +506,16 @@ pub trait Reader {
500506
///
501507
/// # Example
502508
///
503-
/// let mut reader = BufferedReader::new(File::open(&Path::new("foo.txt")));
504-
/// for line in reader.lines() {
505-
/// println(line);
506-
/// }
509+
/// ```rust
510+
/// use std::io;
511+
/// # let _g = ::std::io::ignore_io_error();
512+
/// let mut reader = io::stdin();
513+
///
514+
/// let mut bytes = [0, .. 10];
515+
/// reader.read(bytes);
516+
///
517+
/// if reader.eof() { println("stdin() had at most 10 bytes of data."); }
518+
/// ```
507519
///
508520
/// # Failure
509521
///
@@ -1098,6 +1110,18 @@ pub trait Buffer: Reader {
10981110
/// encoded unicode codepoints. If a newline is encountered, then the
10991111
/// newline is contained in the returned string.
11001112
///
1113+
/// # Example
1114+
///
1115+
/// ```rust
1116+
/// use std::io::buffered::BufferedReader;
1117+
/// use std::io;
1118+
/// # let _g = ::std::io::ignore_io_error();
1119+
///
1120+
/// let mut reader = BufferedReader::new(io::stdin());
1121+
///
1122+
/// let input = reader.read_line().unwrap_or(~"nothing");
1123+
/// ```
1124+
///
11011125
/// # Failure
11021126
///
11031127
/// This function will raise on the `io_error` condition (except for

0 commit comments

Comments
 (0)