diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 0f39b29c60a9e..62bbd88070025 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -261,7 +261,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] { debug!("making tests from {}", config.src_base.display()); let mut tests = ~[]; - let dirs = fs::readdir(&config.src_base); + let dirs = fs::readdir(&config.src_base).unwrap(); for file in dirs.iter() { let file = file.clone(); debug!("inspecting file {}", file.display()); diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 6be92b12535f5..add38849bac68 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -21,7 +21,7 @@ pub fn load_errors(testfile: &Path) -> ~[ExpectedError] { let mut line_num = 1u; loop { let ln = match rdr.read_line() { - Some(ln) => ln, None => break, + Ok(ln) => ln, Err(*) => break, }; error_patterns.push_all_move(parse_expected(line_num, ln)); line_num += 1u; diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 1966701dbdedd..e7f463a8f46dd 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -109,7 +109,7 @@ fn iter_header(testfile: &Path, it: |&str| -> bool) -> bool { let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); loop { let ln = match rdr.read_line() { - Some(ln) => ln, None => break + Ok(ln) => ln, Err(*) => break }; // Assume that any directives will be found before the first diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 4c7b212304ceb..3b7a6e784af62 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -152,7 +152,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) { let rounds = match props.pp_exact { Some(_) => 1, None => 2 }; - let src = File::open(testfile).read_to_end(); + let src = File::open(testfile).read_to_end().unwrap(); let src = str::from_utf8_owned(src); let mut srcs = ~[src]; @@ -174,7 +174,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) { let mut expected = match props.pp_exact { Some(ref file) => { let filepath = testfile.dir_path().join(file); - let s = File::open(&filepath).read_to_end(); + let s = File::open(&filepath).read_to_end().unwrap(); str::from_utf8_owned(s) } None => { srcs[srcs.len() - 2u].clone() } @@ -995,7 +995,7 @@ fn _dummy_exec_compiled_test(config: &config, props: &TestProps, fn _arm_push_aux_shared_library(config: &config, testfile: &Path) { let tdir = aux_output_dir_name(config, testfile); - let dirs = fs::readdir(&tdir); + let dirs = fs::readdir(&tdir).unwrap(); for file in dirs.iter() { if file.extension_str() == Some("so") { // FIXME (#9639): This needs to handle non-utf8 paths @@ -1090,7 +1090,7 @@ fn disassemble_extract(config: &config, _props: &TestProps, fn count_extracted_lines(p: &Path) -> uint { - let x = File::open(&p.with_extension("ll")).read_to_end(); + let x = File::open(&p.with_extension("ll")).read_to_end().unwrap(); let x = str::from_utf8_owned(x); x.lines().len() } diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 19959dd2705fc..bca299b14abb0 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -658,14 +658,14 @@ pub mod writer { write_vuint(self.writer, tag_id); // Write a placeholder four-byte size. - self.size_positions.push(self.writer.tell() as uint); + self.size_positions.push(self.writer.tell().unwrap() as uint); let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; self.writer.write(zeroes); } pub fn end_tag(&mut self) { let last_size_pos = self.size_positions.pop(); - let cur_pos = self.writer.tell(); + let cur_pos = self.writer.tell().unwrap(); self.writer.seek(last_size_pos as i64, io::SeekSet); let size = (cur_pos as uint - last_size_pos - 4); write_sized_vuint(self.writer, size as uint, 4u); diff --git a/src/libextra/glob.rs b/src/libextra/glob.rs index 3ee43ca4a5852..57f31e59a5520 100644 --- a/src/libextra/glob.rs +++ b/src/libextra/glob.rs @@ -24,7 +24,6 @@ */ use std::{os, path}; -use std::io; use std::io::fs; use std::path::is_sep; @@ -148,7 +147,7 @@ impl Iterator for GlobIterator { } fn list_dir_sorted(path: &Path) -> ~[Path] { - match io::result(|| fs::readdir(path)) { + match fs::readdir(path) { Ok(children) => { let mut children = children; sort::quick_sort(children, |p1, p2| p2.filename() <= p1.filename()); diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 8dcf0a919d37f..c696a99fb5f8b 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -95,7 +95,7 @@ pub fn Encoder(wr: @mut io::Writer) -> Encoder { } impl serialize::Encoder for Encoder { - fn emit_nil(&mut self) { write!(self.wr, "null") } + fn emit_nil(&mut self) { write!(self.wr, "null"); } fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } @@ -118,13 +118,13 @@ impl serialize::Encoder for Encoder { } fn emit_f64(&mut self, v: f64) { - write!(self.wr, "{}", f64::to_str_digits(v, 6u)) + write!(self.wr, "{}", f64::to_str_digits(v, 6u)); } fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) } fn emit_str(&mut self, v: &str) { - write!(self.wr, "{}", escape_str(v)) + write!(self.wr, "{}", escape_str(v)); } fn emit_enum(&mut self, _name: &str, f: |&mut Encoder|) { f(self) } @@ -180,7 +180,7 @@ impl serialize::Encoder for Encoder { name: &str, idx: uint, f: |&mut Encoder|) { - if idx != 0 { write!(self.wr, ",") } + if idx != 0 { write!(self.wr, ","); } write!(self.wr, "{}:", escape_str(name)); f(self); } @@ -226,7 +226,7 @@ impl serialize::Encoder for Encoder { } fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder|) { - if idx != 0 { write!(self.wr, ",") } + if idx != 0 { write!(self.wr, ","); } f(self) } @@ -252,7 +252,7 @@ pub fn PrettyEncoder(wr: @mut io::Writer) -> PrettyEncoder { } impl serialize::Encoder for PrettyEncoder { - fn emit_nil(&mut self) { write!(self.wr, "null") } + fn emit_nil(&mut self) { write!(self.wr, "null"); } fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } @@ -275,7 +275,7 @@ impl serialize::Encoder for PrettyEncoder { } fn emit_f64(&mut self, v: f64) { - write!(self.wr, "{}", f64::to_str_digits(v, 6u)) + write!(self.wr, "{}", f64::to_str_digits(v, 6u)); } fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } @@ -841,7 +841,12 @@ impl> Parser { /// Decodes a json value from an `&mut io::Reader` pub fn from_reader(rdr: &mut io::Reader) -> Result { - let s = str::from_utf8(rdr.read_to_end()); + let s = match rdr.read_to_end() { + Ok(b) => str::from_utf8_owned(b), + Err(e) => return Err(Error { + line: 0, col: 0, msg: @format!("{}", e) + }) + }; let mut parser = Parser(~s.chars()); parser.parse() } diff --git a/src/libextra/task_pool.rs b/src/libextra/task_pool.rs index bda6935643f04..b3db6e9ae5085 100644 --- a/src/libextra/task_pool.rs +++ b/src/libextra/task_pool.rs @@ -103,6 +103,6 @@ fn test_task_pool() { }; let mut pool = TaskPool::new(4, Some(SingleThreaded), f); 8.times(|| { - pool.execute(proc(i) println!("Hello from thread {}!", *i)); + pool.execute(proc(i) { println!("Hello from thread {}!", *i); }); }) } diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index 5bcba29572304..93ea2451cba9c 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -38,7 +38,7 @@ impl TempDir { let mut r = rand::rng(); for _ in range(0u, 1000) { let p = tmpdir.join(r.gen_ascii_str(16) + suffix); - match io::result(|| fs::mkdir(&p, io::UserRWX)) { + match fs::mkdir(&p, io::UserRWX) { Err(*) => {} Ok(()) => return Some(TempDir { path: Some(p) }) } diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index af1532db93551..a9c67df903e83 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -177,17 +177,17 @@ pub fn parse(file: &mut io::Reader, } // Check magic number - let magic = file.read_le_u16(); + let magic = file.read_le_u16().unwrap(); if (magic != 0x011A) { return Err(format!("invalid magic number: expected {:x} but found {:x}", 0x011A, magic as uint)); } - let names_bytes = file.read_le_i16() as int; - let bools_bytes = file.read_le_i16() as int; - let numbers_count = file.read_le_i16() as int; - let string_offsets_count = file.read_le_i16() as int; - let string_table_bytes = file.read_le_i16() as int; + let names_bytes = file.read_le_i16().unwrap() as int; + let bools_bytes = file.read_le_i16().unwrap() as int; + let numbers_count = file.read_le_i16().unwrap() as int; + let string_offsets_count = file.read_le_i16().unwrap() as int; + let string_table_bytes = file.read_le_i16().unwrap() as int; assert!(names_bytes > 0); @@ -215,7 +215,11 @@ pub fn parse(file: &mut io::Reader, return Err(~"incompatible file: more string offsets than expected"); } - let names_str = str::from_utf8(file.read_bytes(names_bytes as uint - 1)); // don't read NUL + let b = match file.read_bytes(names_bytes as uint - 1) { // don't read NUL + Ok(bytes) => bytes, + Err((_, e)) => return Err(format!("{}", e)), + }; + let names_str = str::from_utf8(b); let term_names: ~[~str] = names_str.split('|').map(|s| s.to_owned()).collect(); file.read_byte(); // consume NUL @@ -246,7 +250,7 @@ pub fn parse(file: &mut io::Reader, let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in range(0, numbers_count) { - let n = file.read_le_u16(); + let n = file.read_le_u16().unwrap(); if n != 0xFFFF { debug!("{}\\#{}", nnames[i], n); numbers_map.insert(nnames[i].to_owned(), n); @@ -261,12 +265,12 @@ pub fn parse(file: &mut io::Reader, if string_offsets_count != 0 { let mut string_offsets = vec::with_capacity(10); for _ in range(0, string_offsets_count) { - string_offsets.push(file.read_le_u16()); + string_offsets.push(file.read_le_u16().unwrap()); } debug!("offsets: {:?}", string_offsets); - let string_table = file.read_bytes(string_table_bytes as uint); + let string_table = file.read_bytes(string_table_bytes as uint).unwrap(); if string_table.len() != string_table_bytes as uint { error!("EOF reading string table after {} bytes, wanted {}", string_table.len(), diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 16e9ea8ece48c..733fe17b60e4f 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -428,7 +428,7 @@ impl ConsoleTestState { term.reset(); } } - Right(ref mut stdout) => stdout.write(word.as_bytes()) + Right(ref mut stdout) => { stdout.write(word.as_bytes()); } } } @@ -550,9 +550,10 @@ impl ConsoleTestState { self.write_plain(format!("\nusing metrics ratcher: {}\n", pth.display())); match ratchet_pct { None => (), - Some(pct) => + Some(pct) => { self.write_plain(format!("with noise-tolerance forced to: {}%\n", - pct)) + pct)); + } } let (diff, ok) = self.metrics.ratchet(pth, ratchet_pct); self.write_metric_diff(&diff); diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 1352bfd424f68..3432df97cc2ee 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -679,26 +679,22 @@ pub fn strptime(s: &str, format: &str) -> Result { let ch = range.ch; let next = range.next; - let mut buf = [0]; - let c = match rdr.read(buf) { - Some(*) => buf[0] as u8 as char, - None => break - }; - match c { - '%' => { - let ch = match rdr.read(buf) { - Some(*) => buf[0] as u8 as char, - None => break + match rdr.read_byte() { + Ok(c) if c == '%' as u8 => { + let ch = match rdr.read_byte() { + Ok(b) => b as char, + Err(*) => break }; match parse_type(s, pos, ch, &mut tm) { Ok(next) => pos = next, Err(e) => { result = Err(e); break; } } }, - c => { - if c != ch { break } + Ok(c) => { + if c as char != ch { break } pos = next; } + Err(*) => break } } @@ -930,18 +926,13 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str { let mut rdr = BufReader::new(format.as_bytes()); loop { - let mut b = [0]; - let ch = match rdr.read(b) { - Some(*) => b[0], - None => break, - }; - match ch as char { - '%' => { - rdr.read(b); - let s = parse_type(b[0] as char, tm); + match rdr.read_byte() { + Ok(c) if c == '%' as u8 => { + let s = parse_type(rdr.read_byte().unwrap() as char, tm); buf.push_all(s.as_bytes()); } - ch => buf.push(ch as u8) + Ok(ch) => buf.push(ch as u8), + Err(*) => break, } } diff --git a/src/libextra/url.rs b/src/libextra/url.rs index 71a8774e35c64..6a3dbd23b11c2 100644 --- a/src/libextra/url.rs +++ b/src/libextra/url.rs @@ -73,8 +73,8 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { loop { let mut buf = [0]; let ch = match rdr.read(buf) { - None => break, - Some(*) => buf[0] as char, + Err(*) => break, + Ok(*) => buf[0] as char, }; match ch { @@ -137,14 +137,14 @@ fn decode_inner(s: &str, full_url: bool) -> ~str { loop { let mut buf = [0]; let ch = match rdr.read(buf) { - None => break, - Some(*) => buf[0] as char + Err(*) => break, + Ok(*) => buf[0] as char }; match ch { '%' => { let mut bytes = [0, 0]; match rdr.read(bytes) { - Some(2) => {} + Ok(2) => {} _ => fail!() // XXX: malformed url? } let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char; @@ -199,8 +199,8 @@ fn encode_plus(s: &str) -> ~str { loop { let mut buf = [0]; let ch = match rdr.read(buf) { - Some(*) => buf[0] as char, - None => break, + Ok(*) => buf[0] as char, + Err(*) => break, }; match ch { 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => { @@ -253,8 +253,8 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> { loop { let mut buf = [0]; let ch = match rdr.read(buf) { - Some(*) => buf[0] as char, - None => break, + Ok(*) => buf[0] as char, + Err(*) => break, }; match ch { '&' | ';' => { @@ -278,7 +278,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> { '%' => { let mut bytes = [0, 0]; match rdr.read(bytes) { - Some(2) => {} + Ok(2) => {} _ => fail!() // XXX: malformed? } uint::parse_bytes(bytes, 16u).unwrap() as u8 as char @@ -318,12 +318,12 @@ fn split_char_first(s: &str, c: char) -> (~str, ~str) { loop { let mut buf = [0]; let ch = match rdr.read(buf) { - Some(*) => buf[0] as char, - None => break, + Ok(*) => buf[0] as char, + Err(*) => break, }; if ch == c { // found a match, adjust markers - index = (rdr.tell() as uint) - 1; + index = (rdr.tell().unwrap() as uint) - 1; mat = 1; break; } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index beb211339083d..5b93069180cf3 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -182,12 +182,12 @@ impl Database { fn load(&mut self) { assert!(!self.db_dirty); assert!(self.db_filename.exists()); - match io::result(|| File::open(&self.db_filename)) { + match File::open(&self.db_filename) { Err(e) => fail!("Couldn't load workcache database {}: {}", self.db_filename.display(), e.desc), Ok(r) => - match json::from_reader(@mut r.unwrap() as @mut io::Reader) { + match json::from_reader(@mut r as @mut io::Reader) { Err(e) => fail!("Couldn't parse workcache database (from file {}): {}", self.db_filename.display(), e.to_str()), Ok(r) => { @@ -512,7 +512,7 @@ fn test() { let subcx = cx.clone(); let pth = pth.clone(); - let file_content = from_utf8_owned(File::open(&pth).read_to_end()); + let file_content = from_utf8_owned(File::open(&pth).read_to_end().unwrap()); // FIXME (#9639): This needs to handle non-utf8 paths prep.declare_input("file", pth.as_str().unwrap(), file_content); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index adc3712bf0f97..93ea82ad7e07e 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -971,11 +971,10 @@ pub fn link_binary(sess: Session, fn is_writeable(p: &Path) -> bool { use std::io; - !p.exists() || - (match io::result(|| p.stat()) { - Err(*) => false, - Ok(m) => m.perm & io::UserWrite == io::UserWrite - }) + match p.stat() { + Err(*) => true, + Ok(m) => m.perm & io::UserWrite == io::UserWrite + } } pub fn link_args(sess: Session, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index dc1aa1f41cbfb..1f7a1c8329f37 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -247,7 +247,7 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) { 1u => { let ifile = matches.free[0].as_slice(); if "-" == ifile { - let src = str::from_utf8(io::stdin().read_to_end()); + let src = str::from_utf8(io::stdin().read_to_end().unwrap()); str_input(src.to_managed()) } else { file_input(Path::new(ifile)) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8f09353796b7e..acc72e8aad9f6 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -137,7 +137,7 @@ fn add_to_index(ebml_w: &mut writer::Encoder, index.push( entry { val: ast_util::path_name_i(full_path), - pos: ebml_w.writer.tell() + pos: ebml_w.writer.tell().unwrap() }); } @@ -364,7 +364,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, for variant in variants.iter() { let def_id = local_def(variant.node.id); index.push(entry {val: variant.node.id as i64, - pos: ebml_w.writer.tell()}); + pos: ebml_w.writer.tell().unwrap()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, def_id); match variant.node.kind { @@ -705,7 +705,7 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic match m { MutImmutable => ebml_w.writer.write(&[ 'i' as u8 ]), MutMutable => ebml_w.writer.write(&[ 'm' as u8 ]), - } + }; } } @@ -745,8 +745,9 @@ fn encode_info_for_struct(ecx: &EncodeContext, }; let id = field.node.id; - index.push(entry {val: id as i64, pos: ebml_w.writer.tell()}); - global_index.push(entry {val: id as i64, pos: ebml_w.writer.tell()}); + let pos = ebml_w.writer.tell().unwrap(); + index.push(entry {val: id as i64, pos: pos}); + global_index.push(entry {val: id as i64, pos: pos}); ebml_w.start_tag(tag_items_data_item); debug!("encode_info_for_struct: doing {} {}", tcx.sess.str_of(nm), id); @@ -767,7 +768,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, ctor_id: NodeId, index: @mut ~[entry], struct_id: NodeId) { - index.push(entry { val: ctor_id as i64, pos: ebml_w.writer.tell() }); + index.push(entry { val: ctor_id as i64, pos: ebml_w.writer.tell().unwrap() }); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(ctor_id)); @@ -909,7 +910,7 @@ fn encode_info_for_item(ecx: &EncodeContext, fn add_to_index(item: @item, ebml_w: &writer::Encoder, index: @mut ~[entry]) { - index.push(entry { val: item.id as i64, pos: ebml_w.writer.tell() }); + index.push(entry { val: item.id as i64, pos: ebml_w.writer.tell().unwrap() }); } let add_to_index: || = || add_to_index(item, ebml_w, index); @@ -1133,7 +1134,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } else { None }; index.push(entry {val: m.def_id.node as i64, - pos: ebml_w.writer.tell()}); + pos: ebml_w.writer.tell().unwrap()}); encode_info_for_method(ecx, ebml_w, *m, @@ -1187,7 +1188,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let method_ty = ty::method(tcx, method_def_id); index.push(entry {val: method_def_id.node as i64, - pos: ebml_w.writer.tell()}); + pos: ebml_w.writer.tell().unwrap()}); ebml_w.start_tag(tag_items_data_item); @@ -1252,7 +1253,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, index: @mut ~[entry], path: &ast_map::path, abi: AbiSet) { - index.push(entry { val: nitem.id as i64, pos: ebml_w.writer.tell() }); + index.push(entry { val: nitem.id as i64, pos: ebml_w.writer.tell().unwrap() }); ebml_w.start_tag(tag_items_data_item); match nitem.node { @@ -1362,7 +1363,7 @@ fn encode_info_for_items(ecx: &EncodeContext, -> ~[entry] { let index = @mut ~[]; ebml_w.start_tag(tag_items_data); - index.push(entry { val: CRATE_NODE_ID as i64, pos: ebml_w.writer.tell() }); + index.push(entry { val: CRATE_NODE_ID as i64, pos: ebml_w.writer.tell().unwrap() }); encode_info_for_mod(ecx, ebml_w, &crate.module, @@ -1416,7 +1417,7 @@ fn encode_index( let mut bucket_locs = ~[]; ebml_w.start_tag(tag_index_buckets); for bucket in buckets.iter() { - bucket_locs.push(ebml_w.writer.tell()); + bucket_locs.push(ebml_w.writer.tell().unwrap()); ebml_w.start_tag(tag_index_buckets_bucket); for elt in (**bucket).iter() { ebml_w.start_tag(tag_index_buckets_bucket_elt); @@ -1792,43 +1793,43 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] { encode_hash(&mut ebml_w, ecx.link_meta.extras_hash); - let mut i = wr.tell(); + let mut i = wr.tell().unwrap(); let crate_attrs = synthesize_crate_attrs(&ecx, crate); encode_attributes(&mut ebml_w, crate_attrs); - ecx.stats.attr_bytes = wr.tell() - i; + ecx.stats.attr_bytes = wr.tell().unwrap() - i; - i = wr.tell(); + i = wr.tell().unwrap(); encode_crate_deps(&ecx, &mut ebml_w, ecx.cstore); - ecx.stats.dep_bytes = wr.tell() - i; + ecx.stats.dep_bytes = wr.tell().unwrap() - i; // Encode the language items. - i = wr.tell(); + i = wr.tell().unwrap(); encode_lang_items(&ecx, &mut ebml_w); - ecx.stats.lang_item_bytes = wr.tell() - i; + ecx.stats.lang_item_bytes = wr.tell().unwrap() - i; // Encode the def IDs of impls, for coherence checking. - i = wr.tell(); + i = wr.tell().unwrap(); encode_impls(&ecx, crate, &mut ebml_w); - ecx.stats.impl_bytes = wr.tell() - i; + ecx.stats.impl_bytes = wr.tell().unwrap() - i; // Encode miscellaneous info. - i = wr.tell(); + i = wr.tell().unwrap(); encode_misc_info(&ecx, crate, &mut ebml_w); - ecx.stats.misc_bytes = wr.tell() - i; + ecx.stats.misc_bytes = wr.tell().unwrap() - i; // Encode and index the items. ebml_w.start_tag(tag_items); - i = wr.tell(); + i = wr.tell().unwrap(); let items_index = encode_info_for_items(&ecx, &mut ebml_w, crate); - ecx.stats.item_bytes = wr.tell() - i; + ecx.stats.item_bytes = wr.tell().unwrap() - i; - i = wr.tell(); + i = wr.tell().unwrap(); let items_buckets = create_index(items_index); encode_index(&mut ebml_w, items_buckets, write_i64); - ecx.stats.index_bytes = wr.tell() - i; + ecx.stats.index_bytes = wr.tell().unwrap() - i; ebml_w.end_tag(); - ecx.stats.total_bytes = wr.tell(); + ecx.stats.total_bytes = wr.tell().unwrap(); if (tcx.sess.meta_stats()) { for e in wr.inner_ref().iter() { diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index b2e5888eee1a5..9e58eb8d51cd1 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -11,7 +11,6 @@ use std::option; use std::os; -use std::io; use std::io::fs; use std::hashmap::HashSet; @@ -120,7 +119,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, pub fn search(filesearch: @FileSearch, pick: pick) { filesearch.for_each_lib_search_path(|lib_search_path| { debug!("searching {}", lib_search_path.display()); - match io::result(|| fs::readdir(lib_search_path)) { + match fs::readdir(lib_search_path) { Ok(files) => { let mut rslt = FileDoesntMatch; for path in files.iter() { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index ecd1c8985bd00..b4a1320a85744 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -273,7 +273,7 @@ pub fn list_file_metadata(intr: @ident_interner, match get_metadata_section(os, path) { option::Some(bytes) => decoder::list_crate_metadata(intr, bytes, out), option::None => { - write!(out, "could not find metadata in {}.\n", path.display()) + write!(out, "could not find metadata in {}.\n", path.display()); } } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 19a9a7efc578a..38c61ff38f4a0 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -84,9 +84,9 @@ pub fn enc_ty(w: @mut MemWriter, cx: @ctxt, t: ty::t) { Some(a) => { w.write(a.s.as_bytes()); return; } None => {} } - let pos = w.tell(); + let pos = w.tell().unwrap(); enc_sty(w, cx, &ty::get(t).sty); - let end = w.tell(); + let end = w.tell().unwrap(); let len = end - pos; fn estimate_sz(u: u64) -> u64 { let mut n = u; diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index d618275ff05e5..f5425eb4540c7 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -20,7 +20,7 @@ use std::fmt; pub struct Escape<'self>(&'self str); impl<'self> fmt::Default for Escape<'self> { - fn fmt(s: &Escape<'self>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Escape<'self>, fmt: &mut fmt::Formatter) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 let pile_o_bits = s.as_slice(); @@ -47,5 +47,6 @@ impl<'self> fmt::Default for Escape<'self> { if last < s.len() { fmt.buf.write(pile_o_bits.slice_from(last).as_bytes()); } + Ok(()) } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 90c317668fc2f..79396dfdd8fa8 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -36,8 +36,8 @@ pub struct PuritySpace(ast::purity); pub struct Method<'self>(&'self clean::SelfTy, &'self clean::FnDecl); impl fmt::Default for clean::Generics { - fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) { - if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return } + fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result { + if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) } f.buf.write("<".as_bytes()); for (i, life) in g.lifetimes.iter().enumerate() { @@ -49,7 +49,7 @@ impl fmt::Default for clean::Generics { if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); } for (i, tp) in g.type_params.iter().enumerate() { - if i > 0 { f.buf.write(", ".as_bytes()) } + if i > 0 { f.buf.write(", ".as_bytes()); } f.buf.write(tp.name.as_bytes()); if tp.bounds.len() > 0 { @@ -62,34 +62,37 @@ impl fmt::Default for clean::Generics { } } f.buf.write(">".as_bytes()); + Ok(()) } } impl fmt::Default for clean::Lifetime { - fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) { + fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result { f.buf.write("'".as_bytes()); f.buf.write(l.as_bytes()); + Ok(()) } } impl fmt::Default for clean::TyParamBound { - fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) { + fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result { match *bound { clean::RegionBound => { - f.buf.write("'static".as_bytes()) + f.buf.write("'static".as_bytes()); } clean::TraitBound(ref ty) => { write!(f.buf, "{}", *ty); } } + Ok(()) } } impl fmt::Default for clean::Path { - fn fmt(path: &clean::Path, f: &mut fmt::Formatter) { - if path.global { f.buf.write("::".as_bytes()) } + fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result { + if path.global { f.buf.write("::".as_bytes()); } for (i, seg) in path.segments.iter().enumerate() { - if i > 0 { f.buf.write("::".as_bytes()) } + if i > 0 { f.buf.write("::".as_bytes()); } f.buf.write(seg.name.as_bytes()); if seg.lifetimes.len() > 0 || seg.types.len() > 0 { @@ -108,6 +111,7 @@ impl fmt::Default for clean::Path { f.buf.write(">".as_bytes()); } } + Ok(()) } } @@ -259,7 +263,7 @@ fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) { } impl fmt::Default for clean::Type { - fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { + fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result { match *g { clean::TyParamBinder(id) | clean::Generic(id) => { local_data::get(cache_key, |cache| { @@ -277,7 +281,7 @@ impl fmt::Default for clean::Type { external_path(f.buf, path, false, fqn.as_slice(), kind, crate); typarams(f.buf, tp); } - clean::Self(*) => f.buf.write("Self".as_bytes()), + clean::Self(*) => { f.buf.write("Self".as_bytes()); } clean::Primitive(prim) => { let s = match prim { ast::ty_int(ast::ty_i) => "int", @@ -299,12 +303,16 @@ impl fmt::Default for clean::Type { f.buf.write(s.as_bytes()); } clean::Closure(ref decl) => { - let region = match decl.region { - Some(ref region) => format!("{} ", *region), - None => ~"", - }; - - write!(f.buf, "{}{}{arrow, select, yes{ -> {ret}} other{}}", + f.buf.write(match decl.sigil { + ast::BorrowedSigil => "&", + ast::ManagedSigil => "@", + ast::OwnedSigil => "~", + }.as_bytes()); + match decl.region { + Some(ref region) => { write!(f.buf, "{} ", *region); } + None => {} + } + write!(f.buf, "{}{}fn{}", PuritySpace(decl.purity), match decl.sigil { ast::OwnedSigil => format!("proc({})", decl.decl.inputs), @@ -328,33 +336,33 @@ impl fmt::Default for clean::Type { clean::Tuple(ref typs) => { f.buf.write("(".as_bytes()); for (i, typ) in typs.iter().enumerate() { - if i > 0 { f.buf.write(", ".as_bytes()) } + if i > 0 { f.buf.write(", ".as_bytes()); } write!(f.buf, "{}", *typ); } f.buf.write(")".as_bytes()); } - clean::Vector(ref t) => write!(f.buf, "[{}]", **t), + clean::Vector(ref t) => { write!(f.buf, "[{}]", **t); } clean::FixedVector(ref t, ref s) => { write!(f.buf, "[{}, ..{}]", **t, *s); } - clean::String => f.buf.write("str".as_bytes()), - clean::Bool => f.buf.write("bool".as_bytes()), - clean::Unit => f.buf.write("()".as_bytes()), - clean::Bottom => f.buf.write("!".as_bytes()), - clean::Unique(ref t) => write!(f.buf, "~{}", **t), + clean::String => { f.buf.write("str".as_bytes()); } + clean::Bool => { f.buf.write("bool".as_bytes()); } + clean::Unit => { f.buf.write("()".as_bytes()); } + clean::Bottom => { f.buf.write("!".as_bytes()); } + clean::Unique(ref t) => { write!(f.buf, "~{}", **t); } clean::Managed(m, ref t) => { write!(f.buf, "@{}{}", match m { clean::Mutable => "mut ", clean::Immutable => "", - }, **t) + }, **t); } clean::RawPointer(m, ref t) => { write!(f.buf, "*{}{}", match m { clean::Mutable => "mut ", clean::Immutable => "", - }, **t) + }, **t); } clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => { let lt = match *l { Some(ref l) => format!("{} ", *l), _ => ~"" }; @@ -367,20 +375,21 @@ impl fmt::Default for clean::Type { **ty); } } + Ok(()) } } impl fmt::Default for clean::FnDecl { - fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) { + fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", args = d.inputs, arrow = match d.output { clean::Unit => "no", _ => "yes" }, - ret = d.output); + ret = d.output) } } impl fmt::Default for ~[clean::Argument] { - fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) { + fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result { let mut args = ~""; for (i, input) in inputs.iter().enumerate() { if i > 0 { args.push_str(", "); } @@ -389,12 +398,12 @@ impl fmt::Default for ~[clean::Argument] { } args.push_str(format!("{}", input.type_)); } - f.buf.write(args.as_bytes()); + f.buf.write(args.as_bytes()) } } impl<'self> fmt::Default for Method<'self> { - fn fmt(m: &Method<'self>, f: &mut fmt::Formatter) { + fn fmt(m: &Method<'self>, f: &mut fmt::Formatter) -> fmt::Result { let Method(selfty, d) = *m; let mut args = ~""; match *selfty { @@ -427,31 +436,34 @@ impl<'self> fmt::Default for Method<'self> { args = args, arrow = match d.output { clean::Unit => "no", _ => "yes" }, ret = d.output); + Ok(()) } } impl fmt::Default for VisSpace { - fn fmt(v: &VisSpace, f: &mut fmt::Formatter) { + fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result { match **v { Some(ast::public) => { write!(f.buf, "pub "); } Some(ast::private) => { write!(f.buf, "priv "); } Some(ast::inherited) | None => {} } + Ok(()) } } impl fmt::Default for PuritySpace { - fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) { + fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result { match **p { - ast::unsafe_fn => write!(f.buf, "unsafe "), - ast::extern_fn => write!(f.buf, "extern "), + ast::unsafe_fn => { write!(f.buf, "unsafe "); } + ast::extern_fn => { write!(f.buf, "extern "); } ast::impure_fn => {} } + Ok(()) } } impl fmt::Default for clean::ViewPath { - fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result { match *v { clean::SimpleImport(ref name, ref src) => { if *name == src.path.segments.last().name { @@ -472,11 +484,12 @@ impl fmt::Default for clean::ViewPath { write!(f.buf, "\\};"); } } + Ok(()) } } impl fmt::Default for clean::ImportSource { - fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result { match v.did { // XXX: shouldn't be restricted to just local imports Some(did) if ast_util::is_local(did) => { @@ -484,16 +497,17 @@ impl fmt::Default for clean::ImportSource { } _ => { for (i, seg) in v.path.segments.iter().enumerate() { - if i > 0 { write!(f.buf, "::") } + if i > 0 { write!(f.buf, "::"); } write!(f.buf, "{}", seg.name); } } } + Ok(()) } } impl fmt::Default for clean::ViewListIdent { - fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { + fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result { match v.source { // XXX: shouldn't be limited to just local imports Some(did) if ast_util::is_local(did) => { @@ -506,6 +520,7 @@ impl fmt::Default for clean::ViewListIdent { }] }; resolved_path(f.buf, did.node, &path, false); + Ok(()) } _ => write!(f.buf, "{}", v.name), } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index ac7c50fdfd809..94d86bdf22f4b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -123,9 +123,11 @@ fn render(w: &mut io::Writer, s: &str) { } impl<'self> fmt::Default for Markdown<'self> { - fn fmt(md: &Markdown<'self>, fmt: &mut fmt::Formatter) { + fn fmt(md: &Markdown<'self>, fmt: &mut fmt::Formatter) -> fmt::Result { // This is actually common enough to special-case - if md.len() == 0 { return; } - render(fmt.buf, md.as_slice()); + if md.len() != 0 { + render(fmt.buf, md.as_slice()); + } + Ok(()) } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 819316313b677..b45bdefc0e8ee 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -271,7 +271,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) { if i > 0 { write!(w, ","); } write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}", item.ty, item.name, item.path, - item.desc.to_json().to_str()) + item.desc.to_json().to_str()); match item.parent { Some(id) => { write!(w, ",parent:'{}'", id); } None => {} @@ -320,15 +320,15 @@ fn write(dst: Path, contents: &str) { /// Makes a directory on the filesystem, failing the task if an error occurs and /// skipping if the directory already exists. fn mkdir(path: &Path) { - io::io_error::cond.trap(|err| { - error!("Couldn't create directory `{}`: {}", - path.display(), err.desc); - fail!() - }).inside(|| { - if !path.is_dir() { - fs::mkdir(path, io::UserRWX); + if path.is_dir() { return } + match fs::mkdir(path, io::UserRWX) { + Ok(()) => {} + Err(e) => { + fail!("Couldn't create directory `{}`: {}", + path.display(), e); } - }) + + } } /// Takes a path to a source file and cleans the path to it. This canonicalizes @@ -414,25 +414,19 @@ impl<'self> SourceCollector<'self> { let p = Path::new(filename); // Read the contents of the file - let mut contents = ~[]; + let mut contents; { - let mut buf = [0, ..1024]; // If we couldn't open this file, then just returns because it // probably means that it's some standard library macro thing and we // can't have the source to it anyway. - let mut r = match io::result(|| File::open(&p)) { + let mut r = match File::open(&p) { Ok(r) => r, // eew macro hacks Err(*) => return filename == "" }; // read everything - loop { - match r.read(buf) { - Some(n) => contents.push_all(buf.slice_to(n)), - None => break - } - } + contents = r.read_to_end().unwrap(); } let contents = str::from_utf8_owned(contents); @@ -860,7 +854,7 @@ impl<'self> Item<'self> { } impl<'self> fmt::Default for Item<'self> { - fn fmt(it: &Item<'self>, fmt: &mut fmt::Formatter) { + fn fmt(it: &Item<'self>, fmt: &mut fmt::Formatter) -> fmt::Result { match attr::find_stability(it.item.attrs.iter()) { Some(stability) => { write!(fmt.buf, @@ -895,11 +889,11 @@ impl<'self> fmt::Default for Item<'self> { // Write the breadcrumb trail header for the top write!(fmt.buf, "

"); match it.item.inner { - clean::ModuleItem(*) => write!(fmt.buf, "Module "), - clean::FunctionItem(*) => write!(fmt.buf, "Function "), - clean::TraitItem(*) => write!(fmt.buf, "Trait "), - clean::StructItem(*) => write!(fmt.buf, "Struct "), - clean::EnumItem(*) => write!(fmt.buf, "Enum "), + clean::ModuleItem(*) => { write!(fmt.buf, "Module "); } + clean::FunctionItem(*) => { write!(fmt.buf, "Function "); } + clean::TraitItem(*) => { write!(fmt.buf, "Trait "); } + clean::StructItem(*) => { write!(fmt.buf, "Struct "); } + clean::EnumItem(*) => { write!(fmt.buf, "Enum "); } _ => {} } let cur = it.cx.current.as_slice(); @@ -926,6 +920,8 @@ impl<'self> fmt::Default for Item<'self> { clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t), _ => {} } + + Ok(()) } } @@ -1048,12 +1044,13 @@ fn item_module(w: &mut Writer, cx: &Context, clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { struct Initializer<'self>(&'self str); impl<'self> fmt::Default for Initializer<'self> { - fn fmt(s: &Initializer<'self>, f: &mut fmt::Formatter) { - if s.len() == 0 { return; } + fn fmt(s: &Initializer<'self>, + f: &mut fmt::Formatter) -> fmt::Result { + if s.len() == 0 { return Ok(()); } write!(f.buf, " = "); let tag = if s.contains("\n") { "pre" } else { "code" }; write!(f.buf, "<{tag}>{}", - s.as_slice(), tag=tag); + s.as_slice(), tag=tag) } } @@ -1076,8 +1073,9 @@ fn item_module(w: &mut Writer, cx: &Context, write!(w, "extern mod {}", name.as_slice()); match *src { - Some(ref src) => write!(w, " = \"{}\"", - src.as_slice()), + Some(ref src) => { + write!(w, " = \"{}\"", src.as_slice()); + } None => {} } write!(w, ";"); @@ -1294,11 +1292,11 @@ fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) { match v.inner { clean::VariantItem(ref var) => { match var.kind { - clean::CLikeVariant => write!(w, "{}", name), + clean::CLikeVariant => { write!(w, "{}", name); } clean::TupleVariant(ref tys) => { write!(w, "{}(", name); for (i, ty) in tys.iter().enumerate() { - if i > 0 { write!(w, ", ") } + if i > 0 { write!(w, ", "); } write!(w, "{}", *ty); } write!(w, ")"); @@ -1368,7 +1366,7 @@ fn render_struct(w: &mut Writer, it: &clean::Item, if structhead {"struct "} else {""}, it.name.get_ref().as_slice()); match g { - Some(g) => write!(w, "{}", *g), + Some(g) => { write!(w, "{}", *g); } None => {} } match ty { @@ -1395,7 +1393,7 @@ fn render_struct(w: &mut Writer, it: &clean::Item, doctree::Tuple | doctree::Newtype => { write!(w, "("); for (i, field) in fields.iter().enumerate() { - if i > 0 { write!(w, ", ") } + if i > 0 { write!(w, ", "); } match field.inner { clean::StructFieldItem(ref field) => { write!(w, "{}", field.type_); @@ -1553,13 +1551,13 @@ fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) { } impl<'self> fmt::Default for Sidebar<'self> { - fn fmt(s: &Sidebar<'self>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Sidebar<'self>, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = s.cx; let it = s.item; write!(fmt.buf, "

"); let len = cx.current.len() - if it.is_mod() {1} else {0}; for (i, name) in cx.current.iter().take(len).enumerate() { - if i > 0 { write!(fmt.buf, "&\\#8203;::") } + if i > 0 { write!(fmt.buf, "&\\#8203;::"); } write!(fmt.buf, "{}", cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name); } @@ -1596,6 +1594,7 @@ impl<'self> fmt::Default for Sidebar<'self> { block(fmt.buf, "enum", "Enums", it, cx); block(fmt.buf, "trait", "Traits", it, cx); block(fmt.buf, "fn", "Functions", it, cx); + Ok(()) } } @@ -1618,7 +1617,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { } impl<'self> fmt::Default for Source<'self> { - fn fmt(s: &Source<'self>, fmt: &mut fmt::Formatter) { + fn fmt(s: &Source<'self>, fmt: &mut fmt::Formatter) -> fmt::Result { let lines = s.lines().len(); let mut cols = 0; let mut tmp = lines; @@ -1634,5 +1633,6 @@ impl<'self> fmt::Default for Source<'self> { write!(fmt.buf, "

");
         write!(fmt.buf, "{}", Escape(s.as_slice()));
         write!(fmt.buf, "
"); + Ok(()) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 977931eb42ac9..e2fbbabcd7635 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -263,8 +263,9 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output { /// run over the deserialized output. fn json_input(input: &str) -> Result { let input = match File::open(&Path::new(input)) { - Some(f) => f, - None => return Err(format!("couldn't open {} for reading", input)), + Ok(f) => f, + Err(e) => return Err(format!("couldn't open {} for reading: {}", + input, e)), }; match json::from_reader(@mut input as @mut io::Reader) { Err(s) => Err(s.to_str()), diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs index b1e3d1bd879ec..ee86d2a9f4971 100644 --- a/src/librustpkg/installed_packages.rs +++ b/src/librustpkg/installed_packages.rs @@ -13,13 +13,14 @@ use rustc::metadata::filesearch::rust_path; use path_util::*; use std::os; -use std::io; use std::io::fs; pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool { let workspaces = rust_path(); for p in workspaces.iter() { - let binfiles = io::ignore_io_error(|| fs::readdir(&p.join("bin"))); + let binfiles = match fs::readdir(&p.join("bin")) { + Ok(d) => d, Err(*) => return false, + }; for exec in binfiles.iter() { // FIXME (#9639): This needs to handle non-utf8 paths match exec.filestem_str() { @@ -31,7 +32,9 @@ pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool { } } } - let libfiles = io::ignore_io_error(|| fs::readdir(&p.join("lib"))); + let libfiles = match fs::readdir(&p.join("lib")) { + Ok(d) => d, Err(*) => return false, + }; for lib in libfiles.iter() { debug!("Full name: {}", lib.display()); match has_library(lib) { @@ -55,7 +58,9 @@ pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool { } pub fn has_library(p: &Path) -> Option<~str> { - let files = io::ignore_io_error(|| fs::readdir(p)); + let files = match fs::readdir(p) { + Ok(d) => d, Err(*) => return None, + }; for path in files.iter() { if path.extension_str() == Some(os::consts::DLL_EXTENSION) { let stuff : &str = path.filestem_str().expect("has_library: weird path"); diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index b93199e2c6179..275c964f9c690 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -12,7 +12,6 @@ extern mod extra; use target::*; use package_id::PkgId; -use std::io; use std::io::fs; use std::os; use context::*; @@ -302,7 +301,7 @@ impl PkgSrc { // Move clone_target to local. // First, create all ancestor directories. let moved = make_dir_rwx_recursive(&local.dir_path()) - && io::result(|| fs::rename(&clone_target, local)).is_ok(); + && fs::rename(&clone_target, local).is_ok(); if moved { Some(local.clone()) } else { None } } @@ -351,7 +350,7 @@ impl PkgSrc { let prefix = self.start_dir.components().len(); debug!("Matching against {}", self.id.short_name); - for pth in fs::walk_dir(&self.start_dir) { + for pth in fs::walk_dir(&self.start_dir).unwrap() { let maybe_known_crate_set = match pth.filename_str() { Some(filename) if filter(filename) => match filename { "lib.rs" => Some(&mut self.libs), diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 9d5b5e91fe27c..ce5aca803d86d 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -45,11 +45,11 @@ pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// and executable by the user. Returns true iff creation /// succeeded. pub fn make_dir_rwx(p: &Path) -> bool { - io::result(|| fs::mkdir(p, io::UserRWX)).is_ok() + fs::mkdir(p, io::UserRWX).is_ok() } pub fn make_dir_rwx_recursive(p: &Path) -> bool { - io::result(|| fs::mkdir_recursive(p, io::UserRWX)).is_ok() + fs::mkdir_recursive(p, io::UserRWX).is_ok() } // n.b. The next three functions ignore the package version right @@ -72,7 +72,7 @@ pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path, if !src_dir.is_dir() { return None } let mut found = None; - for p in fs::walk_dir(&src_dir) { + for p in fs::walk_dir(&src_dir).unwrap() { if p.is_dir() { if p == src_dir.join(&pkgid.path) || { let pf = p.filename_str(); @@ -215,7 +215,13 @@ pub fn system_library(sysroot: &Path, lib_name: &str) -> Option { fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option { debug!("Listing directory {}", dir_to_search.display()); +<<<<<<< HEAD let dir_contents = io::ignore_io_error(|| fs::readdir(dir_to_search)); +======= + let dir_contents = match fs::readdir(dir_to_search) { + Ok(d) => d, Err(*) => return None, + }; +>>>>>>> Remove io::io_error debug!("dir has {:?} entries", dir_contents.len()); let lib_prefix = format!("{}{}", os::consts::DLL_PREFIX, short_name); @@ -338,7 +344,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path, (Install, Lib) => target_lib_dir(workspace), (Install, _) => target_bin_dir(workspace) }; - if io::result(|| fs::mkdir_recursive(&result, io::UserRWX)).is_err() { + if fs::mkdir_recursive(&result, io::UserRWX).is_err() { cond.raise((result.clone(), format!("target_file_in_workspace couldn't \ create the {} dir (pkgid={}, workspace={}, what={:?}, where={:?}", subdir, pkgid.to_str(), workspace.display(), what, where))); diff --git a/src/librustpkg/source_control.rs b/src/librustpkg/source_control.rs index 702a849e4addd..444ce8de049f7 100644 --- a/src/librustpkg/source_control.rs +++ b/src/librustpkg/source_control.rs @@ -96,7 +96,7 @@ pub enum CloneResult { pub fn make_read_only(target: &Path) { // Now, make all the files in the target dir read-only - for p in fs::walk_dir(target) { + for p in fs::walk_dir(target).unwrap() { if !p.is_dir() { assert!(chmod_read_only(&p)); } diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 86c0fb2768016..9971e24d18822 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -199,13 +199,17 @@ fn add_git_tag(repo: &Path, tag: ~str) { } fn is_rwx(p: &Path) -> bool { - if !p.exists() { return false } - p.stat().perm & io::UserRWX == io::UserRWX + match p.stat() { + Ok(s) => s.perm & io::UserRWX == io::UserRWX, + Err(*) => false, + } } fn is_read_only(p: &Path) -> bool { - if !p.exists() { return false } - p.stat().perm & io::UserRWX == io::UserRead + match p.stat() { + Ok(s) => s.perm & io::UserRWX == io::UserRead, + Err(*) => false, + } } fn test_sysroot() -> Path { @@ -411,7 +415,7 @@ fn built_executable_exists(repo: &Path, short_name: &str) -> bool { fn remove_built_executable_file(p: &PkgId, workspace: &Path) { let exec = built_executable_in_workspace(&PkgId::new(p.short_name), workspace); match exec { - Some(r) => fs::unlink(&r), + Some(r) => { fs::unlink(&r); } None => () } } @@ -515,7 +519,7 @@ fn touch_source_file(workspace: &Path, pkgid: &PkgId) { fn touch_source_file(workspace: &Path, pkgid: &PkgId) { use conditions::bad_path::cond; let pkg_src_dir = workspace.join_many([~"src", pkgid.to_str()]); - let contents = fs::readdir(&pkg_src_dir); + let contents = fs::readdir(&pkg_src_dir).unwrap(); for p in contents.iter() { if p.extension_str() == Some("rs") { // should be able to do this w/o a process @@ -531,7 +535,6 @@ fn touch_source_file(workspace: &Path, pkgid: &PkgId) { /// Add a comment at the end fn frob_source_file(workspace: &Path, pkgid: &PkgId, filename: &str) { - use conditions::bad_path::cond; let pkg_src_dir = workspace.join_many([~"src", pkgid.to_str()]); let mut maybe_p = None; let maybe_file = pkg_src_dir.join(filename); @@ -542,12 +545,8 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId, filename: &str) { debug!("Frobbed? {:?}", maybe_p); match maybe_p { Some(ref p) => { - io::io_error::cond.trap(|e| { - cond.raise((p.clone(), format!("Bad path: {}", e.desc))); - }).inside(|| { - let mut w = File::open_mode(p, io::Append, io::Write); - w.write(bytes!("/* hi */\n")); - }) + let mut w = File::open_mode(p, io::Append, io::Write).unwrap(); + w.write(bytes!("/* hi */\n")); } None => fail!("frob_source_file failed to find a source file in {}", pkg_src_dir.display()) @@ -1968,7 +1967,7 @@ fn test_target_specific_build_dir() { workspace); assert!(target_build_dir(workspace).is_dir()); assert!(built_executable_exists(workspace, "foo")); - assert!(fs::readdir(&workspace.join("build")).len() == 1); + assert!(fs::readdir(&workspace.join("build")).unwrap().len() == 1); } #[test] @@ -1984,7 +1983,7 @@ fn test_target_specific_install_dir() { workspace); assert!(workspace.join_many([~"lib", host_triple()]).is_dir()); assert_lib_exists(workspace, &Path::new("foo"), NoVersion); - assert!(fs::readdir(&workspace.join("lib")).len() == 1); + assert!(fs::readdir(&workspace.join("lib")).unwrap().len() == 1); assert!(workspace.join("bin").is_dir()); assert_executable_exists(workspace, "foo"); } @@ -2442,5 +2441,8 @@ fn correct_error_dependency() { /// Returns true if p exists and is executable fn is_executable(p: &Path) -> bool { - p.exists() && p.stat().perm & io::UserExecute == io::UserExecute + match p.stat() { + Ok(stat) => stat.perm & io::UserExecute == io::UserExecute, + Err(*) => false, + } } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index ec5922cf67a71..525d7af91742b 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -643,7 +643,7 @@ fn debug_flags() -> ~[~str] { ~[] } pub fn datestamp(p: &Path) -> Option { debug!("Scrutinizing datestamp for {} - does it exist? {:?}", p.display(), p.exists()); - match io::result(|| p.stat()) { + match p.stat() { Ok(s) => { let out = s.modified; debug!("Date = {:?}", out); diff --git a/src/librustpkg/workcache_support.rs b/src/librustpkg/workcache_support.rs index 42f0aec6b7437..82f5d09a9cfee 100644 --- a/src/librustpkg/workcache_support.rs +++ b/src/librustpkg/workcache_support.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::io; use std::io::File; use extra::workcache; use sha1::{Digest, Sha1}; @@ -17,11 +16,11 @@ use sha1::{Digest, Sha1}; pub fn digest_file_with_date(path: &Path) -> ~str { use conditions::bad_path::cond; - match io::result(|| File::open(path).read_to_end()) { + match File::open(path).read_to_end() { Ok(bytes) => { let mut sha = Sha1::new(); sha.input(bytes); - let st = path.stat(); + let st = path.stat().unwrap(); sha.input_str(st.modified.to_str()); sha.result_str() } @@ -35,7 +34,7 @@ pub fn digest_file_with_date(path: &Path) -> ~str { /// Hashes only the last-modified time pub fn digest_only_date(path: &Path) -> ~str { let mut sha = Sha1::new(); - let st = path.stat(); + let st = path.stat().unwrap(); sha.input_str(st.modified.to_str()); sha.result_str() } diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 33ef4731405fa..51ff4d7becd88 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -462,17 +462,22 @@ use prelude::*; use cast; use char::Char; -use io::Decorator; +use io::{Decorator, IoResult}; use io::mem::MemWriter; use io; -use str; use repr; +use result::{Ok, Err}; +use str; use util; use vec; pub mod parse; pub mod rt; +/// A type which represents the result of a formatting operation. This error is +/// propagated upwards from the underlying io::Writer instance. +pub type Result = IoResult<()>; + /// A struct to represent both where to emit formatting strings to and how they /// should be formatted. A mutable version of this is passed to all formatting /// traits. @@ -499,7 +504,7 @@ pub struct Formatter<'self> { /// compile time it is ensured that the function and the value have the correct /// types, and then this struct is used to canonicalize arguments to one type. pub struct Argument<'self> { - priv formatter: extern "Rust" fn(&util::Void, &mut Formatter), + priv formatter: extern "Rust" fn(&util::Void, &mut Formatter) -> Result, priv value: &'self util::Void, } @@ -533,44 +538,44 @@ pub struct Arguments<'self> { /// to this trait. There is not an explicit way of selecting this trait to be /// used for formatting, it is only if no other format is specified. #[allow(missing_doc)] -pub trait Default { fn fmt(&Self, &mut Formatter); } +pub trait Default { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `b` character #[allow(missing_doc)] -pub trait Bool { fn fmt(&Self, &mut Formatter); } +pub trait Bool { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `c` character #[allow(missing_doc)] -pub trait Char { fn fmt(&Self, &mut Formatter); } +pub trait Char { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `i` and `d` characters #[allow(missing_doc)] -pub trait Signed { fn fmt(&Self, &mut Formatter); } +pub trait Signed { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `u` character #[allow(missing_doc)] -pub trait Unsigned { fn fmt(&Self, &mut Formatter); } +pub trait Unsigned { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `o` character #[allow(missing_doc)] -pub trait Octal { fn fmt(&Self, &mut Formatter); } +pub trait Octal { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `b` character #[allow(missing_doc)] -pub trait Binary { fn fmt(&Self, &mut Formatter); } +pub trait Binary { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `x` character #[allow(missing_doc)] -pub trait LowerHex { fn fmt(&Self, &mut Formatter); } +pub trait LowerHex { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `X` character #[allow(missing_doc)] -pub trait UpperHex { fn fmt(&Self, &mut Formatter); } +pub trait UpperHex { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `s` character #[allow(missing_doc)] -pub trait String { fn fmt(&Self, &mut Formatter); } +pub trait String { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `?` character #[allow(missing_doc)] -pub trait Poly { fn fmt(&Self, &mut Formatter); } +pub trait Poly { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `p` character #[allow(missing_doc)] -pub trait Pointer { fn fmt(&Self, &mut Formatter); } +pub trait Pointer { fn fmt(&Self, &mut Formatter) -> Result; } /// Format trait for the `f` character #[allow(missing_doc)] -pub trait Float { fn fmt(&Self, &mut Formatter); } +pub trait Float { fn fmt(&Self, &mut Formatter) -> Result; } /// The `write` function takes an output stream, a precompiled format string, /// and a list of arguments. The arguments will be formatted according to the @@ -588,15 +593,15 @@ pub trait Float { fn fmt(&Self, &mut Formatter); } /// let w: &mut io::Writer = ...; /// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world"); /// ``` -pub fn write(output: &mut io::Writer, args: &Arguments) { +pub fn write(output: &mut io::Writer, args: &Arguments) -> Result { unsafe { write_unsafe(output, args.fmt, args.args) } } /// The `writeln` function takes the same arguments as `write`, except that it /// will also write a newline (`\n`) character at the end of the format string. -pub fn writeln(output: &mut io::Writer, args: &Arguments) { - unsafe { write_unsafe(output, args.fmt, args.args) } - output.write(['\n' as u8]); +pub fn writeln(output: &mut io::Writer, args: &Arguments) -> Result { + if_ok!(unsafe { write_unsafe(output, args.fmt, args.args) }); + output.write(['\n' as u8]) } /// The `write_unsafe` function takes an output stream, a precompiled format @@ -621,7 +626,7 @@ pub fn writeln(output: &mut io::Writer, args: &Arguments) { /// format string. pub unsafe fn write_unsafe(output: &mut io::Writer, fmt: &[rt::Piece], - args: &[Argument]) { + args: &[Argument]) -> Result { let mut formatter = Formatter { flags: 0, width: None, @@ -633,8 +638,9 @@ pub unsafe fn write_unsafe(output: &mut io::Writer, curarg: args.iter(), }; for piece in fmt.iter() { - formatter.run(piece, None); + seq!(formatter.run(piece, None)); } + Ok(()) } /// The format function takes a precompiled format string and a list of @@ -690,10 +696,10 @@ impl<'self> Formatter<'self> { // at runtime. This consumes all of the compile-time statics generated by // the format! syntax extension. - fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) { + fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) -> Result { match *piece { - rt::String(s) => { self.buf.write(s.as_bytes()); } - rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); } + rt::String(s) => { self.buf.write(s.as_bytes()) } + rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()) } rt::Argument(ref arg) => { // Fill in the format parameters into the formatter self.fill = arg.format.fill; @@ -710,8 +716,8 @@ impl<'self> Formatter<'self> { // Then actually do some printing match arg.method { - None => { (value.formatter)(value.value, self); } - Some(ref method) => { self.execute(*method, value); } + None => { (value.formatter)(value.value, self) } + Some(ref method) => { self.execute(*method, value) } } } } @@ -732,7 +738,7 @@ impl<'self> Formatter<'self> { } } - fn execute(&mut self, method: &rt::Method, arg: Argument) { + fn execute(&mut self, method: &rt::Method, arg: Argument) -> Result { match *method { // Pluralization is selection upon a numeric value specified as the // parameter. @@ -775,7 +781,7 @@ impl<'self> Formatter<'self> { } } - self.runplural(value, *default); + self.runplural(value, *default) } // Select is just a matching against the string specified. @@ -788,14 +794,15 @@ impl<'self> Formatter<'self> { for s in selectors.iter() { if s.selector == value { for piece in s.result.iter() { - self.run(piece, Some(value)); + if_ok!(self.run(piece, Some(value))) } - return; + return Ok(()); } } for piece in default.iter() { - self.run(piece, Some(value)); + if_ok!(self.run(piece, Some(value))) } + return Ok(()); } } } @@ -803,9 +810,14 @@ impl<'self> Formatter<'self> { fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) { ::uint::to_str_bytes(value, 10, |buf| { let valuestr = str::from_utf8_slice(buf); + let mut ret = Ok(()); for piece in pieces.iter() { - self.run(piece, Some(valuestr)); + ret = self.run(piece, Some(valuestr)); + if ret.is_err() { + break + } } + ret }) } @@ -827,7 +839,7 @@ impl<'self> Formatter<'self> { /// This function will correctly account for the flags provided as well as /// the minimum width. It will not take precision into account. pub fn pad_integral(&mut self, s: &[u8], alternate_prefix: &str, - positive: bool) { + positive: bool) -> Result { use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad}; let mut actual_len = s.len(); @@ -843,21 +855,31 @@ impl<'self> Formatter<'self> { let mut signprinted = false; let sign = |this: &mut Formatter| { if !signprinted { - if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive { - this.buf.write(['+' as u8]); + let r1 = if this.flags & 1 << (FlagSignPlus as uint) != 0 && + positive + { + this.buf.write(['+' as u8]) } else if !positive { - this.buf.write(['-' as u8]); - } - if this.flags & 1 << (FlagAlternate as uint) != 0 { - this.buf.write(alternate_prefix.as_bytes()); - } + this.buf.write(['-' as u8]) + } else { + Ok(()) + }; + let r2 = r1.and_then(|()| { + if this.flags & 1 << (FlagAlternate as uint) != 0 { + this.buf.write(alternate_prefix.as_bytes()) + } else { + Ok(()) + } + }); signprinted = true; + r2 + } else { + Ok(()) } }; let emit = |this: &mut Formatter| { - sign(this); - this.buf.write(s); + sign(this).and_then(|()| this.buf.write(s)) }; match self.width { @@ -866,10 +888,10 @@ impl<'self> Formatter<'self> { Some(min) => { if self.flags & 1 << (FlagSignAwareZeroPad as uint) != 0 { self.fill = '0'; - sign(self); + if_ok!(sign(self)) } self.with_padding(min - actual_len, parse::AlignRight, |me| { - emit(me); + emit(me) }) } } @@ -886,11 +908,10 @@ impl<'self> Formatter<'self> { /// is longer than this length /// /// Notably this function ignored the `flag` parameters - pub fn pad(&mut self, s: &str) { + pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front if self.width.is_none() && self.precision.is_none() { - self.buf.write(s.as_bytes()); - return + return self.buf.write(s.as_bytes()); } // The `precision` field can be interpreted as a `max-width` for the // string being formatted @@ -902,8 +923,7 @@ impl<'self> Formatter<'self> { let char_len = s.char_len(); if char_len >= max { let nchars = ::uint::min(max, char_len); - self.buf.write(s.slice_chars(0, nchars).as_bytes()); - return + return self.buf.write(s.slice_chars(0, nchars).as_bytes()); } } None => {} @@ -925,7 +945,7 @@ impl<'self> Formatter<'self> { // up the minimum width with the specified string + some alignment. Some(width) => { self.with_padding(width - s.len(), parse::AlignLeft, |me| { - me.buf.write(s.as_bytes()); + me.buf.write(s.as_bytes()) }) } } @@ -934,29 +954,30 @@ impl<'self> Formatter<'self> { fn with_padding(&mut self, padding: uint, default: parse::Alignment, - f: |&mut Formatter|) { + f: |&mut Formatter| -> Result) -> Result { let align = match self.align { parse::AlignUnknown => default, parse::AlignLeft | parse::AlignRight => self.align }; if align == parse::AlignLeft { - f(self); + if_ok!(f(self)) } let mut fill = [0u8, ..4]; let len = self.fill.encode_utf8(fill); for _ in range(0, padding) { - self.buf.write(fill.slice_to(len)); + if_ok!(self.buf.write(fill.slice_to(len))) } if align == parse::AlignRight { - f(self); + if_ok!(f(self)) } + Ok(()) } } /// This is a function which calls are emitted to by the compiler itself to /// create the Argument structures that are passed into the `format` function. #[doc(hidden)] #[inline] -pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter), +pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result, t: &'a T) -> Argument<'a> { unsafe { Argument { @@ -983,23 +1004,23 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { // Implementations of the core formatting traits impl Bool for bool { - fn fmt(b: &bool, f: &mut Formatter) { - String::fmt(&(if *b {"true"} else {"false"}), f); + fn fmt(b: &bool, f: &mut Formatter) -> Result { + String::fmt(&(if *b {"true"} else {"false"}), f) } } impl<'self, T: str::Str> String for T { - fn fmt(s: &T, f: &mut Formatter) { - f.pad(s.as_slice()); + fn fmt(s: &T, f: &mut Formatter) -> Result { + f.pad(s.as_slice()) } } impl Char for char { - fn fmt(c: &char, f: &mut Formatter) { + fn fmt(c: &char, f: &mut Formatter) -> Result { let mut utf8 = [0u8, ..4]; let amt = c.encode_utf8(utf8); let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) }; - String::fmt(&s, f); + String::fmt(&s, f) } } @@ -1008,7 +1029,7 @@ macro_rules! int_base(($ty:ident, $into:ident, $base:expr, impl $name for $ty { fn fmt(c: &$ty, f: &mut Formatter) { ::$into::to_str_bytes(*c as $into, $base, |buf| { - f.pad_integral(buf, $prefix, true); + f.pad_integral(buf, $prefix, true) }) } } @@ -1017,7 +1038,7 @@ macro_rules! upper_hex(($ty:ident, $into:ident) => { impl UpperHex for $ty { fn fmt(c: &$ty, f: &mut Formatter) { ::$into::to_str_bytes(*c as $into, 16, |buf| { - upperhex(buf, f); + upperhex(buf, f) }) } } @@ -1025,7 +1046,7 @@ macro_rules! upper_hex(($ty:ident, $into:ident) => { // Not sure why, but this causes an "unresolved enum variant, struct or const" // when inlined into the above macro... #[doc(hidden)] -pub fn upperhex(buf: &[u8], f: &mut Formatter) { +pub fn upperhex(buf: &[u8], f: &mut Formatter) -> Result { let mut local = [0u8, ..16]; for i in ::iter::range(0, buf.len()) { local[i] = match buf[i] as char { @@ -1033,7 +1054,7 @@ pub fn upperhex(buf: &[u8], f: &mut Formatter) { c => c as u8, } } - f.pad_integral(local.slice_to(buf.len()), "0x", true); + f.pad_integral(local.slice_to(buf.len()), "0x", true) } // FIXME(#4375) shouldn't need an inner module @@ -1046,7 +1067,7 @@ macro_rules! integer(($signed:ident, $unsigned:ident) => { impl Signed for $signed { fn fmt(c: &$signed, f: &mut Formatter) { ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| { - f.pad_integral(buf, "", *c >= 0); + f.pad_integral(buf, "", *c >= 0) }) } } @@ -1071,13 +1092,13 @@ integer!(i64, u64) macro_rules! floating(($ty:ident) => { impl Float for $ty { - fn fmt(f: &$ty, fmt: &mut Formatter) { + fn fmt(f: &$ty, fmt: &mut Formatter) -> Result { // XXX: this shouldn't perform an allocation let s = match fmt.precision { Some(i) => ::$ty::to_str_exact(f.abs(), i), None => ::$ty::to_str_digits(f.abs(), 6) }; - fmt.pad_integral(s.as_bytes(), "", *f >= 0.0); + fmt.pad_integral(s.as_bytes(), "", *f >= 0.0) } } }) @@ -1085,39 +1106,36 @@ floating!(f32) floating!(f64) impl Poly for T { - fn fmt(t: &T, f: &mut Formatter) { + fn fmt(t: &T, f: &mut Formatter) -> Result { match (f.width, f.precision) { - (None, None) => { - repr::write_repr(f.buf, t); - } + (None, None) => repr::write_repr(f.buf, t), // If we have a specified width for formatting, then we have to make // this allocation of a new string - _ => { - let s = repr::repr_to_str(t); - f.pad(s); - } + _ => f.pad(repr::repr_to_str(t)), } } } impl Pointer for *T { - fn fmt(t: &*T, f: &mut Formatter) { + fn fmt(t: &*T, f: &mut Formatter) -> Result { f.flags |= 1 << (parse::FlagAlternate as uint); ::uint::to_str_bytes(*t as uint, 16, |buf| { - f.pad_integral(buf, "0x", true); + f.pad_integral(buf, "0x", true) }) } } impl Pointer for *mut T { - fn fmt(t: &*mut T, f: &mut Formatter) { Pointer::fmt(&(*t as *T), f) } + fn fmt(t: &*mut T, f: &mut Formatter) -> Result { + Pointer::fmt(&(*t as *T), f) + } } // Implementation of Default for various core types macro_rules! delegate(($ty:ty to $other:ident) => { impl<'self> Default for $ty { - fn fmt(me: &$ty, f: &mut Formatter) { + fn fmt(me: &$ty, f: &mut Formatter) -> Result { $other::fmt(me, f) } } @@ -1141,10 +1159,10 @@ delegate!(f32 to Float) delegate!(f64 to Float) impl Default for *T { - fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) } + fn fmt(me: &*T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) } } impl Default for *mut T { - fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) } + fn fmt(me: &*mut T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) } } // If you expected tests to be here, look instead at the run-pass/ifmt.rs test, diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index 5a671eea7a348..59ab7f076fe31 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -28,8 +28,9 @@ use container::Container; use iter::Iterator; +use result::Ok; use option::{Some, None}; -use io::Writer; +use io::{Writer, IoResult}; use str::OwnedStr; use to_bytes::IterBytes; use vec::ImmutableVector; @@ -265,7 +266,7 @@ macro_rules! compress ( impl Writer for SipState { // Methods for io::writer #[inline] - fn write(&mut self, msg: &[u8]) { + fn write(&mut self, msg: &[u8]) -> IoResult<()> { let length = msg.len(); self.length += length; @@ -281,7 +282,7 @@ impl Writer for SipState { t += 1; } self.ntail += length; - return; + return Ok(()); } let mut t = 0; @@ -323,10 +324,7 @@ impl Writer for SipState { t += 1 } self.ntail = left; - } - - fn flush(&mut self) { - // No-op + return Ok(()); } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 8c1897339cbef..55d990a1fe5ac 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -55,7 +55,7 @@ use prelude::*; use num; use vec; -use super::{Stream, Decorator}; +use super::{Reader, Writer, Stream, Decorator, IoResult}; // libuv recommends 64k buffers to maximize throughput // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA @@ -95,17 +95,12 @@ impl BufferedReader { } impl Buffer for BufferedReader { - fn fill<'a>(&'a mut self) -> &'a [u8] { + fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { if self.pos == self.cap { - match self.inner.read(self.buf) { - Some(cap) => { - self.pos = 0; - self.cap = cap; - } - None => {} - } + self.cap = if_ok!(self.inner.read(self.buf)); + self.pos = 0; } - return self.buf.slice(self.pos, self.cap); + return Ok(self.buf.slice(self.pos, self.cap)); } fn consume(&mut self, amt: uint) { @@ -115,18 +110,15 @@ impl Buffer for BufferedReader { } impl Reader for BufferedReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { let nread = { - let available = self.fill(); - if available.len() == 0 { - return None; - } + let available = if_ok!(self.fill_buffer()); let nread = num::min(available.len(), buf.len()); vec::bytes::copy_memory(buf, available, nread); nread }; self.pos += nread; - Some(nread) + Ok(nread) } fn eof(&mut self) -> bool { @@ -169,26 +161,27 @@ impl BufferedWriter { } impl Writer for BufferedWriter { - fn write(&mut self, buf: &[u8]) { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { if self.pos + buf.len() > self.buf.len() { - self.flush(); + if_ok!(self.flush()); } if buf.len() > self.buf.len() { - self.inner.write(buf); + self.inner.write(buf) } else { let dst = self.buf.mut_slice_from(self.pos); vec::bytes::copy_memory(dst, buf, buf.len()); self.pos += buf.len(); + Ok(()) } } - fn flush(&mut self) { + fn flush(&mut self) -> IoResult<()> { if self.pos != 0 { - self.inner.write(self.buf.slice_to(self.pos)); + if_ok!(self.inner.write(self.buf.slice_to(self.pos))); self.pos = 0; } - self.inner.flush(); + self.inner.flush() } } @@ -217,18 +210,21 @@ impl LineBufferedWriter { } impl Writer for LineBufferedWriter { - fn write(&mut self, buf: &[u8]) { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { match buf.iter().position(|&b| b == '\n' as u8) { Some(i) => { - self.inner.write(buf.slice_to(i + 1)); - self.inner.flush(); - self.inner.write(buf.slice_from(i + 1)); + seq!( + self.inner.write(buf.slice_to(i + 1)); + self.inner.flush(); + self.inner.write(buf.slice_from(i + 1)); + ); + Ok(()) } None => self.inner.write(buf), } } - fn flush(&mut self) { self.inner.flush() } + fn flush(&mut self) -> IoResult<()> { self.inner.flush() } } impl Decorator for LineBufferedWriter { @@ -240,7 +236,7 @@ impl Decorator for LineBufferedWriter { struct InternalBufferedWriter(BufferedWriter); impl Reader for InternalBufferedWriter { - fn read(&mut self, buf: &mut [u8]) -> Option { self.inner.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.inner.read(buf) } fn eof(&mut self) -> bool { self.inner.eof() } } @@ -268,18 +264,20 @@ impl BufferedStream { } impl Buffer for BufferedStream { - fn fill<'a>(&'a mut self) -> &'a [u8] { self.inner.fill() } + fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() } fn consume(&mut self, amt: uint) { self.inner.consume(amt) } } impl Reader for BufferedStream { - fn read(&mut self, buf: &mut [u8]) -> Option { self.inner.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.inner.read(buf) } fn eof(&mut self) -> bool { self.inner.eof() } } impl Writer for BufferedStream { - fn write(&mut self, buf: &[u8]) { self.inner.inner.write(buf) } - fn flush(&mut self) { self.inner.inner.flush() } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + self.inner.inner.write(buf) + } + fn flush(&mut self) -> IoResult<()> { self.inner.inner.flush() } } impl Decorator for BufferedStream { @@ -293,8 +291,9 @@ impl Decorator for BufferedStream { #[cfg(test)] mod test { use prelude::*; + use result::{Ok, Err}; use super::*; - use io; + use io::{IoResult, EndOfFile, standard_error}; use super::super::mem::{MemReader, MemWriter}; use Harness = extra::test::BenchHarness; @@ -325,28 +324,28 @@ mod test { let mut buf = [0, 0, 0]; let nread = reader.read(buf); - assert_eq!(Some(2), nread); + assert_eq!(Ok(2), nread); assert_eq!([0, 1, 0], buf); assert!(!reader.eof()); let mut buf = [0]; let nread = reader.read(buf); - assert_eq!(Some(1), nread); + assert_eq!(Ok(1), nread); assert_eq!([2], buf); assert!(!reader.eof()); let mut buf = [0, 0, 0]; let nread = reader.read(buf); - assert_eq!(Some(1), nread); + assert_eq!(Ok(1), nread); assert_eq!([3, 0, 0], buf); assert!(!reader.eof()); let nread = reader.read(buf); - assert_eq!(Some(1), nread); + assert_eq!(Ok(1), nread); assert_eq!([4, 0, 0], buf); assert!(reader.eof()); - assert_eq!(None, reader.read(buf)); + assert!(reader.read(buf).is_err()); } #[test] @@ -391,14 +390,17 @@ mod test { // newtype struct autoderef weirdness #[test] fn test_buffered_stream() { + use io; struct S; impl io::Writer for S { - fn write(&mut self, _: &[u8]) {} + fn write(&mut self, _: &[u8]) -> IoResult<()> { Ok(()) } } impl io::Reader for S { - fn read(&mut self, _: &mut [u8]) -> Option { None } + fn read(&mut self, _: &mut [u8]) -> IoResult { + Err(standard_error(EndOfFile)) + } fn eof(&mut self) -> bool { true } } @@ -414,11 +416,11 @@ mod test { fn test_read_until() { let inner = MemReader::new(~[0, 1, 2, 1, 0]); let mut reader = BufferedReader::with_capacity(2, inner); - assert_eq!(reader.read_until(0), Some(~[0])); - assert_eq!(reader.read_until(2), Some(~[1, 2])); - assert_eq!(reader.read_until(1), Some(~[1])); - assert_eq!(reader.read_until(8), Some(~[0])); - assert_eq!(reader.read_until(9), None); + assert_eq!(reader.read_until(0), Ok(~[0])); + assert_eq!(reader.read_until(2), Ok(~[1, 2])); + assert_eq!(reader.read_until(1), Ok(~[1])); + assert_eq!(reader.read_until(8), Ok(~[0])); + assert!(reader.read_until(9).is_err()); } #[test] diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 98dbec27fb961..1cd608953ba16 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -10,7 +10,7 @@ use option::Option; use comm::{GenericPort, GenericChan}; -use super::{Reader, Writer}; +use super::{Reader, Writer, IoResult}; struct PortReader

; @@ -19,7 +19,7 @@ impl> PortReader

{ } impl> Reader for PortReader

{ - fn read(&mut self, _buf: &mut [u8]) -> Option { fail!() } + fn read(&mut self, _buf: &mut [u8]) -> IoResult { fail!() } fn eof(&mut self) -> bool { fail!() } } @@ -31,7 +31,7 @@ impl> ChanWriter { } impl> Writer for ChanWriter { - fn write(&mut self, _buf: &[u8]) { fail!() } + fn write(&mut self, _buf: &[u8]) -> IoResult<()> { fail!() } } struct ReaderPort; diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index 564e664027f73..0748496a5926f 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -13,48 +13,8 @@ // XXX: Not sure how this should be structured // XXX: Iteration should probably be considered separately -use iter::Iterator; -use option::Option; -use io::{Reader, Decorator}; - -/// An iterator that reads a single byte on each iteration, -/// until `.read_byte()` returns `None`. -/// -/// # Notes about the Iteration Protocol -/// -/// The `ByteIterator` may yield `None` and thus terminate -/// an iteration, but continue to yield elements if iteration -/// is attempted again. -/// -/// # Failure -/// -/// Raises the same conditions as the `read` method, for -/// each call to its `.next()` method. -/// Yields `None` if the condition is handled. -pub struct ByteIterator { - priv reader: T, -} - -impl ByteIterator { - pub fn new(r: R) -> ByteIterator { - ByteIterator { reader: r } - } -} - -impl Decorator for ByteIterator { - fn inner(self) -> R { self.reader } - fn inner_ref<'a>(&'a self) -> &'a R { &self.reader } - fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.reader } -} - -impl<'self, R: Reader> Iterator for ByteIterator { - #[inline] - fn next(&mut self) -> Option { - self.reader.read_byte() - } -} - -pub fn u64_to_le_bytes(n: u64, size: uint, f: |v: &[u8]| -> T) -> T { +pub fn u64_to_le_bytes(n: u64, size: uint, + f: |v: &[u8]| -> T) -> T { assert!(size <= 8u); match size { 1u => f(&[n as u8]), @@ -136,9 +96,10 @@ pub fn u64_from_be_bytes(data: &[u8], #[cfg(test)] mod test { - use option::{None, Option, Some}; + use result::{Ok, Err}; + use option::{None, Some}; use io::mem::{MemReader, MemWriter}; - use io::{Reader, io_error, placeholder_error}; + use io::{Reader, standard_error, EndOfFile, IoUnavailable, IoResult}; use vec::ImmutableVector; struct InitialZeroByteReader { @@ -146,13 +107,13 @@ mod test { } impl Reader for InitialZeroByteReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { if self.count == 0 { self.count = 1; - Some(0) + Ok(0) } else { buf[0] = 10; - Some(1) + Ok(1) } } fn eof(&mut self) -> bool { @@ -163,8 +124,8 @@ mod test { struct EofReader; impl Reader for EofReader { - fn read(&mut self, _: &mut [u8]) -> Option { - None + fn read(&mut self, _: &mut [u8]) -> IoResult { + Err(standard_error(EndOfFile)) } fn eof(&mut self) -> bool { false @@ -174,9 +135,8 @@ mod test { struct ErroringReader; impl Reader for ErroringReader { - fn read(&mut self, _: &mut [u8]) -> Option { - io_error::cond.raise(placeholder_error()); - None + fn read(&mut self, _: &mut [u8]) -> IoResult { + Err(standard_error(IoUnavailable)) } fn eof(&mut self) -> bool { false @@ -188,16 +148,16 @@ mod test { } impl Reader for PartialReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { if self.count == 0 { self.count = 1; buf[0] = 10; buf[1] = 11; - Some(2) + Ok(2) } else { buf[0] = 12; buf[1] = 13; - Some(2) + Ok(2) } } fn eof(&mut self) -> bool { @@ -210,14 +170,13 @@ mod test { } impl Reader for ErroringLaterReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { if self.count == 0 { self.count = 1; buf[0] = 10; - Some(1) + Ok(1) } else { - io_error::cond.raise(placeholder_error()); - None + Err(standard_error(IoUnavailable)) } } fn eof(&mut self) -> bool { @@ -230,19 +189,19 @@ mod test { } impl Reader for ThreeChunkReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { if self.count == 0 { self.count = 1; buf[0] = 10; buf[1] = 11; - Some(2) + Ok(2) } else if self.count == 1 { self.count = 2; buf[0] = 12; buf[1] = 13; - Some(2) + Ok(2) } else { - None + Err(standard_error(EndOfFile)) } } fn eof(&mut self) -> bool { @@ -254,7 +213,7 @@ mod test { fn read_byte() { let mut reader = MemReader::new(~[10]); let byte = reader.read_byte(); - assert!(byte == Some(10)); + assert!(byte == Ok(10)); } #[test] @@ -263,57 +222,28 @@ mod test { count: 0, }; let byte = reader.read_byte(); - assert!(byte == Some(10)); + assert!(byte == Ok(10)); } #[test] fn read_byte_eof() { let mut reader = EofReader; let byte = reader.read_byte(); - assert!(byte == None); + assert!(byte.is_err()); } #[test] fn read_byte_error() { let mut reader = ErroringReader; - io_error::cond.trap(|_| { - }).inside(|| { - let byte = reader.read_byte(); - assert!(byte == None); - }); - } - - #[test] - fn bytes_0_bytes() { - let reader = InitialZeroByteReader { - count: 0, - }; - let byte = reader.bytes().next(); - assert!(byte == Some(10)); - } - - #[test] - fn bytes_eof() { - let reader = EofReader; - let byte = reader.bytes().next(); - assert!(byte == None); - } - - #[test] - fn bytes_error() { - let reader = ErroringReader; - let mut it = reader.bytes(); - io_error::cond.trap(|_| ()).inside(|| { - let byte = it.next(); - assert!(byte == None); - }) + let byte = reader.read_byte(); + assert!(byte.is_err()); } #[test] fn read_bytes() { let mut reader = MemReader::new(~[10, 11, 12, 13]); let bytes = reader.read_bytes(4); - assert!(bytes == ~[10, 11, 12, 13]); + assert!(bytes == Ok(~[10, 11, 12, 13])); } #[test] @@ -322,16 +252,16 @@ mod test { count: 0, }; let bytes = reader.read_bytes(4); - assert!(bytes == ~[10, 11, 12, 13]); + assert!(bytes == Ok(~[10, 11, 12, 13])); } #[test] fn read_bytes_eof() { let mut reader = MemReader::new(~[10, 11]); - io_error::cond.trap(|_| { - }).inside(|| { - assert!(reader.read_bytes(4) == ~[10, 11]); - }) + match reader.read_bytes(4) { + Ok(*) => fail!(), + Err((b, _)) => assert_eq!(b, ~[10, 11]), + } } #[test] @@ -356,11 +286,8 @@ mod test { fn push_bytes_eof() { let mut reader = MemReader::new(~[10, 11]); let mut buf = ~[8, 9]; - io_error::cond.trap(|_| { - }).inside(|| { - reader.push_bytes(&mut buf, 4); - assert!(buf == ~[8, 9, 10, 11]); - }) + reader.push_bytes(&mut buf, 4); + assert!(buf == ~[8, 9, 10, 11]); } #[test] @@ -369,14 +296,13 @@ mod test { count: 0, }; let mut buf = ~[8, 9]; - io_error::cond.trap(|_| { } ).inside(|| { - reader.push_bytes(&mut buf, 4); - }); + reader.push_bytes(&mut buf, 4); assert!(buf == ~[8, 9, 10]); } #[test] #[should_fail] + #[ignore] // FIXME(#7049): buf is still borrowed fn push_bytes_fail_reset_len() { // push_bytes unsafely sets the vector length. This is testing that // upon failure the length is reset correctly. @@ -399,7 +325,7 @@ mod test { count: 0, }; let buf = reader.read_to_end(); - assert!(buf == ~[10, 11, 12, 13]); + assert!(buf == Ok(~[10, 11, 12, 13])); } #[test] @@ -409,7 +335,7 @@ mod test { count: 0, }; let buf = reader.read_to_end(); - assert!(buf == ~[10, 11]); + assert!(buf == Ok(~[10, 11])); } #[test] @@ -423,7 +349,7 @@ mod test { let mut reader = MemReader::new(writer.inner()); for i in uints.iter() { - assert!(reader.read_le_u64() == *i); + assert!(reader.read_le_u64() == Ok(*i)); } } @@ -439,7 +365,7 @@ mod test { let mut reader = MemReader::new(writer.inner()); for i in uints.iter() { - assert!(reader.read_be_u64() == *i); + assert!(reader.read_be_u64() == Ok(*i)); } } @@ -456,7 +382,7 @@ mod test { for i in ints.iter() { // this tests that the sign extension is working // (comparing the values as i32 would not test this) - assert!(reader.read_be_int_n(4) == *i as i64); + assert!(reader.read_be_int_n(4) == Ok(*i as i64)); } } @@ -470,7 +396,7 @@ mod test { let mut reader = MemReader::new(writer.inner()); let f = reader.read_be_f32(); - assert!(f == 8.1250); + assert!(f == Ok(8.1250)); } #[test] @@ -482,8 +408,8 @@ mod test { writer.write_le_f32(f); let mut reader = MemReader::new(writer.inner()); - assert!(reader.read_be_f32() == 8.1250); - assert!(reader.read_le_f32() == 8.1250); + assert!(reader.read_be_f32() == Ok(8.1250)); + assert!(reader.read_le_f32() == Ok(8.1250)); } } diff --git a/src/libstd/io/flate.rs b/src/libstd/io/flate.rs deleted file mode 100644 index 8a5aa171eb805..0000000000000 --- a/src/libstd/io/flate.rs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Some various other I/O types - -// FIXME(#3660): should move to libextra - -use prelude::*; -use super::*; - -/// A Writer decorator that compresses using the 'deflate' scheme -pub struct DeflateWriter { - priv inner_writer: W -} - -impl DeflateWriter { - pub fn new(inner_writer: W) -> DeflateWriter { - DeflateWriter { - inner_writer: inner_writer - } - } -} - -impl Writer for DeflateWriter { - fn write(&mut self, _buf: &[u8]) { fail!() } - - fn flush(&mut self) { fail!() } -} - -impl Decorator for DeflateWriter { - fn inner(self) -> W { - match self { - DeflateWriter { inner_writer: w } => w - } - } - - fn inner_ref<'a>(&'a self) -> &'a W { - match *self { - DeflateWriter { inner_writer: ref w } => w - } - } - - fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { - match *self { - DeflateWriter { inner_writer: ref mut w } => w - } - } -} - -/// A Reader decorator that decompresses using the 'deflate' scheme -pub struct InflateReader { - priv inner_reader: R -} - -impl InflateReader { - pub fn new(inner_reader: R) -> InflateReader { - InflateReader { - inner_reader: inner_reader - } - } -} - -impl Reader for InflateReader { - fn read(&mut self, _buf: &mut [u8]) -> Option { fail!() } - - fn eof(&mut self) -> bool { fail!() } -} - -impl Decorator for InflateReader { - fn inner(self) -> R { - match self { - InflateReader { inner_reader: r } => r - } - } - - fn inner_ref<'a>(&'a self) -> &'a R { - match *self { - InflateReader { inner_reader: ref r } => r - } - } - - fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { - match *self { - InflateReader { inner_reader: ref mut r } => r - } - } -} - -#[cfg(test)] -mod test { - use prelude::*; - use super::*; - use super::super::mem::*; - use super::super::Decorator; - - use str; - - #[test] - #[ignore] - fn smoke_test() { - let mem_writer = MemWriter::new(); - let mut deflate_writer = DeflateWriter::new(mem_writer); - let in_msg = "test"; - let in_bytes = in_msg.as_bytes(); - deflate_writer.write(in_bytes); - deflate_writer.flush(); - let buf = deflate_writer.inner().inner(); - let mem_reader = MemReader::new(buf); - let mut inflate_reader = InflateReader::new(mem_reader); - let mut out_bytes = [0, .. 100]; - let bytes_read = inflate_reader.read(out_bytes).unwrap(); - assert_eq!(bytes_read, in_bytes.len()); - let out_msg = str::from_utf8(out_bytes); - assert!(in_msg == out_msg); - } -} diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index d1502df047e70..c506004d91693 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -48,13 +48,13 @@ particular bits of it, etc. use c_str::ToCStr; use clone::Clone; use iter::Iterator; -use super::{Reader, Writer, Seek}; +use super::{Reader, Writer, Seek, IoResult, EndOfFile, standard_error}; use super::{SeekStyle, Read, Write, Open, IoError, Truncate, - FileMode, FileAccess, FileStat, io_error, FilePermission}; + FileMode, FileAccess, FileStat, FilePermission}; use rt::rtio::{RtioFileStream, IoFactory, with_local_io}; use io; use option::{Some, None, Option}; -use result::{Ok, Err, Result}; +use result::{Ok, Err}; use path; use path::{Path, GenericPath}; use vec::{OwnedVector, ImmutableVector}; @@ -75,18 +75,6 @@ pub struct File { priv last_nread: int, } -fn io_raise(f: |io: &mut IoFactory| -> Result) -> Option { - with_local_io(|io| { - match f(io) { - Ok(t) => Some(t), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } - }) -} - impl File { /// Open a file at `path` in the mode specified by the `mode` and `access` /// arguments @@ -131,19 +119,14 @@ impl File { /// * Filesystem-level errors (full disk, etc) pub fn open_mode(path: &Path, mode: FileMode, - access: FileAccess) -> Option { with_local_io(|io| { - match io.fs_open(&path.to_c_str(), mode, access) { - Ok(fd) => Some(File { + io.fs_open(&path.to_c_str(), mode, access).map(|fd| { + File { path: path.clone(), fd: fd, last_nread: -1 - }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None } - } + }) }) } @@ -158,7 +141,7 @@ impl File { /// use std::io::File; /// /// let contents = File::open(&Path::new("foo.txt")).read_to_end(); - pub fn open(path: &Path) -> Option { + pub fn open(path: &Path) -> IoResult { File::open_mode(path, Open, Read) } @@ -174,7 +157,7 @@ impl File { /// /// let mut f = File::create(&Path::new("foo.txt")); /// f.write(bytes!("This is a sample file")); - pub fn create(path: &Path) -> Option { + pub fn create(path: &Path) -> IoResult { File::open_mode(path, Truncate, Write) } @@ -190,8 +173,8 @@ impl File { /// # Errors /// /// This function will raise on the `io_error` condition on failure. - pub fn fsync(&mut self) { - self.fd.fsync().map_err(|e| io_error::cond.raise(e)); + pub fn fsync(&mut self) -> IoResult<()> { + self.fd.fsync() } /// This function is similar to `fsync`, except that it may not synchronize @@ -202,8 +185,8 @@ impl File { /// # Errors /// /// This function will raise on the `io_error` condition on failure. - pub fn datasync(&mut self) { - self.fd.datasync().map_err(|e| io_error::cond.raise(e)); + pub fn datasync(&mut self) -> IoResult<()> { + self.fd.datasync() } /// Either truncates or extends the underlying file, updating the size of @@ -218,8 +201,8 @@ impl File { /// # Errors /// /// On error, this function will raise on the `io_error` condition. - pub fn truncate(&mut self, size: i64) { - self.fd.truncate(size).map_err(|e| io_error::cond.raise(e)); + pub fn truncate(&mut self, offset: i64) -> IoResult<()> { + self.fd.truncate(offset) } } @@ -243,8 +226,8 @@ impl File { /// This function will raise an `io_error` condition if the path points to a /// directory, the user lacks permissions to remove the file, or if some /// other filesystem-level error occurs. -pub fn unlink(path: &Path) { - io_raise(|io| io.fs_unlink(&path.to_c_str())); +pub fn unlink(path: &Path) -> IoResult<()> { + with_local_io(|io| io.fs_unlink(&path.to_c_str())) } /// Given a path, query the file system to get information about a file, @@ -261,7 +244,7 @@ pub fn unlink(path: &Path) { /// use std::io::fs; /// /// let p = Path::new("/some/file/path.txt"); -/// match io::result(|| fs::stat(&p)) { +/// match fs::stat(&p) { /// Ok(stat) => { /* ... */ } /// Err(e) => { /* handle error */ } /// } @@ -271,32 +254,8 @@ pub fn unlink(path: &Path) { /// This call will raise an `io_error` condition if the user lacks the /// requisite permissions to perform a `stat` call on the given path or if /// there is no entry in the filesystem at the provided path. -pub fn stat(path: &Path) -> FileStat { - io_raise(|io| io.fs_stat(&path.to_c_str())).unwrap_or_else(dummystat) -} - -fn dummystat() -> FileStat { - FileStat { - path: Path::new(""), - size: 0, - kind: io::TypeFile, - perm: 0, - created: 0, - modified: 0, - accessed: 0, - unstable: io::UnstableFileStat { - device: 0, - inode: 0, - rdev: 0, - nlink: 0, - uid: 0, - gid: 0, - blksize: 0, - blocks: 0, - flags: 0, - gen: 0, - } - } +pub fn stat(path: &Path) -> IoResult { + with_local_io(|io| io.fs_stat(&path.to_c_str())) } /// Perform the same operation as the `stat` function, except that this @@ -307,8 +266,8 @@ fn dummystat() -> FileStat { /// # Errors /// /// See `stat` -pub fn lstat(path: &Path) -> FileStat { - io_raise(|io| io.fs_lstat(&path.to_c_str())).unwrap_or_else(dummystat) +pub fn lstat(path: &Path) -> IoResult { + with_local_io(|io| io.fs_lstat(&path.to_c_str())) } /// Rename a file or directory to a new name. @@ -325,8 +284,8 @@ pub fn lstat(path: &Path) -> FileStat { /// Will raise an `io_error` condition if the provided `path` doesn't exist, /// the process lacks permissions to view the contents, or if some other /// intermittent I/O error occurs. -pub fn rename(from: &Path, to: &Path) { - io_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str())); +pub fn rename(from: &Path, to: &Path) -> IoResult<()> { + with_local_io(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str())) } /// Copies the contents of one file to another. This function will also @@ -355,27 +314,28 @@ pub fn rename(from: &Path, to: &Path) { /// Note that this copy is not atomic in that once the destination is /// ensured to not exist, there is nothing preventing the destination from /// being created and then destroyed by this operation. -pub fn copy(from: &Path, to: &Path) { +pub fn copy(from: &Path, to: &Path) -> IoResult<()> { if !from.is_file() { - return io_error::cond.raise(IoError { + return Err(IoError { kind: io::MismatchedFileTypeForOperation, desc: "the source path is not an existing file", detail: None, }); } - let mut reader = match File::open(from) { Some(f) => f, None => return }; - let mut writer = match File::create(to) { Some(f) => f, None => return }; + let mut reader = if_ok!(File::open(from)); + let mut writer = if_ok!(File::create(to)); let mut buf = [0, ..io::DEFAULT_BUF_SIZE]; loop { match reader.read(buf) { - Some(amt) => writer.write(buf.slice_to(amt)), - None => break + Ok(amt) => if_ok!(writer.write(buf.slice_to(amt))), + Err(ref e) if e.kind == EndOfFile => break, + Err(e) => return Err(e) } } - chmod(to, from.stat().perm) + chmod(to, from.stat().unwrap().perm) } /// Changes the permission mode bits found on a file or a directory. This @@ -396,8 +356,8 @@ pub fn copy(from: &Path, to: &Path) { /// If this funciton encounters an I/O error, it will raise on the `io_error` /// condition. Some possible error situations are not having the permission to /// change the attributes of a file or the file not existing. -pub fn chmod(path: &Path, mode: io::FilePermission) { - io_raise(|io| io.fs_chmod(&path.to_c_str(), mode)); +pub fn chmod(path: &Path, mode: io::FilePermission) -> IoResult<()> { + with_local_io(|io| io.fs_chmod(&path.to_c_str(), mode)) } /// Change the user and group owners of a file at the specified path. @@ -405,8 +365,8 @@ pub fn chmod(path: &Path, mode: io::FilePermission) { /// # Errors /// /// This funtion will raise on the `io_error` condition on failure. -pub fn chown(path: &Path, uid: int, gid: int) { - io_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid)); +pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> { + with_local_io(|io| io.fs_chown(&path.to_c_str(), uid, gid)) } /// Creates a new hard link on the filesystem. The `dst` path will be a @@ -416,8 +376,8 @@ pub fn chown(path: &Path, uid: int, gid: int) { /// # Errors /// /// This function will raise on the `io_error` condition on failure. -pub fn link(src: &Path, dst: &Path) { - io_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str())); +pub fn link(src: &Path, dst: &Path) -> IoResult<()> { + with_local_io(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str())) } /// Creates a new symbolic link on the filesystem. The `dst` path will be a @@ -426,8 +386,8 @@ pub fn link(src: &Path, dst: &Path) { /// # Errors /// /// This function will raise on the `io_error` condition on failure. -pub fn symlink(src: &Path, dst: &Path) { - io_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str())); +pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { + with_local_io(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str())) } /// Reads a symlink, returning the file that the symlink points to. @@ -437,8 +397,8 @@ pub fn symlink(src: &Path, dst: &Path) { /// This function will raise on the `io_error` condition on failure. Failure /// conditions include reading a file that does not exist or reading a file /// which is not a symlink. -pub fn readlink(path: &Path) -> Option { - io_raise(|io| io.fs_readlink(&path.to_c_str())) +pub fn readlink(path: &Path) -> IoResult { + with_local_io(|io| io.fs_readlink(&path.to_c_str())) } /// Create a new, empty directory at the provided path @@ -457,8 +417,8 @@ pub fn readlink(path: &Path) -> Option { /// This call will raise an `io_error` condition if the user lacks permissions /// to make a new directory at the provided path, or if the directory already /// exists. -pub fn mkdir(path: &Path, mode: FilePermission) { - io_raise(|io| io.fs_mkdir(&path.to_c_str(), mode)); +pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> { + with_local_io(|io| io.fs_mkdir(&path.to_c_str(), mode)) } /// Remove an existing, empty directory @@ -476,8 +436,8 @@ pub fn mkdir(path: &Path, mode: FilePermission) { /// This call will raise an `io_error` condition if the user lacks permissions /// to remove the directory at the provided path, or if the directory isn't /// empty. -pub fn rmdir(path: &Path) { - io_raise(|io| io.fs_rmdir(&path.to_c_str())); +pub fn rmdir(path: &Path) -> IoResult<()> { + with_local_io(|io| io.fs_rmdir(&path.to_c_str())) } /// Retrieve a vector containing all entries within a provided directory @@ -503,15 +463,15 @@ pub fn rmdir(path: &Path) { /// Will raise an `io_error` condition if the provided `from` doesn't exist, /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file -pub fn readdir(path: &Path) -> ~[Path] { - io_raise(|io| io.fs_readdir(&path.to_c_str(), 0)).unwrap_or_else(|| ~[]) +pub fn readdir(path: &Path) -> IoResult<~[Path]> { + with_local_io(|io| io.fs_readdir(&path.to_c_str(), 0)) } /// Returns an iterator which will recursively walk the directory structure /// rooted at `path`. The path given will not be iterated over, and this will /// perform iteration in a top-down order. -pub fn walk_dir(path: &Path) -> WalkIterator { - WalkIterator { stack: readdir(path) } +pub fn walk_dir(path: &Path) -> IoResult { + readdir(path).map(|entries| WalkIterator { stack: entries }) } /// An iterator which walks over a directory @@ -524,7 +484,7 @@ impl Iterator for WalkIterator { match self.stack.shift_opt() { Some(path) => { if path.is_dir() { - self.stack.push_all_move(readdir(&path)); + self.stack.push_all_move(readdir(&path).unwrap()); } Some(path) } @@ -541,14 +501,14 @@ impl Iterator for WalkIterator { /// This function will raise on the `io_error` condition if an error /// happens, see `fs::mkdir` for more information about error conditions /// and performance. -pub fn mkdir_recursive(path: &Path, mode: FilePermission) { +pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> { // tjc: if directory exists but with different permissions, // should we return false? if path.is_dir() { - return + return Ok(()); } if path.filename().is_some() { - mkdir_recursive(&path.dir_path(), mode); + if_ok!(mkdir_recursive(&path.dir_path(), mode)); } mkdir(path, mode) } @@ -561,17 +521,17 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) { /// This function will raise on the `io_error` condition if an error /// happens. See `file::unlink` and `fs::readdir` for possible error /// conditions. -pub fn rmdir_recursive(path: &Path) { - let children = readdir(path); +pub fn rmdir_recursive(path: &Path) -> IoResult<()> { + let children = if_ok!(readdir(path)); for child in children.iter() { if child.is_dir() { - rmdir_recursive(child); + if_ok!(rmdir_recursive(child)); } else { - unlink(child); + if_ok!(unlink(child)); } } // Directory should now be empty - rmdir(path); + rmdir(path) } /// Changes the timestamps for a file's last modification and access time. @@ -584,27 +544,21 @@ pub fn rmdir_recursive(path: &Path) { /// This function will raise on the `io_error` condition if an error /// happens. // FIXME(#10301) these arguments should not be u64 -pub fn change_file_times(path: &Path, atime: u64, mtime: u64) { - io_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime)); +pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> { + with_local_io(|io| io.fs_utime(&path.to_c_str(), atime, mtime)) } impl Reader for File { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { match self.fd.read(buf) { Ok(read) => { self.last_nread = read; match read { - 0 => None, - _ => Some(read as uint) + 0 => Err(standard_error(EndOfFile)), + n => Ok(n as uint) } }, - Err(ioerr) => { - // EOF is indicated by returning None - if ioerr.kind != io::EndOfFile { - io_error::cond.raise(ioerr); - } - return None; - } + Err(ioerr) => Err(ioerr) } } @@ -612,39 +566,17 @@ impl Reader for File { } impl Writer for File { - fn write(&mut self, buf: &[u8]) { - match self.fd.write(buf) { - Ok(()) => (), - Err(ioerr) => { - io_error::cond.raise(ioerr); - } - } - } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.fd.write(buf) } } impl Seek for File { - fn tell(&self) -> u64 { - let res = self.fd.tell(); - match res { - Ok(cursor) => cursor, - Err(ioerr) => { - io_error::cond.raise(ioerr); - return -1; - } - } - } + fn tell(&self) -> IoResult { self.fd.tell() } - fn seek(&mut self, pos: i64, style: SeekStyle) { - match self.fd.seek(pos, style) { - Ok(_) => { - // successful seek resets EOF indicator - self.last_nread = -1; - () - }, - Err(ioerr) => { - io_error::cond.raise(ioerr); - } - } + fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> { + if_ok!(self.fd.seek(pos, style)); + // successful seek resets EOF indicator + self.last_nread = -1; + Ok(()) } } @@ -654,7 +586,7 @@ impl path::Path { /// Consult the `file::stat` documentation for more info. /// /// This call preserves identical runtime/error semantics with `file::stat`. - pub fn stat(&self) -> FileStat { stat(self) } + pub fn stat(&self) -> IoResult { stat(self) } /// Boolean value indicator whether the underlying file exists on the local /// filesystem. This will return true if the path points to either a @@ -664,7 +596,7 @@ impl path::Path { /// /// Will not raise a condition pub fn exists(&self) -> bool { - io::result(|| self.stat()).is_ok() + self.stat().is_ok() } /// Whether the underlying implemention (be it a file path, or something @@ -676,7 +608,7 @@ impl path::Path { /// /// Will not raise a condition pub fn is_file(&self) -> bool { - match io::result(|| self.stat()) { + match self.stat() { Ok(s) => s.kind == io::TypeFile, Err(*) => false } @@ -691,7 +623,7 @@ impl path::Path { /// /// Will not raise a condition pub fn is_dir(&self) -> bool { - match io::result(|| self.stat()) { + match self.stat() { Ok(s) => s.kind == io::TypeDirectory, Err(*) => false } @@ -702,8 +634,7 @@ impl path::Path { #[allow(unused_imports)] mod test { use prelude::*; - use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open, - ReadWrite}; + use io::{SeekSet, SeekCur, SeekEnd, Read, Open, ReadWrite}; use io; use str; use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive, @@ -800,6 +731,16 @@ mod test { assert!(called); }) + test!(fn invalid_path_error() { + let filename = &Path::new("./tmp/file_that_does_not_exist.txt"); + assert!(File::open_mode(filename, Open, Read).is_err()); + }) + + test!(fn file_test_iounlinking_invalid_path_should_raise_condition() { + let filename = &Path::new("./tmp/file_another_file_that_does_not_exist.txt"); + assert!(unlink(filename).is_err()); + }) + test!(fn file_test_io_non_positional_read() { let message = "ten-four"; let mut read_mem = [0, .. 8]; @@ -840,9 +781,9 @@ mod test { { let mut read_stream = File::open_mode(filename, Open, Read); read_stream.seek(set_cursor as i64, SeekSet); - tell_pos_pre_read = read_stream.tell(); + tell_pos_pre_read = read_stream.tell().unwrap(); read_stream.read(read_mem); - tell_pos_post_read = read_stream.tell(); + tell_pos_post_read = read_stream.tell().unwrap(); } unlink(filename); let read_str = str::from_utf8(read_mem); @@ -916,7 +857,7 @@ mod test { let msg = "hw"; fs.write(msg.as_bytes()); } - let stat_res = stat(filename); + let stat_res = stat(filename).unwrap(); assert_eq!(stat_res.kind, io::TypeFile); unlink(filename); }) @@ -925,7 +866,7 @@ mod test { let tmpdir = tmpdir(); let filename = &tmpdir.join("file_stat_correct_on_is_dir"); mkdir(filename, io::UserRWX); - let stat_res = filename.stat(); + let stat_res = filename.stat().unwrap(); assert!(stat_res.kind == io::TypeDirectory); rmdir(filename); }) @@ -971,7 +912,7 @@ mod test { let msg = msg_str.as_bytes(); w.write(msg); } - let files = readdir(dir); + let files = readdir(dir).unwrap(); let mut mem = [0u8, .. 4]; for f in files.iter() { { @@ -1026,7 +967,7 @@ mod test { test!(fn copy_file_does_not_exist() { let from = Path::new("test/nonexistent-bogus-path"); let to = Path::new("test/other-bogus-path"); - match io::result(|| copy(&from, &to)) { + match copy(&from, &to) { Ok(*) => fail!(), Err(*) => { assert!(!from.exists()); @@ -1042,10 +983,10 @@ mod test { File::create(&input).write(bytes!("hello")); copy(&input, &out); - let contents = File::open(&out).read_to_end(); + let contents = File::open(&out).read_to_end().unwrap(); assert_eq!(contents.as_slice(), bytes!("hello")); - assert_eq!(input.stat().perm, out.stat().perm); + assert_eq!(input.stat().unwrap().perm, out.stat().unwrap().perm); }) test!(fn copy_file_dst_dir() { @@ -1053,7 +994,7 @@ mod test { let out = tmpdir.join("out"); File::create(&out); - match io::result(|| copy(&out, &*tmpdir)) { + match copy(&out, &tmpdir) { Ok(*) => fail!(), Err(*) => {} } }) @@ -1068,14 +1009,14 @@ mod test { copy(&input, &output); assert_eq!(File::open(&output).read_to_end(), - (bytes!("foo")).to_owned()); + Ok((bytes!("foo")).to_owned())); }) test!(fn copy_file_src_dir() { let tmpdir = tmpdir(); let out = tmpdir.join("out"); - match io::result(|| copy(&*tmpdir, &out)) { + match copy(&tmpdir, &out) { Ok(*) => fail!(), Err(*) => {} } assert!(!out.exists()); @@ -1089,7 +1030,7 @@ mod test { File::create(&input); chmod(&input, io::UserRead); copy(&input, &out); - assert!(out.stat().perm & io::UserWrite == 0); + assert!(out.stat().unwrap().perm & io::UserWrite == 0); chmod(&input, io::UserFile); chmod(&out, io::UserFile); @@ -1103,11 +1044,10 @@ mod test { File::create(&input).write("foobar".as_bytes()); symlink(&input, &out); - if cfg!(not(windows)) { - assert_eq!(lstat(&out).kind, io::TypeSymlink); - } - assert_eq!(stat(&out).size, stat(&input).size); - assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned()); + assert_eq!(lstat(&out).unwrap().kind, io::TypeSymlink); + assert_eq!(stat(&out).unwrap().size, stat(&input).unwrap().size); + assert_eq!(File::open(&out).read_to_end(), + Ok((bytes!("foobar")).to_owned())); }) #[cfg(not(windows))] // apparently windows doesn't like symlinks @@ -1120,7 +1060,7 @@ mod test { test!(fn readlink_not_symlink() { let tmpdir = tmpdir(); - match io::result(|| readlink(&*tmpdir)) { + match readlink(&tmpdir) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } @@ -1133,20 +1073,19 @@ mod test { File::create(&input).write("foobar".as_bytes()); link(&input, &out); - if cfg!(not(windows)) { - assert_eq!(lstat(&out).kind, io::TypeFile); - assert_eq!(stat(&out).unstable.nlink, 2); - } - assert_eq!(stat(&out).size, stat(&input).size); - assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned()); + assert_eq!(lstat(&out).unwrap().kind, io::TypeFile); + assert_eq!(stat(&out).unwrap().size, stat(&input).unwrap().size); + assert_eq!(stat(&out).unwrap().unstable.nlink, 2); + assert_eq!(File::open(&out).read_to_end(), + Ok((bytes!("foobar")).to_owned())); // can't link to yourself - match io::result(|| link(&input, &input)) { + match link(&input, &input) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } // can't link to something that doesn't exist - match io::result(|| link(&tmpdir.join("foo"), &tmpdir.join("bar"))) { + match link(&tmpdir.join("foo"), &tmpdir.join("bar")) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } @@ -1157,11 +1096,11 @@ mod test { let file = tmpdir.join("in.txt"); File::create(&file); - assert!(stat(&file).perm & io::UserWrite == io::UserWrite); + assert!(stat(&file).unwrap().perm & io::UserWrite == io::UserWrite); chmod(&file, io::UserRead); - assert!(stat(&file).perm & io::UserWrite == 0); + assert!(stat(&file).unwrap().perm & io::UserWrite == 0); - match io::result(|| chmod(&tmpdir.join("foo"), io::UserRWX)) { + match chmod(&tmpdir.join("foo"), io::UserRWX) { Ok(*) => fail!("wanted a failure"), Err(*) => {} } @@ -1191,33 +1130,32 @@ mod test { file.fsync(); // Do some simple things with truncation - assert_eq!(stat(&path).size, 3); + assert_eq!(stat(&path).unwrap().size, 3); file.truncate(10); - assert_eq!(stat(&path).size, 10); + assert_eq!(stat(&path).unwrap().size, 10); file.write(bytes!("bar")); file.fsync(); - assert_eq!(stat(&path).size, 10); + assert_eq!(stat(&path).unwrap().size, 10); assert_eq!(File::open(&path).read_to_end(), - (bytes!("foobar", 0, 0, 0, 0)).to_owned()); + Ok((bytes!("foobar", 0, 0, 0, 0)).to_owned())); // Truncate to a smaller length, don't seek, and then write something. // Ensure that the intermediate zeroes are all filled in (we're seeked // past the end of the file). file.truncate(2); - assert_eq!(stat(&path).size, 2); + assert_eq!(stat(&path).unwrap().size, 2); file.write(bytes!("wut")); file.fsync(); - assert_eq!(stat(&path).size, 9); + assert_eq!(stat(&path).unwrap().size, 9); assert_eq!(File::open(&path).read_to_end(), - (bytes!("fo", 0, 0, 0, 0, "wut")).to_owned()); - util::ignore(file); + Ok((bytes!("fo", 0, 0, 0, 0, "wut")).to_owned())); + free(file); }) test!(fn open_flavors() { let tmpdir = tmpdir(); - match io::result(|| File::open_mode(&tmpdir.join("a"), io::Open, - io::Read)) { + match File::open_mode(&tmpdir.join("a"), io::Open, io::Read) { Ok(*) => fail!(), Err(*) => {} } File::open_mode(&tmpdir.join("b"), io::Open, io::Write).unwrap(); @@ -1232,23 +1170,23 @@ mod test { { let mut f = File::open_mode(&tmpdir.join("h"), io::Open, io::Read).unwrap(); - match io::result(|| f.write("wut".as_bytes())) { + match f.write("wut".as_bytes()) { Ok(*) => fail!(), Err(*) => {} } } - assert_eq!(stat(&tmpdir.join("h")).size, 3); + assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 3); { let mut f = File::open_mode(&tmpdir.join("h"), io::Append, io::Write).unwrap(); f.write("bar".as_bytes()); } - assert_eq!(stat(&tmpdir.join("h")).size, 6); + assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 6); { let mut f = File::open_mode(&tmpdir.join("h"), io::Truncate, io::Write).unwrap(); f.write("bar".as_bytes()); } - assert_eq!(stat(&tmpdir.join("h")).size, 3); + assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 3); }) #[test] @@ -1258,15 +1196,17 @@ mod test { File::create(&path); change_file_times(&path, 1000, 2000); - assert_eq!(path.stat().accessed, 1000); - assert_eq!(path.stat().modified, 2000); + assert_eq!(path.stat().unwrap().accessed, 1000); + assert_eq!(path.stat().unwrap().modified, 2000); + + rmdir_recursive(&tmpdir); } #[test] fn utime_noexist() { let tmpdir = tmpdir(); - match io::result(|| change_file_times(&tmpdir.join("a"), 100, 200)) { + match change_file_times(&tmpdir.join("a"), 100, 200) { Ok(*) => fail!(), Err(*) => {} } diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index b08f4af9a54c6..91e20e6bd4e13 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -33,7 +33,7 @@ impl MemWriter { } impl Writer for MemWriter { - fn write(&mut self, buf: &[u8]) { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { // Make sure the internal buffer is as least as big as where we // currently are let difference = self.pos as i64 - self.buf.len() as i64; @@ -61,13 +61,17 @@ impl Writer for MemWriter { // Bump us forward self.pos += buf.len(); + Ok(()) } } -// FIXME(#10432) +// FIXME(#10432) is this the right behavior? impl Seek for MemWriter { - fn tell(&self) -> u64 { self.pos as u64 } + fn tell(&self) -> IoResult { Ok(self.pos as u64) } + /// Seeks this memory writer to the given position. If the position is + /// beyond the current end of the buffer, then the intermediate bytes will + /// all be filled with 0s. fn seek(&mut self, pos: i64, style: SeekStyle) { // compute offset as signed and clamp to prevent overflow let offset = match style { @@ -94,16 +98,14 @@ pub struct MemReader { impl MemReader { pub fn new(buf: ~[u8]) -> MemReader { - MemReader { - buf: buf, - pos: 0 - } + MemReader { buf: buf, pos: 0 } } } impl Reader for MemReader { - fn read(&mut self, buf: &mut [u8]) -> Option { - { if self.eof() { return None; } } + fn read(&mut self, buf: &mut [u8]) -> IoResult { + if self.eof() { return Err(standard_error(EndOfFile)); } + assert!(self.pos < self.buf.len()); let write_len = min(buf.len(), self.buf.len() - self.pos); { @@ -115,22 +117,24 @@ impl Reader for MemReader { self.pos += write_len; assert!(self.pos <= self.buf.len()); - return Some(write_len); + return Ok(write_len); } - fn eof(&mut self) -> bool { self.pos == self.buf.len() } + fn eof(&mut self) -> bool { self.pos >= self.buf.len() } } +// FIXME(#10432) implement this impl Seek for MemReader { - fn tell(&self) -> u64 { self.pos as u64 } - fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() } + fn tell(&self) -> IoResult { Ok(self.pos as u64) } + fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() } } impl Buffer for MemReader { - fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) } + fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { + Ok(self.buf.slice_from(self.pos)) + } fn consume(&mut self, amt: uint) { self.pos += amt; } } - impl Decorator<~[u8]> for MemReader { fn inner(self) -> ~[u8] { self.buf } fn inner_ref<'a>(&'a self) -> &'a ~[u8] { &self.buf } @@ -208,8 +212,8 @@ impl<'self> BufReader<'self> { } impl<'self> Reader for BufReader<'self> { - fn read(&mut self, buf: &mut [u8]) -> Option { - { if self.eof() { return None; } } + fn read(&mut self, buf: &mut [u8]) -> IoResult { + if self.eof() { return Err(standard_error(EndOfFile)); } let write_len = min(buf.len(), self.buf.len() - self.pos); { @@ -221,16 +225,16 @@ impl<'self> Reader for BufReader<'self> { self.pos += write_len; assert!(self.pos <= self.buf.len()); - return Some(write_len); + return Ok(write_len); } fn eof(&mut self) -> bool { self.pos == self.buf.len() } } +// FIXME(#10432) implement this impl<'self> Seek for BufReader<'self> { - fn tell(&self) -> u64 { self.pos as u64 } - - fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() } + fn tell(&self) -> IoResult { Ok(self.pos as u64) } + fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() } } impl<'self> Buffer for BufReader<'self> { @@ -255,16 +259,16 @@ mod test { #[test] fn test_mem_writer() { let mut writer = MemWriter::new(); - assert_eq!(writer.tell(), 0); + assert_eq!(writer.tell(), Ok(0)); writer.write([0]); - assert_eq!(writer.tell(), 1); + assert_eq!(writer.tell(), Ok(1)); writer.write([1, 2, 3]); writer.write([4, 5, 6, 7]); - assert_eq!(writer.tell(), 8); + assert_eq!(writer.tell(), Ok(8)); assert_eq!(*writer.inner_ref(), ~[0, 1, 2, 3, 4, 5, 6, 7]); writer.seek(0, SeekSet); - assert_eq!(writer.tell(), 0); + assert_eq!(writer.tell(), Ok(0)); writer.write([3, 4]); assert_eq!(*writer.inner_ref(), ~[3, 4, 2, 3, 4, 5, 6, 7]); @@ -344,20 +348,20 @@ mod test { fn test_mem_reader() { let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]); let mut buf = []; - assert_eq!(reader.read(buf), Some(0)); - assert_eq!(reader.tell(), 0); + assert_eq!(reader.read(buf), Ok(0)); + assert_eq!(reader.tell(), Ok(0)); let mut buf = [0]; - assert_eq!(reader.read(buf), Some(1)); - assert_eq!(reader.tell(), 1); + assert_eq!(reader.read(buf), Ok(1)); + assert_eq!(reader.tell(), Ok(1)); assert_eq!(buf, [0]); let mut buf = [0, ..4]; - assert_eq!(reader.read(buf), Some(4)); - assert_eq!(reader.tell(), 5); + assert_eq!(reader.read(buf), Ok(4)); + assert_eq!(reader.tell(), Ok(5)); assert_eq!(buf, [1, 2, 3, 4]); - assert_eq!(reader.read(buf), Some(3)); + assert_eq!(reader.read(buf), Ok(3)); assert_eq!(buf.slice(0, 3), [5, 6, 7]); assert!(reader.eof()); - assert_eq!(reader.read(buf), None); + assert!(reader.read(buf).is_err()); assert!(reader.eof()); } @@ -366,26 +370,28 @@ mod test { let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7]; let mut reader = BufReader::new(in_buf); let mut buf = []; - assert_eq!(reader.read(buf), Some(0)); - assert_eq!(reader.tell(), 0); + assert_eq!(reader.read(buf), Ok(0)); + assert_eq!(reader.tell(), Ok(0)); let mut buf = [0]; - assert_eq!(reader.read(buf), Some(1)); - assert_eq!(reader.tell(), 1); + assert_eq!(reader.read(buf), Ok(1)); + assert_eq!(reader.tell(), Ok(1)); assert_eq!(buf, [0]); let mut buf = [0, ..4]; - assert_eq!(reader.read(buf), Some(4)); - assert_eq!(reader.tell(), 5); + assert_eq!(reader.read(buf), Ok(4)); + assert_eq!(reader.tell(), Ok(5)); assert_eq!(buf, [1, 2, 3, 4]); - assert_eq!(reader.read(buf), Some(3)); + assert_eq!(reader.read(buf), Ok(3)); assert_eq!(buf.slice(0, 3), [5, 6, 7]); assert!(reader.eof()); - assert_eq!(reader.read(buf), None); + assert!(reader.read(buf).is_err()); assert!(reader.eof()); } #[test] fn test_with_mem_writer() { - let buf = with_mem_writer(|wr| wr.write([1,2,3,4,5,6,7])); + let buf = with_mem_writer(|wr| { + wr.write([1,2,3,4,5,6,7]); + }); assert_eq!(buf, ~[1,2,3,4,5,6,7]); } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 8cc4e7b389b46..9bae2e7d6e1eb 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -242,6 +242,7 @@ Out of scope use cast; use container::Container; +use fmt; use int; use iter::Iterator; use option::{Option, Some, None}; @@ -289,11 +290,8 @@ pub mod mem; /// Non-blocking access to stdin, stdout, stderr pub mod stdio; -/// Implementations for Option -mod option; - -/// Basic stream compression. XXX: Belongs with other flate code -pub mod flate; +/// Implementations for Result +mod result; /// Interop between byte streams and pipes. Not sure where it belongs pub mod comm_adapters; @@ -315,11 +313,14 @@ pub mod signal; /// The default buffer size for various I/O operations static DEFAULT_BUF_SIZE: uint = 1024 * 64; +pub type IoResult = Result; + /// The type passed to I/O condition handlers to indicate error /// /// # XXX /// /// Is something like this sufficient? It's kind of archaic +#[deriving(Clone, Eq)] pub struct IoError { kind: IoErrorKind, desc: &'static str, @@ -340,9 +341,17 @@ impl ToStr for IoError { } } -#[deriving(Eq)] +impl fmt::Default for IoError { + fn fmt(err: &IoError, f: &mut fmt::Formatter) -> fmt::Result { + match err.detail { + None => write!(f.buf, "{}", err.desc), + Some(ref s) => write!(f.buf, "{} ({})", err.desc, *s), + } + } +} + +#[deriving(Eq, Clone)] pub enum IoErrorKind { - PreviousIoError, OtherIoError, EndOfFile, FileNotFound, @@ -359,13 +368,13 @@ pub enum IoErrorKind { MismatchedFileTypeForOperation, ResourceUnavailable, IoUnavailable, + InvalidParameters, } // FIXME: #8242 implementing manually because deriving doesn't work for some reason impl ToStr for IoErrorKind { fn to_str(&self) -> ~str { match *self { - PreviousIoError => ~"PreviousIoError", OtherIoError => ~"OtherIoError", EndOfFile => ~"EndOfFile", FileNotFound => ~"FileNotFound", @@ -382,42 +391,11 @@ impl ToStr for IoErrorKind { IoUnavailable => ~"IoUnavailable", ResourceUnavailable => ~"ResourceUnavailable", ConnectionAborted => ~"ConnectionAborted", + InvalidParameters => ~"InvalidParameters", } } } -// XXX: Can't put doc comments on macros -// Raised by `I/O` operations on error. -condition! { - pub io_error: IoError -> (); -} - -/// Helper for wrapper calls where you want to -/// ignore any io_errors that might be raised -pub fn ignore_io_error(cb: || -> T) -> T { - io_error::cond.trap(|_| { - // just swallow the error.. downstream users - // who can make a decision based on a None result - // won't care - }).inside(|| cb()) -} - -/// Helper for catching an I/O error and wrapping it in a Result object. The -/// return result will be the last I/O error that happened or the result of the -/// closure if no error occurred. -pub fn result(cb: || -> T) -> Result { - let mut err = None; - let ret = io_error::cond.trap(|e| { - if err.is_none() { - err = Some(e); - } - }).inside(cb); - match err { - Some(e) => Err(e), - None => Ok(ret), - } -} - pub trait Reader { // Only two methods which need to get implemented for this trait @@ -444,7 +422,7 @@ pub trait Reader { /// Will people often need to slice their vectors to call this /// and will that be annoying? /// Is it actually possible for 0 bytes to be read successfully? - fn read(&mut self, buf: &mut [u8]) -> Option; + fn read(&mut self, buf: &mut [u8]) -> IoResult; /// Return whether the Reader has reached the end of the stream. /// @@ -468,16 +446,16 @@ pub trait Reader { /// /// Raises the same conditions as the `read` method. Returns /// `None` if the condition is handled. - fn read_byte(&mut self) -> Option { + fn read_byte(&mut self) -> IoResult { let mut buf = [0]; - match self.read(buf) { - Some(0) => { - debug!("read 0 bytes. trying again"); - self.read_byte() + loop { + match self.read(buf) { + Ok(1) => return Ok(buf[0]), + Err(e) => return Err(e), + + Ok(0) => {} // try again + Ok(_) => unreachable!(), } - Some(1) => Some(buf[0]), - Some(_) => unreachable!(), - None => None } } @@ -491,7 +469,7 @@ pub trait Reader { /// Raises the same conditions as `read`. Additionally raises `io_error` /// on EOF. If `io_error` is handled then `push_bytes` may push less /// than the requested number of bytes. - fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) { + fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> { unsafe { let start_len = buf.len(); let mut total_read = 0; @@ -499,21 +477,22 @@ pub trait Reader { buf.reserve_additional(len); vec::raw::set_len(buf, start_len + len); + let mut ret = Ok(()); (|| { while total_read < len { let len = buf.len(); - let slice = buf.mut_slice(start_len + total_read, len); - match self.read(slice) { - Some(nread) => { + match self.read(buf.mut_slice(start_len + total_read, len)) { + Ok(nread) => { total_read += nread; } - None => { - io_error::cond.raise(standard_error(EndOfFile)); + Err(e) => { + ret = Err(e); break; } } } }).finally(|| vec::raw::set_len(buf, start_len + total_read)) + ret } } @@ -524,10 +503,12 @@ pub trait Reader { /// Raises the same conditions as `read`. Additionally raises `io_error` /// on EOF. If `io_error` is handled then the returned vector may /// contain less than the requested number of bytes. - fn read_bytes(&mut self, len: uint) -> ~[u8] { + fn read_bytes(&mut self, len: uint) -> Result<~[u8], (~[u8], IoError)> { let mut buf = vec::with_capacity(len); - self.push_bytes(&mut buf, len); - return buf; + match self.push_bytes(&mut buf, len) { + Ok(()) => Ok(buf), + Err(e) => Err((buf, e)), + } } /// Reads all remaining bytes from the stream. @@ -535,33 +516,15 @@ pub trait Reader { /// # Failure /// /// Raises the same conditions as the `read` method. - fn read_to_end(&mut self) -> ~[u8] { + fn read_to_end(&mut self) -> IoResult<~[u8]> { let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE); - let mut keep_reading = true; - io_error::cond.trap(|e| { - if e.kind == EndOfFile { - keep_reading = false; - } else { - io_error::cond.raise(e) - } - }).inside(|| { - while keep_reading { - self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) + loop { + match self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) { + Ok(()) => {} + Err(ref e) if e.kind == EndOfFile => return Ok(buf), + Err(e) => return Err(e) } - }); - return buf; - } - - /// Create an iterator that reads a single byte on - /// each iteration, until EOF. - /// - /// # Failure - /// - /// Raises the same conditions as the `read` method, for - /// each call to its `.next()` method. - /// Ends the iteration if the condition is handled. - fn bytes(self) -> extensions::ByteIterator { - extensions::ByteIterator::new(self) + } } // Byte conversion helpers @@ -569,226 +532,216 @@ pub trait Reader { /// Reads `n` little-endian unsigned integer bytes. /// /// `n` must be between 1 and 8, inclusive. - fn read_le_uint_n(&mut self, nbytes: uint) -> u64 { + fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult { assert!(nbytes > 0 && nbytes <= 8); let mut val = 0u64; let mut pos = 0; let mut i = nbytes; while i > 0 { - val += (self.read_u8() as u64) << pos; + val += if_ok!(self.read_u8()) as u64 << pos; pos += 8; i -= 1; } - val + Ok(val) } /// Reads `n` little-endian signed integer bytes. /// /// `n` must be between 1 and 8, inclusive. - fn read_le_int_n(&mut self, nbytes: uint) -> i64 { - extend_sign(self.read_le_uint_n(nbytes), nbytes) + fn read_le_int_n(&mut self, nbytes: uint) -> IoResult { + self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes)) } /// Reads `n` big-endian unsigned integer bytes. /// /// `n` must be between 1 and 8, inclusive. - fn read_be_uint_n(&mut self, nbytes: uint) -> u64 { + fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult { assert!(nbytes > 0 && nbytes <= 8); let mut val = 0u64; let mut i = nbytes; while i > 0 { i -= 1; - val += (self.read_u8() as u64) << i * 8; + val += if_ok!(self.read_u8()) as u64 << i * 8; } - val + Ok(val) } /// Reads `n` big-endian signed integer bytes. /// /// `n` must be between 1 and 8, inclusive. - fn read_be_int_n(&mut self, nbytes: uint) -> i64 { - extend_sign(self.read_be_uint_n(nbytes), nbytes) + fn read_be_int_n(&mut self, nbytes: uint) -> IoResult { + self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes)) } /// Reads a little-endian unsigned integer. /// /// The number of bytes returned is system-dependant. - fn read_le_uint(&mut self) -> uint { - self.read_le_uint_n(uint::bytes) as uint + fn read_le_uint(&mut self) -> IoResult { + self.read_le_uint_n(uint::bytes).map(|i| i as uint) } /// Reads a little-endian integer. /// /// The number of bytes returned is system-dependant. - fn read_le_int(&mut self) -> int { - self.read_le_int_n(int::bytes) as int + fn read_le_int(&mut self) -> IoResult { + self.read_le_int_n(int::bytes).map(|i| i as int) } /// Reads a big-endian unsigned integer. /// /// The number of bytes returned is system-dependant. - fn read_be_uint(&mut self) -> uint { - self.read_be_uint_n(uint::bytes) as uint + fn read_be_uint(&mut self) -> IoResult { + self.read_be_uint_n(uint::bytes).map(|i| i as uint) } /// Reads a big-endian integer. /// /// The number of bytes returned is system-dependant. - fn read_be_int(&mut self) -> int { - self.read_be_int_n(int::bytes) as int + fn read_be_int(&mut self) -> IoResult { + self.read_be_int_n(int::bytes).map(|i| i as int) } /// Reads a big-endian `u64`. /// /// `u64`s are 8 bytes long. - fn read_be_u64(&mut self) -> u64 { - self.read_be_uint_n(8) as u64 + fn read_be_u64(&mut self) -> IoResult { + self.read_be_uint_n(8).map(|i| i as u64) } /// Reads a big-endian `u32`. /// /// `u32`s are 4 bytes long. - fn read_be_u32(&mut self) -> u32 { - self.read_be_uint_n(4) as u32 + fn read_be_u32(&mut self) -> IoResult { + self.read_be_uint_n(4).map(|i| i as u32) } /// Reads a big-endian `u16`. /// /// `u16`s are 2 bytes long. - fn read_be_u16(&mut self) -> u16 { - self.read_be_uint_n(2) as u16 + fn read_be_u16(&mut self) -> IoResult { + self.read_be_uint_n(2).map(|i| i as u16) } /// Reads a big-endian `i64`. /// /// `i64`s are 8 bytes long. - fn read_be_i64(&mut self) -> i64 { - self.read_be_int_n(8) as i64 + fn read_be_i64(&mut self) -> IoResult { + self.read_be_int_n(8).map(|i| i as i64) } /// Reads a big-endian `i32`. /// /// `i32`s are 4 bytes long. - fn read_be_i32(&mut self) -> i32 { - self.read_be_int_n(4) as i32 + fn read_be_i32(&mut self) -> IoResult { + self.read_be_int_n(4).map(|i| i as i32) } /// Reads a big-endian `i16`. /// /// `i16`s are 2 bytes long. - fn read_be_i16(&mut self) -> i16 { - self.read_be_int_n(2) as i16 + fn read_be_i16(&mut self) -> IoResult { + self.read_be_int_n(2).map(|i| i as i16) } /// Reads a big-endian `f64`. /// /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - fn read_be_f64(&mut self) -> f64 { - unsafe { - cast::transmute::(self.read_be_u64()) - } + fn read_be_f64(&mut self) -> IoResult { + self.read_be_u64().map(|i| unsafe { + cast::transmute::(i) + }) } /// Reads a big-endian `f32`. /// /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - fn read_be_f32(&mut self) -> f32 { - unsafe { - cast::transmute::(self.read_be_u32()) - } + fn read_be_f32(&mut self) -> IoResult { + self.read_be_u32().map(|i| unsafe { + cast::transmute::(i) + }) } /// Reads a little-endian `u64`. /// /// `u64`s are 8 bytes long. - fn read_le_u64(&mut self) -> u64 { - self.read_le_uint_n(8) as u64 + fn read_le_u64(&mut self) -> IoResult { + self.read_le_uint_n(8).map(|i| i as u64) } /// Reads a little-endian `u32`. /// /// `u32`s are 4 bytes long. - fn read_le_u32(&mut self) -> u32 { - self.read_le_uint_n(4) as u32 + fn read_le_u32(&mut self) -> IoResult { + self.read_le_uint_n(4).map(|i| i as u32) } /// Reads a little-endian `u16`. /// /// `u16`s are 2 bytes long. - fn read_le_u16(&mut self) -> u16 { - self.read_le_uint_n(2) as u16 + fn read_le_u16(&mut self) -> IoResult { + self.read_le_uint_n(2).map(|i| i as u16) } /// Reads a little-endian `i64`. /// /// `i64`s are 8 bytes long. - fn read_le_i64(&mut self) -> i64 { - self.read_le_int_n(8) as i64 + fn read_le_i64(&mut self) -> IoResult { + self.read_le_int_n(8).map(|i| i as i64) } /// Reads a little-endian `i32`. /// /// `i32`s are 4 bytes long. - fn read_le_i32(&mut self) -> i32 { - self.read_le_int_n(4) as i32 + fn read_le_i32(&mut self) -> IoResult { + self.read_le_int_n(4).map(|i| i as i32) } /// Reads a little-endian `i16`. /// /// `i16`s are 2 bytes long. - fn read_le_i16(&mut self) -> i16 { - self.read_le_int_n(2) as i16 + fn read_le_i16(&mut self) -> IoResult { + self.read_le_int_n(2).map(|i| i as i16) } /// Reads a little-endian `f64`. /// /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers. - fn read_le_f64(&mut self) -> f64 { - unsafe { - cast::transmute::(self.read_le_u64()) - } + fn read_le_f64(&mut self) -> IoResult { + self.read_le_u64().map(|i| unsafe { + cast::transmute::(i) + }) } /// Reads a little-endian `f32`. /// /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers. - fn read_le_f32(&mut self) -> f32 { - unsafe { - cast::transmute::(self.read_le_u32()) - } + fn read_le_f32(&mut self) -> IoResult { + self.read_le_u32().map(|i| unsafe { + cast::transmute::(i) + }) } /// Read a u8. /// /// `u8`s are 1 byte. - fn read_u8(&mut self) -> u8 { - match self.read_byte() { - Some(b) => b as u8, - None => 0 - } - } + fn read_u8(&mut self) -> IoResult { self.read_byte() } /// Read an i8. /// /// `i8`s are 1 byte. - fn read_i8(&mut self) -> i8 { - match self.read_byte() { - Some(b) => b as i8, - None => 0 - } - } + fn read_i8(&mut self) -> IoResult { self.read_byte().map(|i| i as i8) } } impl Reader for ~Reader { - fn read(&mut self, buf: &mut [u8]) -> Option { self.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.read(buf) } fn eof(&mut self) -> bool { self.eof() } } impl<'self> Reader for &'self mut Reader { - fn read(&mut self, buf: &mut [u8]) -> Option { self.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.read(buf) } fn eof(&mut self) -> bool { self.eof() } } @@ -803,122 +756,122 @@ pub trait Writer { /// # Failure /// /// Raises the `io_error` condition on error - fn write(&mut self, buf: &[u8]); + fn write(&mut self, buf: &[u8]) -> IoResult<()>; /// Flush this output stream, ensuring that all intermediately buffered /// contents reach their destination. /// /// This is by default a no-op and implementors of the `Writer` trait should /// decide whether their stream needs to be buffered or not. - fn flush(&mut self) {} + fn flush(&mut self) -> IoResult<()> { Ok(()) } /// Write the result of passing n through `int::to_str_bytes`. - fn write_int(&mut self, n: int) { + fn write_int(&mut self, n: int) -> IoResult<()> { int::to_str_bytes(n, 10u, |bytes| self.write(bytes)) } /// Write the result of passing n through `uint::to_str_bytes`. - fn write_uint(&mut self, n: uint) { + fn write_uint(&mut self, n: uint) -> IoResult<()> { uint::to_str_bytes(n, 10u, |bytes| self.write(bytes)) } /// Write a little-endian uint (number of bytes depends on system). - fn write_le_uint(&mut self, n: uint) { + fn write_le_uint(&mut self, n: uint) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v)) } /// Write a little-endian int (number of bytes depends on system). - fn write_le_int(&mut self, n: int) { + fn write_le_int(&mut self, n: int) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, int::bytes, |v| self.write(v)) } /// Write a big-endian uint (number of bytes depends on system). - fn write_be_uint(&mut self, n: uint) { + fn write_be_uint(&mut self, n: uint) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, uint::bytes, |v| self.write(v)) } /// Write a big-endian int (number of bytes depends on system). - fn write_be_int(&mut self, n: int) { + fn write_be_int(&mut self, n: int) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, int::bytes, |v| self.write(v)) } /// Write a big-endian u64 (8 bytes). - fn write_be_u64(&mut self, n: u64) { + fn write_be_u64(&mut self, n: u64) -> IoResult<()> { extensions::u64_to_be_bytes(n, 8u, |v| self.write(v)) } /// Write a big-endian u32 (4 bytes). - fn write_be_u32(&mut self, n: u32) { + fn write_be_u32(&mut self, n: u32) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) } /// Write a big-endian u16 (2 bytes). - fn write_be_u16(&mut self, n: u16) { + fn write_be_u16(&mut self, n: u16) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) } /// Write a big-endian i64 (8 bytes). - fn write_be_i64(&mut self, n: i64) { + fn write_be_i64(&mut self, n: i64) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v)) } /// Write a big-endian i32 (4 bytes). - fn write_be_i32(&mut self, n: i32) { + fn write_be_i32(&mut self, n: i32) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v)) } /// Write a big-endian i16 (2 bytes). - fn write_be_i16(&mut self, n: i16) { + fn write_be_i16(&mut self, n: i16) -> IoResult<()> { extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v)) } /// Write a big-endian IEEE754 double-precision floating-point (8 bytes). - fn write_be_f64(&mut self, f: f64) { + fn write_be_f64(&mut self, f: f64) -> IoResult<()> { unsafe { self.write_be_u64(cast::transmute(f)) } } /// Write a big-endian IEEE754 single-precision floating-point (4 bytes). - fn write_be_f32(&mut self, f: f32) { + fn write_be_f32(&mut self, f: f32) -> IoResult<()> { unsafe { self.write_be_u32(cast::transmute(f)) } } /// Write a little-endian u64 (8 bytes). - fn write_le_u64(&mut self, n: u64) { + fn write_le_u64(&mut self, n: u64) -> IoResult<()> { extensions::u64_to_le_bytes(n, 8u, |v| self.write(v)) } /// Write a little-endian u32 (4 bytes). - fn write_le_u32(&mut self, n: u32) { + fn write_le_u32(&mut self, n: u32) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) } /// Write a little-endian u16 (2 bytes). - fn write_le_u16(&mut self, n: u16) { + fn write_le_u16(&mut self, n: u16) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) } /// Write a little-endian i64 (8 bytes). - fn write_le_i64(&mut self, n: i64) { + fn write_le_i64(&mut self, n: i64) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v)) } /// Write a little-endian i32 (4 bytes). - fn write_le_i32(&mut self, n: i32) { + fn write_le_i32(&mut self, n: i32) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v)) } /// Write a little-endian i16 (2 bytes). - fn write_le_i16(&mut self, n: i16) { + fn write_le_i16(&mut self, n: i16) -> IoResult<()> { extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v)) } /// Write a little-endian IEEE754 double-precision floating-point /// (8 bytes). - fn write_le_f64(&mut self, f: f64) { + fn write_le_f64(&mut self, f: f64) -> IoResult<()> { unsafe { self.write_le_u64(cast::transmute(f)) } @@ -926,31 +879,31 @@ pub trait Writer { /// Write a little-endian IEEE754 single-precision floating-point /// (4 bytes). - fn write_le_f32(&mut self, f: f32) { + fn write_le_f32(&mut self, f: f32) -> IoResult<()> { unsafe { self.write_le_u32(cast::transmute(f)) } } /// Write a u8 (1 byte). - fn write_u8(&mut self, n: u8) { + fn write_u8(&mut self, n: u8) -> IoResult<()> { self.write([n]) } /// Write a i8 (1 byte). - fn write_i8(&mut self, n: i8) { + fn write_i8(&mut self, n: i8) -> IoResult<()> { self.write([n as u8]) } } impl Writer for ~Writer { - fn write(&mut self, buf: &[u8]) { self.write(buf) } - fn flush(&mut self) { self.flush() } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) } + fn flush(&mut self) -> IoResult<()> { self.flush() } } impl<'self> Writer for &'self mut Writer { - fn write(&mut self, buf: &[u8]) { self.write(buf) } - fn flush(&mut self) { self.flush() } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) } + fn flush(&mut self) -> IoResult<()> { self.flush() } } pub trait Stream: Reader + Writer { } @@ -974,7 +927,7 @@ pub trait Buffer: Reader { /// /// This function will raise on the `io_error` condition if a read error is /// encountered. - fn fill<'a>(&'a mut self) -> &'a [u8]; + fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>; /// Tells this buffer that `amt` bytes have been consumed from the buffer, /// so they should no longer be returned in calls to `fill` or `read`. @@ -989,7 +942,7 @@ pub trait Buffer: Reader { /// This function will raise on the `io_error` condition if a read error is /// encountered. The task will also fail if sequence of bytes leading up to /// the newline character are not valid utf-8. - fn read_line(&mut self) -> Option<~str> { + fn read_line(&mut self) -> IoResult<~str> { self.read_until('\n' as u8).map(str::from_utf8_owned) } @@ -1001,12 +954,17 @@ pub trait Buffer: Reader { /// /// This function will raise on the `io_error` condition if a read error is /// encountered. - fn read_until(&mut self, byte: u8) -> Option<~[u8]> { + fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> { let mut res = ~[]; let mut used; loop { { - let available = self.fill(); + used = 0; + let available = match self.fill() { + Ok(b) => b, + Err(*) if res.len() > 0 => break, + Err(e) => return Err(e) + }; match available.iter().position(|&b| b == byte) { Some(i) => { res.push_all(available.slice_to(i + 1)); @@ -1025,7 +983,7 @@ pub trait Buffer: Reader { self.consume(used); } self.consume(used); - return if res.len() == 0 {None} else {Some(res)}; + return Ok(res) } /// Reads the next utf8-encoded character from the underlying stream. @@ -1037,21 +995,17 @@ pub trait Buffer: Reader { /// /// This function will raise on the `io_error` condition if a read error is /// encountered. - fn read_char(&mut self) -> Option { + fn read_char(&mut self) -> IoResult { let width = { - let available = self.fill(); - if available.len() == 0 { return None } // read error + let available = if_ok!(self.fill()); str::utf8_char_width(available[0]) }; - if width == 0 { return None } // not uf8 + if width == 0 { return Err(standard_error(InvalidParameters)) } let mut buf = [0, ..4]; - match self.read(buf.mut_slice_to(width)) { - Some(n) if n == width => {} - Some(*) | None => return None // read error - } + if_ok!(self.read(buf.mut_slice_to(width))); match str::from_utf8_slice_opt(buf.slice_to(width)) { - Some(s) => Some(s.char_at(0)), - None => None + Some(s) => Ok(s.char_at(0)), + None => Err(standard_error(InvalidParameters)) } } } @@ -1065,20 +1019,19 @@ pub enum SeekStyle { SeekCur, } -/// # XXX -/// * Are `u64` and `i64` the right choices? +/// A trait for I/O streams which have the notion of an underlying cursor which +/// can be moved around. This is most prevelant in file streams, but may also be +/// implemented for others. pub trait Seek { /// Return position of file cursor in the stream - fn tell(&self) -> u64; + fn tell(&self) -> IoResult; /// Seek to an offset in a stream /// /// A successful seek clears the EOF indicator. /// - /// # XXX - /// - /// * What is the behavior when seeking past the end of a stream? - fn seek(&mut self, pos: i64, style: SeekStyle); + // FIXME(#10432) What is the behavior when seeking past the end of a stream? + fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>; } /// A listener is a value that can consume itself to start listening for connections. @@ -1090,7 +1043,7 @@ pub trait Listener> { /// /// Raises `io_error` condition. If the condition is handled, /// then `listen` returns `None`. - fn listen(self) -> Option; + fn listen(self) -> IoResult; } /// An acceptor is a value that presents incoming connections @@ -1100,7 +1053,7 @@ pub trait Acceptor { /// # Failure /// Raise `io_error` condition. If the condition is handled, /// then `accept` returns `None`. - fn accept(&mut self) -> Option; + fn accept(&mut self) -> IoResult; /// Create an iterator over incoming connection attempts fn incoming<'r>(&'r mut self) -> IncomingIterator<'r, Self> { @@ -1119,8 +1072,8 @@ struct IncomingIterator<'self, A> { priv inc: &'self mut A, } -impl<'self, T, A: Acceptor> Iterator> for IncomingIterator<'self, A> { - fn next(&mut self) -> Option> { +impl<'self, T, A: Acceptor> Iterator> for IncomingIterator<'self, A> { + fn next(&mut self) -> Option> { Some(self.inc.accept()) } } @@ -1153,13 +1106,6 @@ pub trait Decorator { pub fn standard_error(kind: IoErrorKind) -> IoError { match kind { - PreviousIoError => { - IoError { - kind: PreviousIoError, - desc: "Failing due to a previous I/O error", - detail: None - } - } EndOfFile => { IoError { kind: EndOfFile, @@ -1174,18 +1120,17 @@ pub fn standard_error(kind: IoErrorKind) -> IoError { detail: None } } + InvalidParameters => { + IoError { + kind: InvalidParameters, + desc: "invalid input or parameters detected", + detail: None + } + } _ => fail!() } } -pub fn placeholder_error() -> IoError { - IoError { - kind: OtherIoError, - desc: "Placeholder error. You shouldn't be seeing this", - detail: None - } -} - /// A mode specifies how a file should be opened or created. These modes are /// passed to `File::open_mode` and are used to control where the file is /// positioned when it is initially opened. diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs index 03af64cc6dccf..c5cb17f6a2693 100644 --- a/src/libstd/io/net/addrinfo.rs +++ b/src/libstd/io/net/addrinfo.rs @@ -18,8 +18,7 @@ getaddrinfo() */ use option::{Option, Some, None}; -use result::{Ok, Err}; -use io::{io_error}; +use io::IoResult; use io::net::ip::{SocketAddr, IpAddr}; use rt::rtio::{IoFactory, with_local_io}; use vec::ImmutableVector; @@ -75,7 +74,7 @@ pub struct Info { /// # Failure /// /// On failure, this will raise on the `io_error` condition. -pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> { +pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> { lookup(Some(host), None, None).map(|a| a.map(|i| i.address.ip)) } @@ -96,16 +95,8 @@ pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> { /// XXX: this is not public because the `Hint` structure is not ready for public /// consumption just yet. fn lookup(hostname: Option<&str>, servname: Option<&str>, - hint: Option) -> Option<~[Info]> { - with_local_io(|io| { - match io.get_host_addresses(hostname, servname, hint) { - Ok(i) => Some(i), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } - }) + hint: Option) -> IoResult<~[Info]> { + with_local_io(|io| io.get_host_addresses(hostname, servname, hint)) } #[cfg(test)] diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index aa7a64d221074..9fb8ccfbe3924 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use option::{Option, Some, None}; -use result::{Ok, Err}; use io::net::ip::SocketAddr; use io::{Reader, Writer, Listener, Acceptor}; -use io::{io_error, EndOfFile}; +use io::IoResult; use rt::rtio::{IoFactory, with_local_io, RtioSocket, RtioTcpListener, RtioTcpAcceptor, RtioTcpStream}; @@ -25,64 +23,29 @@ impl TcpStream { TcpStream { obj: s } } - pub fn connect(addr: SocketAddr) -> Option { - with_local_io(|io| { - match io.tcp_connect(addr) { - Ok(s) => Some(TcpStream::new(s)), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } - }) + pub fn connect(addr: SocketAddr) -> IoResult { + with_local_io(|io| io.tcp_connect(addr).map(TcpStream::new)) } - pub fn peer_name(&mut self) -> Option { - match self.obj.peer_name() { - Ok(pn) => Some(pn), - Err(ioerr) => { - debug!("failed to get peer name: {:?}", ioerr); - io_error::cond.raise(ioerr); - None - } - } + pub fn peer_name(&mut self) -> IoResult { + self.obj.peer_name() } - pub fn socket_name(&mut self) -> Option { - match self.obj.socket_name() { - Ok(sn) => Some(sn), - Err(ioerr) => { - debug!("failed to get socket name: {:?}", ioerr); - io_error::cond.raise(ioerr); - None - } - } + pub fn socket_name(&mut self) -> IoResult { + self.obj.socket_name() } } impl Reader for TcpStream { - fn read(&mut self, buf: &mut [u8]) -> Option { - match self.obj.read(buf) { - Ok(read) => Some(read), - Err(ioerr) => { - // EOF is indicated by returning None - if ioerr.kind != EndOfFile { - io_error::cond.raise(ioerr); - } - return None; - } - } + fn read(&mut self, buf: &mut [u8]) -> IoResult { + self.obj.read(buf) } - - fn eof(&mut self) -> bool { fail!() } + fn eof(&mut self) -> bool { false } } impl Writer for TcpStream { - fn write(&mut self, buf: &[u8]) { - match self.obj.write(buf) { - Ok(_) => (), - Err(ioerr) => io_error::cond.raise(ioerr), - } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + self.obj.write(buf) } } @@ -91,39 +54,18 @@ pub struct TcpListener { } impl TcpListener { - pub fn bind(addr: SocketAddr) -> Option { - with_local_io(|io| { - match io.tcp_bind(addr) { - Ok(l) => Some(TcpListener { obj: l }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } - }) + pub fn bind(addr: SocketAddr) -> IoResult { + with_local_io(|io| io.tcp_bind(addr).map(|l| TcpListener { obj: l })) } - pub fn socket_name(&mut self) -> Option { - match self.obj.socket_name() { - Ok(sn) => Some(sn), - Err(ioerr) => { - debug!("failed to get socket name: {:?}", ioerr); - io_error::cond.raise(ioerr); - None - } - } + pub fn socket_name(&mut self) -> IoResult { + self.obj.socket_name() } } impl Listener for TcpListener { - fn listen(self) -> Option { - match self.obj.listen() { - Ok(acceptor) => Some(TcpAcceptor { obj: acceptor }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + fn listen(self) -> IoResult { + self.obj.listen().map(|a| TcpAcceptor { obj: a }) } } @@ -132,14 +74,8 @@ pub struct TcpAcceptor { } impl Acceptor for TcpAcceptor { - fn accept(&mut self) -> Option { - match self.obj.accept() { - Ok(s) => Some(TcpStream::new(s)), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + fn accept(&mut self) -> IoResult { + self.obj.accept().map(TcpStream::new) } } @@ -156,38 +92,27 @@ mod test { #[test] #[ignore] fn bind_error() { do run_in_mt_newsched_task { - let mut called = false; - io_error::cond.trap(|e| { - assert!(e.kind == PermissionDenied); - called = true; - }).inside(|| { - let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; - let listener = TcpListener::bind(addr); - assert!(listener.is_none()); - }); - assert!(called); + let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; + match TcpListener::bind(addr) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, PermissionDenied), + } } } #[test] fn connect_error() { do run_in_mt_newsched_task { - let mut called = false; - io_error::cond.trap(|e| { - let expected_error = if cfg!(unix) { + let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; + match TcpStream::connect(addr) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, if cfg!(unix) { ConnectionRefused } else { // On Win32, opening port 1 gives WSAEADDRNOTAVAIL error. OtherIoError - }; - assert_eq!(e.kind, expected_error); - called = true; - }).inside(|| { - let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; - let stream = TcpStream::connect(addr); - assert!(stream.is_none()); - }); - assert!(called); + }) + } } } @@ -255,7 +180,7 @@ mod test { let mut stream = acceptor.accept(); let mut buf = [0]; let nread = stream.read(buf); - assert!(nread.is_none()); + assert!(nread.is_err()); } do spawntask { @@ -280,7 +205,7 @@ mod test { let mut stream = acceptor.accept(); let mut buf = [0]; let nread = stream.read(buf); - assert!(nread.is_none()); + assert!(nread.is_err()); } do spawntask { @@ -304,18 +229,18 @@ mod test { chan.take().send(()); let mut stream = acceptor.accept(); let mut buf = [0]; - let nread = stream.read(buf); - assert!(nread.is_none()); - io_error::cond.trap(|e| { - if cfg!(windows) { - assert_eq!(e.kind, NotConnected); + match stream.read(buf) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, EndOfFile), + } + match stream.read(buf) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, if cfg!(windows) { + NotConnected } else { - fail!(); - } - }).inside(|| { - let nread = stream.read(buf); - assert!(nread.is_none()); - }) + EndOfFile + }) + } } do spawntask { @@ -339,18 +264,18 @@ mod test { chan.take().send(()); let mut stream = acceptor.accept(); let mut buf = [0]; - let nread = stream.read(buf); - assert!(nread.is_none()); - io_error::cond.trap(|e| { - if cfg!(windows) { - assert_eq!(e.kind, NotConnected); + match stream.read(buf) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, EndOfFile), + } + match stream.read(buf) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, if cfg!(windows) { + NotConnected } else { - fail!(); - } - }).inside(|| { - let nread = stream.read(buf); - assert!(nread.is_none()); - }) + EndOfFile + }) + } } do spawntask { @@ -375,19 +300,18 @@ mod test { let mut stream = acceptor.accept(); let buf = [0]; loop { - let mut stop = false; - io_error::cond.trap(|e| { - // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED - // on windows - assert!(e.kind == ConnectionReset || - e.kind == BrokenPipe || - e.kind == ConnectionAborted, - "unknown error: {:?}", e); - stop = true; - }).inside(|| { - stream.write(buf); - }); - if stop { break } + match stream.write(buf) { + Ok(*) => {} + Err(e) => { + // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED + // on windows + assert!(e.kind == ConnectionReset || + e.kind == BrokenPipe || + e.kind == ConnectionAborted, + "unknown error: {:?}", e); + break + } + } } } @@ -413,19 +337,18 @@ mod test { let mut stream = acceptor.accept(); let buf = [0]; loop { - let mut stop = false; - io_error::cond.trap(|e| { - // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED - // on windows - assert!(e.kind == ConnectionReset || - e.kind == BrokenPipe || - e.kind == ConnectionAborted, - "unknown error: {:?}", e); - stop = true; - }).inside(|| { - stream.write(buf); - }); - if stop { break } + match stream.write(buf) { + Ok(*) => {} + Err(e) => { + // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED + // on windows + assert!(e.kind == ConnectionReset || + e.kind == BrokenPipe || + e.kind == ConnectionAborted, + "unknown error: {:?}", e); + break + } + } } } @@ -671,7 +594,7 @@ mod test { // Make sure socket_name gives // us the socket we binded to. let so_name = listener.socket_name(); - assert!(so_name.is_some()); + assert!(so_name.is_ok()); assert_eq!(addr, so_name.unwrap()); } @@ -696,14 +619,14 @@ mod test { port.take().recv(); let stream = TcpStream::connect(addr); - assert!(stream.is_some()); + assert!(stream.is_ok()); let mut stream = stream.unwrap(); // Make sure peer_name gives us the // address/port of the peer we've // connected to. let peer_name = stream.peer_name(); - assert!(peer_name.is_some()); + assert!(peer_name.is_ok()); assert_eq!(addr, peer_name.unwrap()); } } diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs index f02fc1ae4471c..9ab69f9f57784 100644 --- a/src/libstd/io/net/udp.rs +++ b/src/libstd/io/net/udp.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use option::{Option, Some, None}; use result::{Ok, Err}; use io::net::ip::SocketAddr; use io::{Reader, Writer}; -use io::{io_error, EndOfFile}; +use io::IoResult; use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, with_local_io}; pub struct UdpSocket { @@ -20,51 +19,24 @@ pub struct UdpSocket { } impl UdpSocket { - pub fn bind(addr: SocketAddr) -> Option { - with_local_io(|io| { - match io.udp_bind(addr) { - Ok(s) => Some(UdpSocket { obj: s }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } - }) + pub fn bind(addr: SocketAddr) -> IoResult { + with_local_io(|io| io.udp_bind(addr).map(|s| UdpSocket { obj: s })) } - pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> { - match self.obj.recvfrom(buf) { - Ok((nread, src)) => Some((nread, src)), - Err(ioerr) => { - // EOF is indicated by returning None - if ioerr.kind != EndOfFile { - io_error::cond.raise(ioerr); - } - None - } - } + pub fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> { + self.obj.recvfrom(buf) } - pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) { - match self.obj.sendto(buf, dst) { - Ok(_) => (), - Err(ioerr) => io_error::cond.raise(ioerr), - } + pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> { + self.obj.sendto(buf, dst) } pub fn connect(self, other: SocketAddr) -> UdpStream { UdpStream { socket: self, connectedTo: other } } - pub fn socket_name(&mut self) -> Option { - match self.obj.socket_name() { - Ok(sn) => Some(sn), - Err(ioerr) => { - debug!("failed to get socket name: {:?}", ioerr); - io_error::cond.raise(ioerr); - None - } - } + pub fn socket_name(&mut self) -> IoResult { + self.obj.socket_name() } } @@ -74,31 +46,29 @@ pub struct UdpStream { } impl UdpStream { - pub fn as_socket(&mut self, f: |&mut UdpSocket| -> T) -> T { - f(&mut self.socket) + pub fn as_socket<'a>(&'a mut self) -> &'a mut UdpSocket { + &mut self.socket } pub fn disconnect(self) -> UdpSocket { self.socket } } impl Reader for UdpStream { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { let peer = self.connectedTo; - self.as_socket(|sock| { - match sock.recvfrom(buf) { - Some((_nread, src)) if src != peer => Some(0), - Some((nread, _src)) => Some(nread), - None => None, - } - }) + let sock = self.as_socket(); + match if_ok!(sock.recvfrom(buf)) { + (_nread, src) if src != peer => Ok(0), + (nread, _src) => Ok(nread), + } } - fn eof(&mut self) -> bool { fail!() } + fn eof(&mut self) -> bool { false } } impl Writer for UdpStream { - fn write(&mut self, buf: &[u8]) { - self.as_socket(|sock| sock.sendto(buf, self.connectedTo)); + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + self.as_socket().sendto(buf, self.connectedTo) } } @@ -108,23 +78,18 @@ mod test { use rt::test::*; use io::net::ip::{Ipv4Addr, SocketAddr}; use io::*; - use option::{Some, None}; + use result::{Ok, Err}; use rt::comm::oneshot; use cell::Cell; #[test] #[ignore] fn bind_error() { do run_in_mt_newsched_task { - let mut called = false; - io_error::cond.trap(|e| { - assert!(e.kind == PermissionDenied); - called = true; - }).inside(|| { - let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; - let socket = UdpSocket::bind(addr); - assert!(socket.is_none()); - }); - assert!(called); + let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; + match UdpSocket::bind(addr) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, PermissionDenied), + } } } @@ -139,29 +104,29 @@ mod test { do spawntask { match UdpSocket::bind(server_ip) { - Some(ref mut server) => { + Ok(ref mut server) => { chan.take().send(()); let mut buf = [0]; match server.recvfrom(buf) { - Some((nread, src)) => { + Ok((nread, src)) => { assert_eq!(nread, 1); assert_eq!(buf[0], 99); assert_eq!(src, client_ip); } - None => fail!() + Err(*) => fail!() } } - None => fail!() + Err(*) => fail!() } } do spawntask { match UdpSocket::bind(client_ip) { - Some(ref mut client) => { + Ok(ref mut client) => { port.take().recv(); - client.sendto([99], server_ip) + client.sendto([99], server_ip); } - None => fail!() + Err(*) => fail!() } } } @@ -178,29 +143,29 @@ mod test { do spawntask { match UdpSocket::bind(server_ip) { - Some(ref mut server) => { + Ok(ref mut server) => { chan.take().send(()); let mut buf = [0]; match server.recvfrom(buf) { - Some((nread, src)) => { + Ok((nread, src)) => { assert_eq!(nread, 1); assert_eq!(buf[0], 99); assert_eq!(src, client_ip); } - None => fail!() + Err(*) => fail!() } } - None => fail!() + Err(*) => fail!() } } do spawntask { match UdpSocket::bind(client_ip) { - Some(ref mut client) => { + Ok(ref mut client) => { port.take().recv(); - client.sendto([99], server_ip) + client.sendto([99], server_ip); } - None => fail!() + Err(*) => fail!() } } } @@ -217,32 +182,32 @@ mod test { do spawntask { match UdpSocket::bind(server_ip) { - Some(server) => { + Ok(server) => { let server = ~server; let mut stream = server.connect(client_ip); chan.take().send(()); let mut buf = [0]; match stream.read(buf) { - Some(nread) => { + Ok(nread) => { assert_eq!(nread, 1); assert_eq!(buf[0], 99); } - None => fail!() + Err(*) => fail!() } } - None => fail!() + Err(*) => fail!() } } do spawntask { match UdpSocket::bind(client_ip) { - Some(client) => { + Ok(client) => { let client = ~client; let mut stream = client.connect(server_ip); port.take().recv(); stream.write([99]); } - None => fail!() + Err(*) => fail!() } } } @@ -259,32 +224,32 @@ mod test { do spawntask { match UdpSocket::bind(server_ip) { - Some(server) => { + Ok(server) => { let server = ~server; let mut stream = server.connect(client_ip); chan.take().send(()); let mut buf = [0]; match stream.read(buf) { - Some(nread) => { + Ok(nread) => { assert_eq!(nread, 1); assert_eq!(buf[0], 99); } - None => fail!() + Err(*) => fail!() } } - None => fail!() + Err(*) => fail!() } } do spawntask { match UdpSocket::bind(client_ip) { - Some(client) => { + Ok(client) => { let client = ~client; let mut stream = client.connect(server_ip); port.take().recv(); stream.write([99]); } - None => fail!() + Err(*) => fail!() } } } @@ -296,13 +261,13 @@ mod test { do spawntask { let server = UdpSocket::bind(addr); - assert!(server.is_some()); + assert!(server.is_ok()); let mut server = server.unwrap(); // Make sure socket_name gives // us the socket we binded to. let so_name = server.socket_name(); - assert!(so_name.is_some()); + assert!(so_name.is_ok()); assert_eq!(addr, so_name.unwrap()); } diff --git a/src/libstd/io/net/unix.rs b/src/libstd/io/net/unix.rs index 6d2deccaa4cfe..f83c63e481025 100644 --- a/src/libstd/io/net/unix.rs +++ b/src/libstd/io/net/unix.rs @@ -28,7 +28,7 @@ use c_str::ToCStr; use rt::rtio::{IoFactory, RtioUnixListener, with_local_io}; use rt::rtio::{RtioUnixAcceptor, RtioPipe}; use io::pipe::PipeStream; -use io::{io_error, Listener, Acceptor, Reader, Writer}; +use io::{IoResult, Listener, Acceptor, Reader, Writer}; /// A stream which communicates over a named pipe. pub struct UnixStream { @@ -58,26 +58,20 @@ impl UnixStream { /// let mut stream = UnixStream::connect(&server); /// stream.write([1, 2, 3]); /// - pub fn connect(path: &P) -> Option { + pub fn connect(path: &P) -> IoResult { with_local_io(|io| { - match io.unix_connect(&path.to_c_str()) { - Ok(s) => Some(UnixStream::new(s)), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + io.unix_connect(&path.to_c_str()).map(UnixStream::new) }) } } impl Reader for UnixStream { - fn read(&mut self, buf: &mut [u8]) -> Option { self.obj.read(buf) } + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.obj.read(buf) } fn eof(&mut self) -> bool { self.obj.eof() } } impl Writer for UnixStream { - fn write(&mut self, buf: &[u8]) { self.obj.write(buf) } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) } } pub struct UnixListener { @@ -107,28 +101,16 @@ impl UnixListener { /// client.write([1, 2, 3, 4]); /// } /// - pub fn bind(path: &P) -> Option { + pub fn bind(path: &P) -> IoResult { with_local_io(|io| { - match io.unix_bind(&path.to_c_str()) { - Ok(s) => Some(UnixListener{ obj: s }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + io.unix_bind(&path.to_c_str()).map(|s| UnixListener { obj: s }) }) } } impl Listener for UnixListener { - fn listen(self) -> Option { - match self.obj.listen() { - Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + fn listen(self) -> IoResult { + self.obj.listen().map(|a| UnixAcceptor { obj: a }) } } @@ -137,14 +119,8 @@ pub struct UnixAcceptor { } impl Acceptor for UnixAcceptor { - fn accept(&mut self) -> Option { - match self.obj.accept() { - Ok(s) => Some(UnixStream::new(s)), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } - } + fn accept(&mut self) -> IoResult { + self.obj.accept().map(UnixStream::new) } } @@ -185,30 +161,20 @@ mod tests { #[test] fn bind_error() { do run_in_mt_newsched_task { - let mut called = false; - io_error::cond.trap(|e| { - assert!(e.kind == PermissionDenied); - called = true; - }).inside(|| { - let listener = UnixListener::bind(&("path/to/nowhere")); - assert!(listener.is_none()); - }); - assert!(called); + match UnixListener::bind(&("path/to/nowhere")) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, PermissionDenied) + } } } #[test] fn connect_error() { do run_in_mt_newsched_task { - let mut called = false; - io_error::cond.trap(|e| { - assert_eq!(e.kind, OtherIoError); - called = true; - }).inside(|| { - let stream = UnixStream::connect(&("path/to/nowhere")); - assert!(stream.is_none()); - }); - assert!(called); + match UnixStream::connect(&("path/to/nowhere")) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, OtherIoError), + } } } @@ -227,9 +193,9 @@ mod tests { fn read_eof() { smalltest(proc(mut server) { let mut buf = [0]; - assert!(server.read(buf).is_none()); - assert!(server.read(buf).is_none()); - }, proc(_client) { + assert!(server.read(buf).is_err()); + assert!(server.read(buf).is_err()); + }, |_client| { // drop the client }) } @@ -240,13 +206,14 @@ mod tests { let buf = [0]; let mut stop = false; while !stop{ - io_error::cond.trap(|e| { - assert!(e.kind == BrokenPipe || e.kind == NotConnected, - "unknown error {:?}", e); - stop = true; - }).inside(|| { - server.write(buf); - }) + match server.write(buf) { + Ok(*) => {} + Err(e) => { + stop = true; + assert!(e.kind == BrokenPipe || e.kind == NotConnected, + "unknown error {:?}", e); + } + } } }, proc(_client) { // drop the client diff --git a/src/libstd/io/option.rs b/src/libstd/io/option.rs deleted file mode 100644 index 61c5411f3602f..0000000000000 --- a/src/libstd/io/option.rs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementations of I/O traits for the Option type -//! -//! I/O constructors return option types to allow errors to be handled. -//! These implementations allow e.g. `Option` to be used -//! as a `Reader` without unwrapping the option first. - -use option::*; -use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle}; -use super::{standard_error, PreviousIoError, io_error, IoError}; - -fn prev_io_error() -> IoError { - standard_error(PreviousIoError) -} - -impl Writer for Option { - fn write(&mut self, buf: &[u8]) { - match *self { - Some(ref mut writer) => writer.write(buf), - None => io_error::cond.raise(prev_io_error()) - } - } - - fn flush(&mut self) { - match *self { - Some(ref mut writer) => writer.flush(), - None => io_error::cond.raise(prev_io_error()) - } - } -} - -impl Reader for Option { - fn read(&mut self, buf: &mut [u8]) -> Option { - match *self { - Some(ref mut reader) => reader.read(buf), - None => { - io_error::cond.raise(prev_io_error()); - None - } - } - } - - fn eof(&mut self) -> bool { - match *self { - Some(ref mut reader) => reader.eof(), - None => { - io_error::cond.raise(prev_io_error()); - true - } - } - } -} - -impl Seek for Option { - fn tell(&self) -> u64 { - match *self { - Some(ref seeker) => seeker.tell(), - None => { - io_error::cond.raise(prev_io_error()); - 0 - } - } - } - fn seek(&mut self, pos: i64, style: SeekStyle) { - match *self { - Some(ref mut seeker) => seeker.seek(pos, style), - None => io_error::cond.raise(prev_io_error()) - } - } -} - -impl, L: Listener> Listener for Option { - fn listen(self) -> Option { - match self { - Some(listener) => listener.listen(), - None => { - io_error::cond.raise(prev_io_error()); - None - } - } - } -} - -impl> Acceptor for Option { - fn accept(&mut self) -> Option { - match *self { - Some(ref mut acceptor) => acceptor.accept(), - None => { - io_error::cond.raise(prev_io_error()); - None - } - } - } -} - -#[cfg(test)] -mod test { - use option::*; - use super::super::mem::*; - use rt::test::*; - use super::super::{PreviousIoError, io_error}; - - #[test] - fn test_option_writer() { - do run_in_mt_newsched_task { - let mut writer: Option = Some(MemWriter::new()); - writer.write([0, 1, 2]); - writer.flush(); - assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]); - } - } - - #[test] - fn test_option_writer_error() { - do run_in_mt_newsched_task { - let mut writer: Option = None; - - let mut called = false; - io_error::cond.trap(|err| { - assert_eq!(err.kind, PreviousIoError); - called = true; - }).inside(|| { - writer.write([0, 0, 0]); - }); - assert!(called); - - let mut called = false; - io_error::cond.trap(|err| { - assert_eq!(err.kind, PreviousIoError); - called = true; - }).inside(|| { - writer.flush(); - }); - assert!(called); - } - } - - #[test] - fn test_option_reader() { - do run_in_mt_newsched_task { - let mut reader: Option = Some(MemReader::new(~[0, 1, 2, 3])); - let mut buf = [0, 0]; - reader.read(buf); - assert_eq!(buf, [0, 1]); - assert!(!reader.eof()); - } - } - - #[test] - fn test_option_reader_error() { - let mut reader: Option = None; - let mut buf = []; - - let mut called = false; - io_error::cond.trap(|err| { - assert_eq!(err.kind, PreviousIoError); - called = true; - }).inside(|| { - reader.read(buf); - }); - assert!(called); - - let mut called = false; - io_error::cond.trap(|err| { - assert_eq!(err.kind, PreviousIoError); - called = true; - }).inside(|| { - assert!(reader.eof()); - }); - assert!(called); - } -} diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs index 373de1649edc4..905a1823dc76c 100644 --- a/src/libstd/io/pipe.rs +++ b/src/libstd/io/pipe.rs @@ -15,7 +15,7 @@ use prelude::*; use super::{Reader, Writer}; -use io::{io_error, EndOfFile}; +use io::IoResult; use io::native::file; use rt::rtio::{RtioPipe, with_local_io}; @@ -43,16 +43,8 @@ impl PipeStream { /// /// If the pipe cannot be created, an error will be raised on the /// `io_error` condition. - pub fn open(fd: file::fd_t) -> Option { - with_local_io(|io| { - match io.pipe_open(fd) { - Ok(obj) => Some(PipeStream { obj: obj }), - Err(e) => { - io_error::cond.raise(e); - None - } - } - }) + pub fn open(fd: file::fd_t) -> IoResult { + with_local_io(|io| io.pipe_open(fd).map(|obj| PipeStream { obj: obj })) } pub fn new(inner: ~RtioPipe) -> PipeStream { @@ -61,29 +53,10 @@ impl PipeStream { } impl Reader for PipeStream { - fn read(&mut self, buf: &mut [u8]) -> Option { - match self.obj.read(buf) { - Ok(read) => Some(read), - Err(ioerr) => { - // EOF is indicated by returning None - if ioerr.kind != EndOfFile { - io_error::cond.raise(ioerr); - } - return None; - } - } - } - + fn read(&mut self, buf: &mut [u8]) -> IoResult { self.obj.read(buf) } fn eof(&mut self) -> bool { false } } impl Writer for PipeStream { - fn write(&mut self, buf: &[u8]) { - match self.obj.write(buf) { - Ok(_) => (), - Err(ioerr) => { - io_error::cond.raise(ioerr); - } - } - } + fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) } } diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index 308e969c43a1f..b2ae98e4b09e2 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -15,7 +15,7 @@ use cell::Cell; use libc; use io; -use io::io_error; +use io::IoResult; use rt::rtio::{RtioProcess, IoFactory, with_local_io}; use fmt; @@ -94,7 +94,7 @@ pub enum ProcessExit { impl fmt::Default for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. - fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) { + fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) -> fmt::Result { match *obj { ExitStatus(code) => write!(f.buf, "exit code: {}", code), ExitSignal(code) => write!(f.buf, "signal: {}", code), @@ -119,20 +119,17 @@ impl ProcessExit { impl Process { /// Creates a new pipe initialized, but not bound to any particular /// source/destination - pub fn new(config: ProcessConfig) -> Option { + pub fn new(config: ProcessConfig) -> IoResult { let config = Cell::new(config); with_local_io(|io| { match io.spawn(config.take()) { - Ok((p, io)) => Some(Process{ + Ok((p, io)) => Ok(Process{ handle: p, io: io.move_iter().map(|p| p.map(|p| io::PipeStream::new(p)) ).collect() }), - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } + Err(ioerr) => Err(ioerr) } }) } @@ -147,13 +144,8 @@ impl Process { /// function. /// /// If the signal delivery fails, then the `io_error` condition is raised on - pub fn signal(&mut self, signal: int) { - match self.handle.kill(signal) { - Ok(()) => {} - Err(err) => { - io_error::cond.raise(err) - } - } + pub fn signal(&mut self, signal: int) -> IoResult<()> { + self.handle.kill(signal) } /// Wait for the child to exit completely, returning the status that it diff --git a/src/libstd/io/result.rs b/src/libstd/io/result.rs new file mode 100644 index 0000000000000..b7e293fe59aca --- /dev/null +++ b/src/libstd/io/result.rs @@ -0,0 +1,138 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementations of I/O traits for the IoResult type +//! +//! I/O constructors return option types to allow errors to be handled. +//! These implementations allow e.g. `IoResult` to be used +//! as a `Reader` without unwrapping the option first. + +use clone::Clone; +use result::{Ok, Err}; +use super::IoResult; +use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle}; + +impl Writer for IoResult { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + match *self { + Ok(ref mut writer) => writer.write(buf), + Err(ref e) => Err(e.clone()) + } + } + + fn flush(&mut self) -> IoResult<()> { + match *self { + Ok(ref mut writer) => writer.flush(), + Err(ref e) => Err(e.clone()), + } + } +} + +impl Reader for IoResult { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + match *self { + Ok(ref mut reader) => reader.read(buf), + Err(ref e) => Err(e.clone()) + } + } + + fn eof(&mut self) -> bool { + match *self { + Ok(ref mut reader) => reader.eof(), + Err(*) => true, + } + } +} + +impl Seek for IoResult { + fn tell(&self) -> IoResult { + match *self { + Ok(ref seeker) => seeker.tell(), + Err(ref e) => Err(e.clone()), + } + } + fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> { + match *self { + Ok(ref mut seeker) => seeker.seek(pos, style), + Err(ref e) => Err(e.clone()) + } + } +} + +impl, L: Listener> Listener for IoResult { + fn listen(self) -> IoResult { + (if_ok!(self)).listen() + } +} + +impl> Acceptor for IoResult { + fn accept(&mut self) -> IoResult { + match *self { + Ok(ref mut acceptor) => acceptor.accept(), + Err(ref e) => Err(e.clone()), + } + } +} + +#[cfg(test)] +mod test { + use result::{Ok, Err}; + use super::super::mem::*; + use rt::test::*; + use super::super::{standard_error, EndOfFile, IoResult}; + + #[test] + fn test_option_writer() { + do run_in_mt_newsched_task { + let mut writer: IoResult = Ok(MemWriter::new()); + writer.write([0, 1, 2]); + writer.flush(); + assert_eq!(writer.unwrap().inner(), ~[0, 1, 2]); + } + } + + #[test] + fn test_option_writer_error() { + do run_in_mt_newsched_task { + let mut writer: IoResult = Err(standard_error(EndOfFile)); + + match writer.write([0, 0, 0]) { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, EndOfFile), + } + match writer.flush() { + Ok(*) => fail!(), + Err(e) => assert_eq!(e.kind, EndOfFile), + } + } + } + + #[test] + fn test_option_reader() { + do run_in_mt_newsched_task { + let mut reader: IoResult = Ok(MemReader::new(~[0, 1, 2, 3])); + let mut buf = [0, 0]; + reader.read(buf); + assert_eq!(buf, [0, 1]); + assert!(!reader.eof()); + } + } + + #[test] + fn test_option_reader_error() { + let mut reader: IoResult = Err(standard_error(EndOfFile)); + let mut buf = []; + + match reader.read(buf) { + Err(e) => assert_eq!(e.kind, EndOfFile), + Ok(*) => fail!(), + } + } +} diff --git a/src/libstd/io/signal.rs b/src/libstd/io/signal.rs index f6e79a0332321..e1d72afca8694 100644 --- a/src/libstd/io/signal.rs +++ b/src/libstd/io/signal.rs @@ -23,9 +23,8 @@ use clone::Clone; use comm::{Port, SharedChan, stream}; use container::{Map, MutableMap}; use hashmap; -use io::io_error; -use option::{Some, None}; use result::{Err, Ok}; +use io::IoResult; use rt::rtio::{IoFactory, RtioSignal, with_local_io}; #[repr(int)] @@ -119,22 +118,19 @@ impl Listener { /// If this function fails to register a signal handler, then an error will /// be raised on the `io_error` condition and the function will return /// false. - pub fn register(&mut self, signum: Signum) -> bool { + pub fn register(&mut self, signum: Signum) -> IoResult<()> { if self.handles.contains_key(&signum) { - return true; // self is already listening to signum, so succeed + return Ok(()); // self is already listening to signum, so succeed } with_local_io(|io| { match io.signal(signum, self.chan.clone()) { Ok(w) => { self.handles.insert(signum, w); - Some(()) + Ok(()) }, - Err(ioerr) => { - io_error::cond.raise(ioerr); - None - } + Err(ioerr) => Err(ioerr), } - }).is_some() + }) } /// Unregisters a signal. If this listener currently had a handler diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 2aa8b0c7ed6d5..fd9c085ab4cf0 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -28,12 +28,12 @@ out.write(bytes!("Hello, world!")); use fmt; use libc; -use option::{Option, Some, None}; +use option::{Some, None}; use result::{Ok, Err}; use io::buffered::LineBufferedWriter; use rt::rtio::{IoFactory, RtioTTY, RtioFileStream, with_local_io, CloseAsynchronously}; -use super::{Reader, Writer, io_error, IoError, OtherIoError, +use super::{Reader, Writer, IoResult, IoError, OtherIoError, standard_error, EndOfFile}; // And so begins the tale of acquiring a uv handle to a stdio stream on all @@ -73,7 +73,7 @@ fn src(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T { with_local_io(|io| { let fd = unsafe { libc::dup(fd) }; match io.tty_open(fd, readable) { - Ok(tty) => Some(f(TTY(tty))), + Ok(tty) => Ok(f(TTY(tty))), Err(_) => { // It's not really that desirable if these handles are closed // synchronously, and because they're squirreled away in a task @@ -81,7 +81,7 @@ fn src(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T { // attempted to get destroyed. This means that if we run a // synchronous destructor we'll attempt to do some scheduling // operations which will just result in sadness. - Some(f(File(io.fs_from_raw_fd(fd, CloseAsynchronously)))) + Ok(f(File(io.fs_from_raw_fd(fd, CloseAsynchronously)))) } } }).unwrap() @@ -119,9 +119,9 @@ pub fn stderr() -> StdWriter { // with_task_stdout(|io1| { // with_task_stdout(|io2| { // // io1 aliases io2 -// }) -// }) -fn with_task_stdout(f: |&mut Writer|) { +// } +// } +fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) -> IoResult<()> { use rt::local::Local; use rt::task::Task; @@ -157,34 +157,33 @@ fn with_task_stdout(f: |&mut Writer|) { /// Note that logging macros do not use this stream. Using the logging macros /// will emit output to stderr, and while they are line buffered the log /// messages are always terminated in a newline (no need to flush). -pub fn flush() { +pub fn flush() -> IoResult<()> { with_task_stdout(|io| io.flush()) } /// Prints a string to the stdout of the current process. No newline is emitted /// after the string is printed. -pub fn print(s: &str) { +pub fn print(s: &str) -> IoResult<()> { with_task_stdout(|io| io.write(s.as_bytes())) } /// Prints a string as a line. to the stdout of the current process. A literal /// `\n` character is printed to the console after the string. -pub fn println(s: &str) { +pub fn println(s: &str) -> IoResult<()> { with_task_stdout(|io| { - io.write(s.as_bytes()); - io.write(['\n' as u8]); + io.write(s.as_bytes()).and_then(|()| io.write(['\n' as u8])) }) } /// Similar to `print`, but takes a `fmt::Arguments` structure to be compatible /// with the `format_args!` macro. -pub fn print_args(fmt: &fmt::Arguments) { +pub fn print_args(fmt: &fmt::Arguments) -> IoResult<()> { with_task_stdout(|io| fmt::write(io, fmt)) } /// Similar to `println`, but takes a `fmt::Arguments` structure to be /// compatible with the `format_args!` macro. -pub fn println_args(fmt: &fmt::Arguments) { +pub fn println_args(fmt: &fmt::Arguments) -> IoResult<()> { with_task_stdout(|io| fmt::writeln(io, fmt)) } @@ -194,7 +193,7 @@ pub struct StdReader { } impl Reader for StdReader { - fn read(&mut self, buf: &mut [u8]) -> Option { + fn read(&mut self, buf: &mut [u8]) -> IoResult { let ret = match self.inner { TTY(ref mut tty) => tty.read(buf), File(ref mut file) => file.read(buf).map(|i| i as uint), @@ -205,15 +204,9 @@ impl Reader for StdReader { // return an actual EOF error, but apparently for stdin it's a // little different. Hence, here we convert a 0 length read to an // end-of-file indicator so the caller knows to stop reading. - Ok(0) => { - io_error::cond.raise(standard_error(EndOfFile)); - None - } - Ok(amt) => Some(amt as uint), - Err(e) => { - io_error::cond.raise(e); - None - } + Ok(0) => Err(standard_error(EndOfFile)), + Ok(amt) => Ok(amt as uint), + Err(e) => Err(e) } } @@ -236,25 +229,14 @@ impl StdWriter { /// /// This function will raise on the `io_error` condition if an error /// happens. - pub fn winsize(&mut self) -> Option<(int, int)> { + pub fn winsize(&mut self) -> IoResult<(int, int)> { match self.inner { - TTY(ref mut tty) => { - match tty.get_winsize() { - Ok(p) => Some(p), - Err(e) => { - io_error::cond.raise(e); - None - } - } - } - File(*) => { - io_error::cond.raise(IoError { - kind: OtherIoError, - desc: "stream is not a tty", - detail: None, - }); - None - } + TTY(ref mut tty) => tty.get_winsize(), + File(*) => Err(IoError { + kind: OtherIoError, + desc: "stream is not a tty", + detail: None, + }) } } @@ -265,21 +247,14 @@ impl StdWriter { /// /// This function will raise on the `io_error` condition if an error /// happens. - pub fn set_raw(&mut self, raw: bool) { + pub fn set_raw(&mut self, raw: bool) -> IoResult<()> { match self.inner { - TTY(ref mut tty) => { - match tty.set_raw(raw) { - Ok(()) => {}, - Err(e) => io_error::cond.raise(e), - } - } - File(*) => { - io_error::cond.raise(IoError { - kind: OtherIoError, - desc: "stream is not a tty", - detail: None, - }); - } + TTY(ref mut tty) => tty.set_raw(raw), + File(*) => Err(IoError { + kind: OtherIoError, + desc: "stream is not a tty", + detail: None, + }) } } @@ -293,14 +268,10 @@ impl StdWriter { } impl Writer for StdWriter { - fn write(&mut self, buf: &[u8]) { - let ret = match self.inner { + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + match self.inner { TTY(ref mut tty) => tty.write(buf), File(ref mut file) => file.write(buf), - }; - match ret { - Ok(()) => {} - Err(e) => io_error::cond.raise(e) } } } diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index 8dda79358887e..632e0ec1cbb7b 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -39,9 +39,7 @@ loop { */ use comm::{Port, PortOne}; -use option::{Option, Some, None}; -use result::{Ok, Err}; -use io::io_error; +use io::IoResult; use rt::rtio::{IoFactory, RtioTimer, with_local_io}; pub struct Timer { @@ -59,18 +57,8 @@ impl Timer { /// Creates a new timer which can be used to put the current task to sleep /// for a number of milliseconds, or to possibly create channels which will /// get notified after an amount of time has passed. - pub fn new() -> Option { - with_local_io(|io| { - match io.timer_init() { - Ok(t) => Some(Timer { obj: t }), - Err(ioerr) => { - debug!("Timer::init: failed to init: {:?}", ioerr); - io_error::cond.raise(ioerr); - None - } - } - - }) + pub fn new() -> IoResult { + with_local_io(|io| io.timer_init().map(|t| Timer { obj: t })) } /// Blocks the current task for `msecs` milliseconds. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7a8b4467fcc9c..574b8ba0de1d1 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -91,6 +91,36 @@ pub mod linkhack { } } +macro_rules! if_ok ( + ($inp: expr) => ( + match $inp { + Ok(v) => v, + Err(e) => return Err(e) + } + ) +) + +macro_rules! seq ( + (let $p:pat = $e:expr; $($rest:tt)*) => ({ + let $p = match $e { + Ok(e) => e, Err(e) => return Err(e) + }; + seq!($($rest)*) + }); + ($e:expr; $($rest:tt)+) => ({ + match $e { + Ok(()) => {}, Err(e) => return Err(e) + } + seq!($($rest)+) + }); + ($e:expr;) => ( + match $e { + Ok(()) => {}, Err(e) => return Err(e) + } + ); + ($e:expr) => ($e) +) + /* The Prelude. */ pub mod prelude; diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 715072653a7ab..8fd15a65f8270 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -438,7 +438,7 @@ impl AsResult for Option { impl fmt::Default for Option { #[inline] - fn fmt(s: &Option, f: &mut fmt::Formatter) { + fn fmt(s: &Option, f: &mut fmt::Formatter) -> fmt::Result { match *s { Some(ref t) => write!(f.buf, "Some({})", *t), None => write!(f.buf, "None") diff --git a/src/libstd/os.rs b/src/libstd/os.rs index baa4423220c5d..f814fb8e00df0 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1441,7 +1441,6 @@ mod tests { use result::{Ok, Err}; use os::*; use libc::*; - use io; use io::fs; #[cfg(unix)] @@ -1485,7 +1484,7 @@ mod tests { assert!(*chunk.data == 0xbe); close(fd); } - io::ignore_io_error(|| fs::unlink(&path)); + fs::unlink(&path); } // More recursive_mkdir tests are in extra::tempfile diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 2b6009206acf7..97f9da5705ed5 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -529,7 +529,7 @@ pub struct Display<'self, P> { } impl<'self, P: GenericPath> fmt::Default for Display<'self, P> { - fn fmt(d: &Display

, f: &mut fmt::Formatter) { + fn fmt(d: &Display

, f: &mut fmt::Formatter) -> fmt::Result { d.with_str(|s| f.pad(s)) } } diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index 4beabb8bf6aa4..f703de23642dd 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -10,7 +10,7 @@ //! A wrapper around any Reader to treat it as an RNG. -use option::{Some, None}; +use result::{Ok, Err}; use io::Reader; use rand::Rng; @@ -50,26 +50,26 @@ impl Rng for ReaderRng { // platform just involves blitting the bytes into the memory // of the u32, similarly for BE on BE; avoiding byteswapping. if cfg!(target_endian="little") { - self.reader.read_le_u32() + self.reader.read_le_u32().unwrap() } else { - self.reader.read_be_u32() + self.reader.read_be_u32().unwrap() } } fn next_u64(&mut self) -> u64 { // see above for explanation. if cfg!(target_endian="little") { - self.reader.read_le_u64() + self.reader.read_le_u64().unwrap() } else { - self.reader.read_be_u64() + self.reader.read_be_u64().unwrap() } } fn fill_bytes(&mut self, v: &mut [u8]) { if v.len() == 0 { return } match self.reader.read(v) { - Some(n) if n == v.len() => return, - Some(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \ - read {} out of {} bytes.", n, v.len()), - None => fail!("ReaderRng.fill_bytes reached eof.") + Ok(n) if n == v.len() => return, + Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \ + read {} out of {} bytes.", n, v.len()), + Err(e) => fail!("ReaderRng.fill_bytes error: {}", e) } } } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index d26989c36e66a..b70e78a924b4a 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -24,46 +24,47 @@ use iter::Iterator; use libc::c_void; use option::{Some, None}; use ptr; -use reflect; use reflect::{MovePtr, align}; +use reflect; +use result::Ok; use str::StrSlice; use to_str::ToStr; -use vec::OwnedVector; use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc}; use unstable::raw; +use vec::OwnedVector; /// Representations trait Repr { - fn write_repr(&self, writer: &mut io::Writer); + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> ; } impl Repr for () { - fn write_repr(&self, writer: &mut io::Writer) { - writer.write("()".as_bytes()); + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> { + writer.write("()".as_bytes()) } } impl Repr for bool { - fn write_repr(&self, writer: &mut io::Writer) { + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> { let s = if *self { "true" } else { "false" }; writer.write(s.as_bytes()) } } impl Repr for int { - fn write_repr(&self, writer: &mut io::Writer) { + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> { ::int::to_str_bytes(*self, 10u, |bits| { - writer.write(bits); + writer.write(bits) }) } } macro_rules! int_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty { - fn write_repr(&self, writer: &mut io::Writer) { + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> { ::$ty::to_str_bytes(*self, 10u, |bits| { - writer.write(bits); - writer.write(bytes!($suffix)); + writer.write(bits).and_then(|()| + writer.write(bytes!($suffix))) }) } })) @@ -79,10 +80,10 @@ int_repr!(u32, "u32") int_repr!(u64, "u64") macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty { - fn write_repr(&self, writer: &mut io::Writer) { + fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> { let s = self.to_str(); - writer.write(s.as_bytes()); - writer.write(bytes!($suffix)); + writer.write(s.as_bytes()).and_then(|()| + writer.write(bytes!($suffix))) } })) @@ -236,9 +237,10 @@ impl<'self> ReprVisitor<'self> { _ => { char::escape_unicode(ch, |c| { self.writer.write([c as u8]); - }) + } + Ok(()) // XXX: ignoring errors } - } + }; // XXX: this shouldn't ignore the error } } @@ -607,13 +609,14 @@ impl<'self> TyVisitor for ReprVisitor<'self> { fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true } } -pub fn write_repr(writer: &mut io::Writer, object: &T) { +pub fn write_repr(writer: &mut io::Writer, object: &T) -> io::IoResult<()> { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; let tydesc = get_tydesc::(); let u = ReprVisitor(ptr, writer); let mut v = reflect::MovePtrAdaptor(u); visit_tydesc(tydesc, &mut v as &mut TyVisitor); + Ok(()) // XXX: this should catch errors from down below } } @@ -700,7 +703,8 @@ fn test_repr() { exact_test(&("'"), "\"'\""); exact_test(&("\""), "\"\\\"\""); - exact_test(&println, "fn(&str)"); + fn foo(_: &str) {} + exact_test(&foo, "fn(&str)"); exact_test(&swap::, "fn(&mut int, &mut int)"); exact_test(&is_alphabetic, "fn(char) -> bool"); exact_test(&(~5 as ~ToStr), "~to_str::ToStr:Send"); diff --git a/src/libstd/result.rs b/src/libstd/result.rs index ff425a8a73b25..cafef5344755d 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -332,7 +332,7 @@ impl AsOption for Result { impl fmt::Default for Result { #[inline] - fn fmt(s: &Result, f: &mut fmt::Formatter) { + fn fmt(s: &Result, f: &mut fmt::Formatter) -> fmt::Result { match *s { Ok(ref t) => write!(f.buf, "Ok({})", *t), Err(ref e) => write!(f.buf, "Err({})", *e) diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index f83932f9ffa28..1786bd0a5aebc 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -22,7 +22,7 @@ use io::net::ip::{IpAddr, SocketAddr}; use io::process::{ProcessConfig, ProcessExit}; use io::signal::Signum; use io::{FileMode, FileAccess, FileStat, FilePermission}; -use io::{SeekStyle}; +use io::{SeekStyle, IoResult}; pub trait Callback { fn call(&mut self); @@ -75,7 +75,7 @@ pub enum CloseBehavior { CloseAsynchronously, } -pub fn with_local_io(f: |&mut IoFactory| -> Option) -> Option { +pub fn with_local_io(f: |&mut IoFactory| -> IoResult) -> IoResult { use rt::sched::Scheduler; use rt::local::Local; use io::native; diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 7f977fdd2a39f..660c860b67a06 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -221,20 +221,16 @@ impl Process { let ch_clone = ch.clone(); do spawn { - io::ignore_io_error(|| { - match error.take() { - Some(ref mut e) => ch.send((2, e.read_to_end())), - None => ch.send((2, ~[])) - } - }) + match error.take() { + Some(ref mut e) => ch.send((2, e.read_to_end())), + None => ch.send((2, Ok(~[]))) + } } do spawn { - io::ignore_io_error(|| { - match output.take() { - Some(ref mut e) => ch_clone.send((1, e.read_to_end())), - None => ch_clone.send((1, ~[])) - } - }) + match output.take() { + Some(ref mut e) => ch_clone.send((1, e.read_to_end())), + None => ch_clone.send((1, Ok(~[]))) + } } let status = self.finish(); @@ -248,8 +244,8 @@ impl Process { }; return ProcessOutput {status: status, - output: outs, - error: errs}; + output: outs.unwrap(), + error: errs.unwrap()}; } /** @@ -324,12 +320,13 @@ mod tests { use option::{Option, None, Some}; use os; use path::Path; + use result::{Ok, Err}; + use io::native::file; + use io::{Writer, Reader}; use run; use str; use task::spawn; use unstable::running_on_valgrind; - use io::native::file; - use io::{Writer, Reader}; #[test] #[cfg(not(target_os="android"))] // FIXME(#10380) @@ -410,8 +407,8 @@ mod tests { let mut buf = [0, ..1024]; loop { match reader.read(buf) { - Some(n) => { res.push_all(buf.slice_to(n)); } - None => break + Ok(n) => { res.push_all(buf.slice_to(n)); } + Err(*) => break } } str::from_utf8_owned(res) @@ -508,8 +505,8 @@ mod tests { let parent_dir = os::getcwd(); let child_dir = Path::new(output.trim()); - let parent_stat = parent_dir.stat(); - let child_stat = child_dir.stat(); + let parent_stat = parent_dir.stat().unwrap(); + let child_stat = child_dir.stat().unwrap(); assert_eq!(parent_stat.unstable.device, child_stat.unstable.device); assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode); @@ -525,8 +522,8 @@ mod tests { let output = str::from_utf8(prog.finish_with_output().output); let child_dir = Path::new(output.trim()); - let parent_stat = parent_dir.stat(); - let child_stat = child_dir.stat(); + let parent_stat = parent_dir.stat().unwrap(); + let child_stat = child_dir.stat().unwrap(); assert_eq!(parent_stat.unstable.device, child_stat.unstable.device); assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 5a37e0a5ab319..2eef0b25129eb 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -19,7 +19,6 @@ use parse; use parse::token::{get_ident_interner}; use print::pprust; -use std::io; use std::io::File; use std::str; @@ -91,7 +90,7 @@ pub fn expand_include_str(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult { let file = get_single_str_from_tts(cx, sp, tts, "include_str!"); let file = res_rel_file(cx, sp, &Path::new(file)); - let bytes = match io::result(|| File::open(&file).read_to_end()) { + let bytes = match File::open(&file).read_to_end() { Err(e) => { cx.span_fatal(sp, format!("couldn't read {}: {}", file.display(), e.desc)); @@ -113,7 +112,7 @@ pub fn expand_include_bin(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) let file = get_single_str_from_tts(cx, sp, tts, "include_bin!"); let file = res_rel_file(cx, sp, &Path::new(file)); - match io::result(|| File::open(&file).read_to_end()) { + match File::open(&file).read_to_end() { Err(e) => { cx.span_fatal(sp, format!("couldn't read {}: {}", file.display(), e.desc)); diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index d8f2d8a53807a..7788356451cac 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -346,7 +346,7 @@ pub fn gather_comments_and_literals(span_diagnostic: path: @str, srdr: &mut io::Reader) -> (~[cmnt], ~[lit]) { - let src = str::from_utf8(srdr.read_to_end()).to_managed(); + let src = str::from_utf8(srdr.read_to_end().unwrap()).to_managed(); let cm = CodeMap::new(); let filemap = cm.new_filemap(path, src); let rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 8fbd152543dd9..821039a9c6166 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -19,7 +19,6 @@ use parse::attr::parser_attr; use parse::lexer::reader; use parse::parser::Parser; -use std::io; use std::io::File; use std::str; @@ -262,7 +261,7 @@ pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option) None => sess.span_diagnostic.handler().fatal(msg), } }; - let bytes = match io::result(|| File::open(path).read_to_end()) { + let bytes = match File::open(path).read_to_end() { Ok(bytes) => bytes, Err(e) => { err(format!("couldn't read {}: {}", path.display(), e.desc)); diff --git a/src/test/compile-fail/by-move-pattern-binding.rs b/src/test/compile-fail/by-move-pattern-binding.rs index 460e2ce23fc9f..d59e41f37f197 100644 --- a/src/test/compile-fail/by-move-pattern-binding.rs +++ b/src/test/compile-fail/by-move-pattern-binding.rs @@ -17,6 +17,6 @@ fn main() { }; match &s.x { &Foo => {} - &Bar(ref identifier) => println(*identifier) + &Bar(ref identifier) => { println(*identifier); } }; } diff --git a/src/test/compile-fail/closure-reform-bad.rs b/src/test/compile-fail/closure-reform-bad.rs index 3da709942e0e6..708994fe73a20 100644 --- a/src/test/compile-fail/closure-reform-bad.rs +++ b/src/test/compile-fail/closure-reform-bad.rs @@ -7,7 +7,7 @@ fn call_bare(f: fn(&str)) { fn main() { let string = "world!"; - let f: |&str| = |s| println(s + string); + let f: |&str| = |s| { println(s + string); }; call_bare(f) //~ ERROR mismatched types } diff --git a/src/test/compile-fail/moves-based-on-type-block-bad.rs b/src/test/compile-fail/moves-based-on-type-block-bad.rs index 690c778183c60..591396cf9729a 100644 --- a/src/test/compile-fail/moves-based-on-type-block-bad.rs +++ b/src/test/compile-fail/moves-based-on-type-block-bad.rs @@ -18,7 +18,7 @@ fn main() { f(&s, |hellothere| { match hellothere.x { ~Foo(_) => {} - ~Bar(x) => println(x.to_str()), //~ ERROR cannot move out + ~Bar(x) => { println(x.to_str()); }, //~ ERROR cannot move out ~Baz => {} } }) diff --git a/src/test/compile-fail/tuple-struct-nonexhaustive.rs b/src/test/compile-fail/tuple-struct-nonexhaustive.rs index 1f14fbb27adee..28ce49f959901 100644 --- a/src/test/compile-fail/tuple-struct-nonexhaustive.rs +++ b/src/test/compile-fail/tuple-struct-nonexhaustive.rs @@ -13,7 +13,7 @@ struct Foo(int, int); fn main() { let x = Foo(1, 2); match x { //~ ERROR non-exhaustive - Foo(1, b) => println!("{}", b), - Foo(2, b) => println!("{}", b) + Foo(1, b) => { println!("{}", b); } + Foo(2, b) => { println!("{}", b); } } } diff --git a/src/test/run-pass/closure-reform.rs b/src/test/run-pass/closure-reform.rs index 629a807266182..71f33f25d4cb4 100644 --- a/src/test/run-pass/closure-reform.rs +++ b/src/test/run-pass/closure-reform.rs @@ -3,6 +3,8 @@ use std::cast; +fn println(_: &str) {} + fn call_it(f: proc(~str) -> ~str) { println(f(~"Fred")) } diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index 07d9fb95dcb55..95282c41db0f2 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -40,9 +40,7 @@ fn test_destroy_twice() { let mut p = run::Process::new(PROG, [], run::ProcessOptions::new()); p.destroy(); // this shouldnt crash... - io::io_error::cond.trap(|_| {}).inside(|| { - p.destroy(); // ...and nor should this (and nor should the destructor) - }) + p.destroy(); // ...and nor should this } fn test_destroy_actually_kills(force: bool) { diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index f39bb8fef0cf8..767695bd70228 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -24,10 +24,14 @@ struct A; struct B; impl fmt::Signed for A { - fn fmt(_: &A, f: &mut fmt::Formatter) { f.buf.write("aloha".as_bytes()); } + fn fmt(_: &A, f: &mut fmt::Formatter) -> fmt::Result { + f.buf.write("aloha".as_bytes()) + } } impl fmt::Signed for B { - fn fmt(_: &B, f: &mut fmt::Formatter) { f.buf.write("adios".as_bytes()); } + fn fmt(_: &B, f: &mut fmt::Formatter) -> fmt::Result { + f.buf.write("adios".as_bytes()) + } } macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) }) diff --git a/src/test/run-pass/issue-5926.rs b/src/test/run-pass/issue-5926.rs index dbaa5460fd090..f8ed17d0ca315 100644 --- a/src/test/run-pass/issue-5926.rs +++ b/src/test/run-pass/issue-5926.rs @@ -14,6 +14,6 @@ pub fn main() { let mut your_favorite_numbers = @[1,2,3]; let mut my_favorite_numbers = @[4,5,6]; let f = your_favorite_numbers + my_favorite_numbers; - println!("The third favorite number is {:?}.", f) + println!("The third favorite number is {:?}.", f); } diff --git a/src/test/run-pass/issue-8398.rs b/src/test/run-pass/issue-8398.rs index f9169618c2a3b..abce015b292ce 100644 --- a/src/test/run-pass/issue-8398.rs +++ b/src/test/run-pass/issue-8398.rs @@ -11,7 +11,7 @@ use std::io; fn foo(a: &mut io::Writer) { - a.write([]) + a.write([]); } pub fn main(){} diff --git a/src/test/run-pass/rtio-processes.rs b/src/test/run-pass/rtio-processes.rs index 00f565324ecda..979da9b54cbcf 100644 --- a/src/test/run-pass/rtio-processes.rs +++ b/src/test/run-pass/rtio-processes.rs @@ -41,7 +41,7 @@ fn smoke() { io: io, }; let p = Process::new(args); - assert!(p.is_some()); + assert!(p.is_ok()); let mut p = p.unwrap(); assert!(p.wait().success()); } @@ -58,7 +58,7 @@ fn smoke_failure() { cwd: None, io: io, }; - match io::result(|| Process::new(args)) { + match Process::new(args) { Ok(*) => fail!(), Err(*) => {} } @@ -77,7 +77,7 @@ fn exit_reported_right() { io: io, }; let p = Process::new(args); - assert!(p.is_some()); + assert!(p.is_ok()); let mut p = p.unwrap(); assert!(p.wait().matches_exit_status(1)); } @@ -94,7 +94,7 @@ fn signal_reported_right() { io: io, }; let p = Process::new(args); - assert!(p.is_some()); + assert!(p.is_ok()); let mut p = p.unwrap(); match p.wait() { process::ExitSignal(1) => {}, @@ -103,20 +103,12 @@ fn signal_reported_right() { } fn read_all(input: &mut Reader) -> ~str { - let mut ret = ~""; - let mut buf = [0, ..1024]; - loop { - match input.read(buf) { - None => { break } - Some(n) => { ret = ret + str::from_utf8(buf.slice_to(n)); } - } - } - return ret; + str::from_utf8(input.read_to_end().unwrap()) } fn run_output(args: ProcessConfig) -> ~str { let p = Process::new(args); - assert!(p.is_some()); + assert!(p.is_ok()); let mut p = p.unwrap(); assert!(p.io[0].is_none()); assert!(p.io[1].is_some()); diff --git a/src/test/run-pass/stat.rs b/src/test/run-pass/stat.rs index b186a68281062..cf11e08d27a8c 100644 --- a/src/test/run-pass/stat.rs +++ b/src/test/run-pass/stat.rs @@ -21,8 +21,8 @@ pub fn main() { { match File::create(&path) { - None => unreachable!(), - Some(f) => { + Err(*) => unreachable!(), + Ok(f) => { let mut f = f; for _ in range(0u, 1000) { f.write([0]); @@ -32,5 +32,5 @@ pub fn main() { } assert!(path.exists()); - assert_eq!(path.stat().size, 1000); + assert_eq!(path.stat().unwrap().size, 1000); } diff --git a/src/test/run-pass/struct-pattern-matching.rs b/src/test/run-pass/struct-pattern-matching.rs index d2b038fab0e9d..45bfcb0b0e0ac 100644 --- a/src/test/run-pass/struct-pattern-matching.rs +++ b/src/test/run-pass/struct-pattern-matching.rs @@ -16,6 +16,6 @@ struct Foo { pub fn main() { let a = Foo { x: 1, y: 2 }; match a { - Foo { x: x, y: y } => println!("yes, {}, {}", x, y) + Foo { x: x, y: y } => { println!("yes, {}, {}", x, y); } } } diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs index 994941b4b2266..ed37ec2ba4f55 100644 --- a/src/test/run-pass/trait-inheritance-num2.rs +++ b/src/test/run-pass/trait-inheritance-num2.rs @@ -95,7 +95,7 @@ impl FloatExt for f32 {} impl FloatExt for f64 {} -fn test_float_ext(n: T) { println!("{}", n < n) } +fn test_float_ext(n: T) { println!("{}", n < n); } pub fn main() { test_float_ext(1f32); diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index 7909f01591228..a01c6a3a0f3d3 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -16,7 +16,7 @@ pub trait NumExt: Eq + Ord + Num + NumCast {} impl NumExt for f32 {} fn num_eq_one(n: T) { - println!("{}", n == NumCast::from(1).unwrap()) + println!("{}", n == NumCast::from(1).unwrap()); } pub fn main() {