diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index cbe4c52b47ebb..8896b44f06008 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -234,7 +234,13 @@ pub fn run_tests(config: &config) {
// For context, see #8904
io::test::raise_fd_limit();
let res = test::run_tests_console(&opts, tests);
- if !res { fail!("Some tests failed"); }
+ match res {
+ Ok(true) => {}
+ Ok(false) => fail!("Some tests failed"),
+ Err(e) => {
+ println!("I/O failure during tests: {}", e);
+ }
+ }
}
pub fn test_opts(config: &config) -> test::TestOpts {
@@ -255,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/procsrv.rs b/src/compiletest/procsrv.rs
index 83fb267b0e720..019803a933779 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/compiletest/procsrv.rs
@@ -58,9 +58,9 @@ pub fn run(lib_path: &str,
});
match opt_process {
- Some(ref mut process) => {
+ Ok(ref mut process) => {
for input in input.iter() {
- process.input().write(input.as_bytes());
+ process.input().write(input.as_bytes()).unwrap();
}
let run::ProcessOutput { status, output, error } = process.finish_with_output();
@@ -70,7 +70,7 @@ pub fn run(lib_path: &str,
err: str::from_utf8_owned(error).unwrap()
})
},
- None => None
+ Err(..) => None
}
}
@@ -90,13 +90,13 @@ pub fn run_background(lib_path: &str,
});
match opt_process {
- Some(mut process) => {
+ Ok(mut process) => {
for input in input.iter() {
- process.input().write(input.as_bytes());
+ process.input().write(input.as_bytes()).unwrap();
}
Some(process)
},
- None => None
+ Err(..) => None
}
}
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index c57d2492d459c..0503790ae943c 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -153,7 +153,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).unwrap();
let mut srcs = ~[src];
@@ -175,7 +175,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).unwrap()
}
None => { srcs[srcs.len() - 2u].clone() }
@@ -318,8 +318,10 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
//waiting 1 second for gdbserver start
timer::sleep(1000);
let result = task::try(proc() {
- tcp::TcpStream::connect(
- SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 5039 });
+ tcp::TcpStream::connect(SocketAddr {
+ ip: Ipv4Addr(127, 0, 0, 1),
+ port: 5039,
+ }).unwrap();
});
if result.is_err() {
continue;
@@ -361,7 +363,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
stdout: out,
stderr: err,
cmdline: cmdline};
- process.force_destroy();
+ process.force_destroy().unwrap();
}
_=> {
@@ -727,7 +729,7 @@ fn compose_and_run_compiler(
fn ensure_dir(path: &Path) {
if path.is_dir() { return; }
- fs::mkdir(path, io::UserRWX);
+ fs::mkdir(path, io::UserRWX).unwrap();
}
fn compose_and_run(config: &config, testfile: &Path,
@@ -852,7 +854,7 @@ fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) {
fn dump_output_file(config: &config, testfile: &Path,
out: &str, extension: &str) {
let outfile = make_out_name(config, testfile, extension);
- File::create(&outfile).write(out.as_bytes());
+ File::create(&outfile).write(out.as_bytes()).unwrap();
}
fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
@@ -1003,7 +1005,7 @@ fn _arm_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
@@ -1099,7 +1101,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).unwrap();
x.lines().len()
}
diff --git a/src/doc/guide-conditions.md b/src/doc/guide-conditions.md
index d97de7799024c..5b7494c061879 100644
--- a/src/doc/guide-conditions.md
+++ b/src/doc/guide-conditions.md
@@ -47,7 +47,7 @@ An example program that does this task reads like this:
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -55,7 +55,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -71,7 +71,6 @@ fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
// Path takes a generic by-value, rather than by reference
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -245,7 +244,7 @@ and trapping its exit status using `task::try`:
use std::io::{BufferedReader, File};
use std::task;
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -253,7 +252,7 @@ use std::task;
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -277,7 +276,6 @@ fn main() {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -347,7 +345,7 @@ but similarly clear as the version that used `fail!` in the logic where the erro
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -355,7 +353,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -374,7 +372,6 @@ fn main() {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -415,7 +412,7 @@ and replaces bad input lines with the pair `(-1,-1)`:
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -423,7 +420,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -447,7 +444,6 @@ fn main() {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -489,7 +485,7 @@ Changing the condition's return type from `(int,int)` to `Option<(int,int)>` wil
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{IoResult, File};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -497,7 +493,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -522,7 +518,6 @@ fn main() {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -573,7 +568,7 @@ This can be encoded in the handler API by introducing a helper type: `enum Malfo
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -581,7 +576,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -615,7 +610,6 @@ fn main() {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
@@ -696,7 +690,7 @@ a second condition and a helper function will suffice:
# #[allow(unused_imports)];
use std::io::{BufferedReader, File};
# mod BufferedReader {
-# use std::io::File;
+# use std::io::{File, IoResult};
# use std::io::MemReader;
# use std::io::BufferedReader;
# static s : &'static [u8] = bytes!("1 2\n\
@@ -704,7 +698,7 @@ use std::io::{BufferedReader, File};
# 789 123\n\
# 45 67\n\
# ");
-# pub fn new(_inner: Option) -> BufferedReader {
+# pub fn new(_inner: IoResult) -> BufferedReader {
# BufferedReader::new(MemReader::new(s.to_owned()))
# }
# }
@@ -752,7 +746,6 @@ fn parse_int(x: &str) -> int {
fn read_int_pairs() -> ~[(int,int)] {
let mut pairs = ~[];
-# let _g = std::io::ignore_io_error();
let path = Path::new(&"foo.txt");
let mut reader = BufferedReader::new(File::open(&path));
diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py
index e87187abbcbf4..457c0b683ac68 100755
--- a/src/etc/combine-tests.py
+++ b/src/etc/combine-tests.py
@@ -69,6 +69,7 @@ def scrub(b):
use run_pass_stage2::*;
use std::io;
use std::io::Writer;
+#[allow(warnings)]
fn main() {
let mut out = io::stdout();
"""
diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs
index 43366d2aa6d84..9615bdc2ad731 100644
--- a/src/libextra/arc.rs
+++ b/src/libextra/arc.rs
@@ -637,7 +637,7 @@ mod tests {
fn test_mutex_arc_poison() {
let arc = ~MutexArc::new(1);
let arc2 = ~arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.access(|one| {
assert_eq!(*one, 2);
})
@@ -668,7 +668,7 @@ mod tests {
fn test_mutex_arc_access_in_unwind() {
let arc = MutexArc::new(1i);
let arc2 = arc.clone();
- task::try::<()>(proc() {
+ let _ = task::try::<()>(proc() {
struct Unwinder {
i: MutexArc
}
@@ -687,7 +687,7 @@ mod tests {
fn test_rw_arc_poison_wr() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.write(|one| {
assert_eq!(*one, 2);
})
@@ -701,7 +701,7 @@ mod tests {
fn test_rw_arc_poison_ww() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.write(|one| {
assert_eq!(*one, 2);
})
@@ -714,7 +714,7 @@ mod tests {
fn test_rw_arc_poison_dw() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.write_downgrade(|mut write_mode| {
write_mode.write(|one| {
assert_eq!(*one, 2);
@@ -729,7 +729,7 @@ mod tests {
fn test_rw_arc_no_poison_rr() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.read(|one| {
assert_eq!(*one, 2);
})
@@ -742,7 +742,7 @@ mod tests {
fn test_rw_arc_no_poison_rw() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.read(|one| {
assert_eq!(*one, 2);
})
@@ -755,7 +755,7 @@ mod tests {
fn test_rw_arc_no_poison_dr() {
let arc = RWArc::new(1);
let arc2 = arc.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
arc2.write_downgrade(|write_mode| {
let read_mode = arc2.downgrade(write_mode);
read_mode.read(|one| {
@@ -800,7 +800,7 @@ mod tests {
// Wait for children to pass their asserts
for r in children.mut_iter() {
- r.recv();
+ let _ = r.recv();
}
// Wait for writer to finish
@@ -814,7 +814,7 @@ mod tests {
fn test_rw_arc_access_in_unwind() {
let arc = RWArc::new(1i);
let arc2 = arc.clone();
- task::try::<()>(proc() {
+ let _ = task::try::<()>(proc() {
struct Unwinder {
i: RWArc
}
diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs
index 738afcd5c5f93..556032af1ac84 100644
--- a/src/libextra/base64.rs
+++ b/src/libextra/base64.rs
@@ -359,7 +359,7 @@ mod test {
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
let b = s.as_bytes().to_base64(STANDARD);
bh.iter(|| {
- b.from_base64();
+ b.from_base64().unwrap();
});
bh.bytes = b.len() as u64;
}
diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs
index 5bbea491ac208..1900313ab6c8e 100644
--- a/src/libextra/ebml.rs
+++ b/src/libextra/ebml.rs
@@ -12,6 +12,10 @@
use std::str;
+macro_rules! if_ok( ($e:expr) => (
+ match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } }
+) )
+
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
// cursor model. See the specification here:
// http://www.matroska.org/technical/specs/rfc/index.html
@@ -595,9 +599,15 @@ pub mod writer {
// ebml writing
pub struct Encoder<'a> {
- // FIXME(#5665): this should take a trait object
+ // FIXME(#5665): this should take a trait object. Note that if you
+ // delete this comment you should consider removing the
+ // unwrap()'s below of the results of the calls to
+ // write(). We're guaranteed that writing into a MemWriter
+ // won't fail, but this is not true for all I/O streams in
+ // general.
writer: &'a mut MemWriter,
priv size_positions: ~[uint],
+ last_error: io::IoResult<()>,
}
fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
@@ -609,7 +619,7 @@ pub mod writer {
4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
(n >> 8_u) as u8, n as u8]),
_ => fail!("vint to write too big: {}", n)
- };
+ }.unwrap()
}
fn write_vuint(w: &mut MemWriter, n: uint) {
@@ -624,7 +634,8 @@ pub mod writer {
let size_positions: ~[uint] = ~[];
Encoder {
writer: w,
- size_positions: size_positions
+ size_positions: size_positions,
+ last_error: Ok(()),
}
}
@@ -635,6 +646,7 @@ pub mod writer {
Encoder {
writer: cast::transmute_copy(&self.writer),
size_positions: self.size_positions.clone(),
+ last_error: Ok(()),
}
}
@@ -645,18 +657,18 @@ 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(if_ok!(self.writer.tell()) as uint);
let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
- self.writer.write(zeroes);
+ if_ok!(self.writer.write(zeroes));
}
pub fn end_tag(&mut self) {
let last_size_pos = self.size_positions.pop().unwrap();
- let cur_pos = self.writer.tell();
- self.writer.seek(last_size_pos as i64, io::SeekSet);
+ let cur_pos = if_ok!(self.writer.tell());
+ if_ok!(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, 4u);
- self.writer.seek(cur_pos as i64, io::SeekSet);
+ if_ok!(self.writer.seek(cur_pos as i64, io::SeekSet));
debug!("End tag (size = {})", size);
}
@@ -670,7 +682,7 @@ pub mod writer {
pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
write_vuint(self.writer, tag_id);
write_vuint(self.writer, b.len());
- self.writer.write(b);
+ self.writer.write(b).unwrap();
}
pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
@@ -723,12 +735,12 @@ pub mod writer {
pub fn wr_bytes(&mut self, b: &[u8]) {
debug!("Write {} bytes", b.len());
- self.writer.write(b);
+ self.writer.write(b).unwrap();
}
pub fn wr_str(&mut self, s: &str) {
debug!("Write str: {}", s);
- self.writer.write(s.as_bytes());
+ self.writer.write(s.as_bytes()).unwrap();
}
}
diff --git a/src/libextra/hex.rs b/src/libextra/hex.rs
index 4fd59bb3aa503..d4e1ae123378e 100644
--- a/src/libextra/hex.rs
+++ b/src/libextra/hex.rs
@@ -201,7 +201,7 @@ mod tests {
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
let b = s.as_bytes().to_hex();
bh.iter(|| {
- b.from_hex();
+ b.from_hex().unwrap();
});
bh.bytes = b.len() as u64;
}
diff --git a/src/libextra/json.rs b/src/libextra/json.rs
index f8b1c216529b1..ef8e0999521b8 100644
--- a/src/libextra/json.rs
+++ b/src/libextra/json.rs
@@ -234,6 +234,10 @@ use serialize::Encodable;
use serialize;
use treemap::TreeMap;
+macro_rules! if_ok( ($e:expr) => (
+ match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } }
+) )
+
/// Represents a json value
#[deriving(Clone, Eq)]
pub enum Json {
@@ -260,6 +264,14 @@ pub struct Error {
priv msg: ~str,
}
+fn io_error_to_error(io: io::IoError) -> Error {
+ Error {
+ line: 0,
+ col: 0,
+ msg: format!("io error: {}", io)
+ }
+}
+
fn escape_str(s: &str) -> ~str {
let mut escaped = ~"\"";
for c in s.chars() {
@@ -289,13 +301,14 @@ fn spaces(n: uint) -> ~str {
/// A structure for implementing serialization to JSON.
pub struct Encoder<'a> {
priv wr: &'a mut io::Writer,
+ priv error: io::IoResult<()>,
}
impl<'a> Encoder<'a> {
/// Creates a new JSON encoder whose output will be written to the writer
/// specified.
pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
- Encoder { wr: wr }
+ Encoder { wr: wr, error: Ok(()) }
}
/// Encode the specified struct into a json [u8]
@@ -317,7 +330,7 @@ impl<'a> Encoder<'a> {
}
impl<'a> serialize::Encoder for Encoder<'a> {
- fn emit_nil(&mut self) { write!(self.wr, "null") }
+ fn emit_nil(&mut self) { if_ok!(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); }
@@ -333,20 +346,20 @@ impl<'a> serialize::Encoder for Encoder<'a> {
fn emit_bool(&mut self, v: bool) {
if v {
- write!(self.wr, "true");
+ if_ok!(write!(self.wr, "true"));
} else {
- write!(self.wr, "false");
+ if_ok!(write!(self.wr, "false"));
}
}
fn emit_f64(&mut self, v: f64) {
- write!(self.wr, "{}", f64::to_str_digits(v, 6u))
+ if_ok!(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))
+ if_ok!(write!(self.wr, "{}", escape_str(v)))
}
fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) }
@@ -360,19 +373,19 @@ impl<'a> serialize::Encoder for Encoder<'a> {
// Bunny => "Bunny"
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
if cnt == 0 {
- write!(self.wr, "{}", escape_str(name));
+ if_ok!(write!(self.wr, "{}", escape_str(name)));
} else {
- write!(self.wr, "\\{\"variant\":");
- write!(self.wr, "{}", escape_str(name));
- write!(self.wr, ",\"fields\":[");
+ if_ok!(write!(self.wr, "\\{\"variant\":"));
+ if_ok!(write!(self.wr, "{}", escape_str(name)));
+ if_ok!(write!(self.wr, ",\"fields\":["));
f(self);
- write!(self.wr, "]\\}");
+ if_ok!(write!(self.wr, "]\\}"));
}
}
fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
if idx != 0 {
- write!(self.wr, ",");
+ if_ok!(write!(self.wr, ","));
}
f(self);
}
@@ -393,17 +406,17 @@ impl<'a> serialize::Encoder for Encoder<'a> {
}
fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) {
- write!(self.wr, r"\{");
+ if_ok!(write!(self.wr, r"\{"));
f(self);
- write!(self.wr, r"\}");
+ if_ok!(write!(self.wr, r"\}"));
}
fn emit_struct_field(&mut self,
name: &str,
idx: uint,
f: |&mut Encoder<'a>|) {
- if idx != 0 { write!(self.wr, ",") }
- write!(self.wr, "{}:", escape_str(name));
+ if idx != 0 { if_ok!(write!(self.wr, ",")) }
+ if_ok!(write!(self.wr, "{}:", escape_str(name)));
f(self);
}
@@ -429,31 +442,31 @@ impl<'a> serialize::Encoder for Encoder<'a> {
fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); }
fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
- write!(self.wr, "[");
+ if_ok!(write!(self.wr, "["));
f(self);
- write!(self.wr, "]");
+ if_ok!(write!(self.wr, "]"));
}
fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
if idx != 0 {
- write!(self.wr, ",");
+ if_ok!(write!(self.wr, ","));
}
f(self)
}
fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
- write!(self.wr, r"\{");
+ if_ok!(write!(self.wr, r"\{"));
f(self);
- write!(self.wr, r"\}");
+ if_ok!(write!(self.wr, r"\}"));
}
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
- if idx != 0 { write!(self.wr, ",") }
+ if idx != 0 { if_ok!(write!(self.wr, ",")) }
f(self)
}
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
- write!(self.wr, ":");
+ if_ok!(write!(self.wr, ":"));
f(self)
}
}
@@ -463,6 +476,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
pub struct PrettyEncoder<'a> {
priv wr: &'a mut io::Writer,
priv indent: uint,
+ priv error: io::IoResult<()>,
}
impl<'a> PrettyEncoder<'a> {
@@ -471,12 +485,13 @@ impl<'a> PrettyEncoder<'a> {
PrettyEncoder {
wr: wr,
indent: 0,
+ error: Ok(())
}
}
}
impl<'a> serialize::Encoder for PrettyEncoder<'a> {
- fn emit_nil(&mut self) { write!(self.wr, "null") }
+ fn emit_nil(&mut self) { if_ok!(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); }
@@ -492,19 +507,21 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
fn emit_bool(&mut self, v: bool) {
if v {
- write!(self.wr, "true");
+ if_ok!(write!(self.wr, "true"));
} else {
- write!(self.wr, "false");
+ if_ok!(write!(self.wr, "false"));
}
}
fn emit_f64(&mut self, v: f64) {
- write!(self.wr, "{}", f64::to_str_digits(v, 6u))
+ if_ok!(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)); }
+ fn emit_str(&mut self, v: &str) {
+ if_ok!(write!(self.wr, "{}", escape_str(v)));
+ }
fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) {
f(self)
@@ -516,13 +533,14 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
cnt: uint,
f: |&mut PrettyEncoder<'a>|) {
if cnt == 0 {
- write!(self.wr, "{}", escape_str(name));
+ if_ok!(write!(self.wr, "{}", escape_str(name)));
} else {
self.indent += 2;
- write!(self.wr, "[\n{}{},\n", spaces(self.indent), escape_str(name));
+ if_ok!(write!(self.wr, "[\n{}{},\n", spaces(self.indent),
+ escape_str(name)));
f(self);
self.indent -= 2;
- write!(self.wr, "\n{}]", spaces(self.indent));
+ if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
}
}
@@ -530,9 +548,9 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
idx: uint,
f: |&mut PrettyEncoder<'a>|) {
if idx != 0 {
- write!(self.wr, ",\n");
+ if_ok!(write!(self.wr, ",\n"));
}
- write!(self.wr, "{}", spaces(self.indent));
+ if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self)
}
@@ -557,13 +575,13 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
len: uint,
f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
- write!(self.wr, "\\{\\}");
+ if_ok!(write!(self.wr, "\\{\\}"));
} else {
- write!(self.wr, "\\{");
+ if_ok!(write!(self.wr, "\\{"));
self.indent += 2;
f(self);
self.indent -= 2;
- write!(self.wr, "\n{}\\}", spaces(self.indent));
+ if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
}
}
@@ -572,11 +590,11 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
idx: uint,
f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
- write!(self.wr, "\n");
+ if_ok!(write!(self.wr, "\n"));
} else {
- write!(self.wr, ",\n");
+ if_ok!(write!(self.wr, ",\n"));
}
- write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name));
+ if_ok!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name)));
f(self);
}
@@ -605,50 +623,50 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
- write!(self.wr, "[]");
+ if_ok!(write!(self.wr, "[]"));
} else {
- write!(self.wr, "[");
+ if_ok!(write!(self.wr, "["));
self.indent += 2;
f(self);
self.indent -= 2;
- write!(self.wr, "\n{}]", spaces(self.indent));
+ if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
}
}
fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
- write!(self.wr, "\n");
+ if_ok!(write!(self.wr, "\n"));
} else {
- write!(self.wr, ",\n");
+ if_ok!(write!(self.wr, ",\n"));
}
- write!(self.wr, "{}", spaces(self.indent));
+ if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self)
}
fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
- write!(self.wr, "\\{\\}");
+ if_ok!(write!(self.wr, "\\{\\}"));
} else {
- write!(self.wr, "\\{");
+ if_ok!(write!(self.wr, "\\{"));
self.indent += 2;
f(self);
self.indent -= 2;
- write!(self.wr, "\n{}\\}", spaces(self.indent));
+ if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
}
}
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
- write!(self.wr, "\n");
+ if_ok!(write!(self.wr, "\n"));
} else {
- write!(self.wr, ",\n");
+ if_ok!(write!(self.wr, ",\n"));
}
- write!(self.wr, "{}", spaces(self.indent));
+ if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self);
}
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) {
- write!(self.wr, ": ");
+ if_ok!(write!(self.wr, ": "));
f(self);
}
}
@@ -668,22 +686,24 @@ impl serialize::Encodable for Json {
impl Json{
/// Encodes a json value into a io::writer. Uses a single line.
- pub fn to_writer(&self, wr: &mut io::Writer) {
+ pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
let mut encoder = Encoder::new(wr);
- self.encode(&mut encoder)
+ self.encode(&mut encoder);
+ encoder.error
}
/// Encodes a json value into a io::writer.
/// Pretty-prints in a more readable format.
- pub fn to_pretty_writer(&self, wr: &mut io::Writer) {
+ pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
let mut encoder = PrettyEncoder::new(wr);
- self.encode(&mut encoder)
+ self.encode(&mut encoder);
+ encoder.error
}
/// Encodes a json value into a string
pub fn to_pretty_str(&self) -> ~str {
let mut s = MemWriter::new();
- self.to_pretty_writer(&mut s as &mut io::Writer);
+ self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
str::from_utf8_owned(s.unwrap()).unwrap()
}
}
@@ -1067,7 +1087,14 @@ 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_owned(rdr.read_to_end()).unwrap();
+ let contents = match rdr.read_to_end() {
+ Ok(c) => c,
+ Err(e) => return Err(io_error_to_error(e))
+ };
+ let s = match str::from_utf8_owned(contents) {
+ Some(s) => s,
+ None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" })
+ };
let mut parser = Parser::new(s.chars());
parser.parse()
}
@@ -1540,7 +1567,7 @@ impl to_str::ToStr for Json {
/// Encodes a json value into a string
fn to_str(&self) -> ~str {
let mut s = MemWriter::new();
- self.to_writer(&mut s as &mut io::Writer);
+ self.to_writer(&mut s as &mut io::Writer).unwrap();
str::from_utf8_owned(s.unwrap()).unwrap()
}
}
diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs
index e2a4b52c810d2..358dca5e5ac47 100644
--- a/src/libextra/lib.rs
+++ b/src/libextra/lib.rs
@@ -34,6 +34,11 @@ Rust extras are part of the standard Rust distribution.
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
+#[cfg(stage0)]
+macro_rules! if_ok (
+ ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
// Utility modules
pub mod c_vec;
diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs
index 096e588277468..8752020f564e0 100644
--- a/src/libextra/stats.rs
+++ b/src/libextra/stats.rs
@@ -322,14 +322,15 @@ pub fn winsorize(samples: &mut [f64], pct: f64) {
}
/// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`.
-pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
+pub fn write_5_number_summary(w: &mut io::Writer,
+ s: &Summary) -> io::IoResult<()> {
let (q1,q2,q3) = s.quartiles;
write!(w, "(min={}, q1={}, med={}, q3={}, max={})",
s.min,
q1,
q2,
q3,
- s.max);
+ s.max)
}
/// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the
@@ -344,7 +345,8 @@ pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
/// 10 | [--****#******----------] | 40
/// ~~~~
-pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
+pub fn write_boxplot(w: &mut io::Writer, s: &Summary,
+ width_hint: uint) -> io::IoResult<()> {
let (q1,q2,q3) = s.quartiles;
@@ -374,48 +376,49 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
let range_width = width_hint - overhead_width;;
let char_step = range / (range_width as f64);
- write!(w, "{} |", lostr);
+ if_ok!(write!(w, "{} |", lostr));
let mut c = 0;
let mut v = lo;
while c < range_width && v < s.min {
- write!(w, " ");
+ if_ok!(write!(w, " "));
v += char_step;
c += 1;
}
- write!(w, "[");
+ if_ok!(write!(w, "["));
c += 1;
while c < range_width && v < q1 {
- write!(w, "-");
+ if_ok!(write!(w, "-"));
v += char_step;
c += 1;
}
while c < range_width && v < q2 {
- write!(w, "*");
+ if_ok!(write!(w, "*"));
v += char_step;
c += 1;
}
- write!(w, r"\#");
+ if_ok!(write!(w, r"\#"));
c += 1;
while c < range_width && v < q3 {
- write!(w, "*");
+ if_ok!(write!(w, "*"));
v += char_step;
c += 1;
}
while c < range_width && v < s.max {
- write!(w, "-");
+ if_ok!(write!(w, "-"));
v += char_step;
c += 1;
}
- write!(w, "]");
+ if_ok!(write!(w, "]"));
while c < range_width {
- write!(w, " ");
+ if_ok!(write!(w, " "));
v += char_step;
c += 1;
}
- write!(w, "| {}", histr);
+ if_ok!(write!(w, "| {}", histr));
+ Ok(())
}
/// Returns a HashMap with the number of occurrences of every element in the
@@ -453,11 +456,11 @@ mod tests {
let mut w = io::stdout();
let w = &mut w as &mut io::Writer;
- write!(w, "\n");
- write_5_number_summary(w, &summ2);
- write!(w, "\n");
- write_boxplot(w, &summ2, 50);
- write!(w, "\n");
+ (write!(w, "\n")).unwrap();
+ write_5_number_summary(w, &summ2).unwrap();
+ (write!(w, "\n")).unwrap();
+ write_boxplot(w, &summ2, 50).unwrap();
+ (write!(w, "\n")).unwrap();
assert_eq!(summ.sum, summ2.sum);
assert_eq!(summ.min, summ2.min);
@@ -1000,7 +1003,7 @@ mod tests {
fn t(s: &Summary, expected: ~str) {
use std::io::MemWriter;
let mut m = MemWriter::new();
- write_boxplot(&mut m as &mut io::Writer, s, 30);
+ write_boxplot(&mut m as &mut io::Writer, s, 30).unwrap();
let out = str::from_utf8_owned(m.unwrap()).unwrap();
assert_eq!(out, expected);
}
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index 26a555a646c58..0a29fd1898229 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -959,7 +959,7 @@ mod tests {
fn test_mutex_cond_no_waiter() {
let m = Mutex::new();
let m2 = m.clone();
- task::try(proc() {
+ let _ = task::try(proc() {
m.lock_cond(|_x| { })
});
m2.lock_cond(|cond| {
diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs
index c9ea556f23a50..5948f356a651d 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) })
}
@@ -73,7 +73,8 @@ impl Drop for TempDir {
fn drop(&mut self) {
for path in self.path.iter() {
if path.exists() {
- fs::rmdir_recursive(path);
+ // FIXME: is failing the right thing to do?
+ fs::rmdir_recursive(path).unwrap();
}
}
}
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index ef5a05b6a3e51..c4d27b25b5503 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -163,7 +163,11 @@ pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
Some(Err(msg)) => fail!("{}", msg),
None => return
};
- if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
+ match run_tests_console(&opts, tests) {
+ Ok(true) => {}
+ Ok(false) => fail!("Some tests failed"),
+ Err(e) => fail!("io error when running tests: {}", e),
+ }
}
// A variant optimized for invocation with a static test vector.
@@ -359,16 +363,17 @@ struct ConsoleTestState {
}
impl ConsoleTestState {
- pub fn new(opts: &TestOpts, _: Option) -> ConsoleTestState {
+ pub fn new(opts: &TestOpts,
+ _: Option) -> io::IoResult> {
let log_out = match opts.logfile {
- Some(ref path) => File::create(path),
+ Some(ref path) => Some(if_ok!(File::create(path))),
None => None
};
let out = match term::Terminal::new(io::stdout()) {
Err(_) => Raw(io::stdout()),
Ok(t) => Pretty(t)
};
- ConsoleTestState {
+ Ok(ConsoleTestState {
out: out,
log_out: log_out,
use_color: use_color(),
@@ -380,100 +385,103 @@ impl ConsoleTestState {
metrics: MetricMap::new(),
failures: ~[],
max_name_len: 0u,
- }
+ })
}
- pub fn write_ok(&mut self) {
- self.write_pretty("ok", term::color::GREEN);
+ pub fn write_ok(&mut self) -> io::IoResult<()> {
+ self.write_pretty("ok", term::color::GREEN)
}
- pub fn write_failed(&mut self) {
- self.write_pretty("FAILED", term::color::RED);
+ pub fn write_failed(&mut self) -> io::IoResult<()> {
+ self.write_pretty("FAILED", term::color::RED)
}
- pub fn write_ignored(&mut self) {
- self.write_pretty("ignored", term::color::YELLOW);
+ pub fn write_ignored(&mut self) -> io::IoResult<()> {
+ self.write_pretty("ignored", term::color::YELLOW)
}
- pub fn write_metric(&mut self) {
- self.write_pretty("metric", term::color::CYAN);
+ pub fn write_metric(&mut self) -> io::IoResult<()> {
+ self.write_pretty("metric", term::color::CYAN)
}
- pub fn write_bench(&mut self) {
- self.write_pretty("bench", term::color::CYAN);
+ pub fn write_bench(&mut self) -> io::IoResult<()> {
+ self.write_pretty("bench", term::color::CYAN)
}
- pub fn write_added(&mut self) {
- self.write_pretty("added", term::color::GREEN);
+ pub fn write_added(&mut self) -> io::IoResult<()> {
+ self.write_pretty("added", term::color::GREEN)
}
- pub fn write_improved(&mut self) {
- self.write_pretty("improved", term::color::GREEN);
+ pub fn write_improved(&mut self) -> io::IoResult<()> {
+ self.write_pretty("improved", term::color::GREEN)
}
- pub fn write_removed(&mut self) {
- self.write_pretty("removed", term::color::YELLOW);
+ pub fn write_removed(&mut self) -> io::IoResult<()> {
+ self.write_pretty("removed", term::color::YELLOW)
}
- pub fn write_regressed(&mut self) {
- self.write_pretty("regressed", term::color::RED);
+ pub fn write_regressed(&mut self) -> io::IoResult<()> {
+ self.write_pretty("regressed", term::color::RED)
}
pub fn write_pretty(&mut self,
word: &str,
- color: term::color::Color) {
+ color: term::color::Color) -> io::IoResult<()> {
match self.out {
Pretty(ref mut term) => {
if self.use_color {
- term.fg(color);
+ if_ok!(term.fg(color));
}
- term.write(word.as_bytes());
+ if_ok!(term.write(word.as_bytes()));
if self.use_color {
- term.reset();
+ if_ok!(term.reset());
}
+ Ok(())
}
Raw(ref mut stdout) => stdout.write(word.as_bytes())
}
}
- pub fn write_plain(&mut self, s: &str) {
+ pub fn write_plain(&mut self, s: &str) -> io::IoResult<()> {
match self.out {
Pretty(ref mut term) => term.write(s.as_bytes()),
Raw(ref mut stdout) => stdout.write(s.as_bytes())
}
}
- pub fn write_run_start(&mut self, len: uint) {
+ pub fn write_run_start(&mut self, len: uint) -> io::IoResult<()> {
self.total = len;
let noun = if len != 1 { &"tests" } else { &"test" };
- self.write_plain(format!("\nrunning {} {}\n", len, noun));
+ self.write_plain(format!("\nrunning {} {}\n", len, noun))
}
- pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) {
+ pub fn write_test_start(&mut self, test: &TestDesc,
+ align: NamePadding) -> io::IoResult<()> {
let name = test.padded_name(self.max_name_len, align);
- self.write_plain(format!("test {} ... ", name));
+ self.write_plain(format!("test {} ... ", name))
}
- pub fn write_result(&mut self, result: &TestResult) {
- match *result {
+ pub fn write_result(&mut self, result: &TestResult) -> io::IoResult<()> {
+ if_ok!(match *result {
TrOk => self.write_ok(),
TrFailed => self.write_failed(),
TrIgnored => self.write_ignored(),
TrMetrics(ref mm) => {
- self.write_metric();
- self.write_plain(format!(": {}", fmt_metrics(mm)));
+ if_ok!(self.write_metric());
+ self.write_plain(format!(": {}", fmt_metrics(mm)))
}
TrBench(ref bs) => {
- self.write_bench();
- self.write_plain(format!(": {}", fmt_bench_samples(bs)));
+ if_ok!(self.write_bench());
+ self.write_plain(format!(": {}", fmt_bench_samples(bs)))
}
- }
- self.write_plain("\n");
+ });
+ self.write_plain("\n")
}
- pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) {
+ pub fn write_log(&mut self, test: &TestDesc,
+ result: &TestResult) -> io::IoResult<()> {
match self.log_out {
- None => (),
+ None => Ok(()),
Some(ref mut o) => {
let s = format!("{} {}\n", match *result {
TrOk => ~"ok",
@@ -482,24 +490,25 @@ impl ConsoleTestState {
TrMetrics(ref mm) => fmt_metrics(mm),
TrBench(ref bs) => fmt_bench_samples(bs)
}, test.name.to_str());
- o.write(s.as_bytes());
+ o.write(s.as_bytes())
}
}
}
- pub fn write_failures(&mut self) {
- self.write_plain("\nfailures:\n");
+ pub fn write_failures(&mut self) -> io::IoResult<()> {
+ if_ok!(self.write_plain("\nfailures:\n"));
let mut failures = ~[];
for f in self.failures.iter() {
failures.push(f.name.to_str());
}
failures.sort();
for name in failures.iter() {
- self.write_plain(format!(" {}\n", name.to_str()));
+ if_ok!(self.write_plain(format!(" {}\n", name.to_str())));
}
+ Ok(())
}
- pub fn write_metric_diff(&mut self, diff: &MetricDiff) {
+ pub fn write_metric_diff(&mut self, diff: &MetricDiff) -> io::IoResult<()> {
let mut noise = 0;
let mut improved = 0;
let mut regressed = 0;
@@ -511,77 +520,82 @@ impl ConsoleTestState {
LikelyNoise => noise += 1,
MetricAdded => {
added += 1;
- self.write_added();
- self.write_plain(format!(": {}\n", *k));
+ if_ok!(self.write_added());
+ if_ok!(self.write_plain(format!(": {}\n", *k)));
}
MetricRemoved => {
removed += 1;
- self.write_removed();
- self.write_plain(format!(": {}\n", *k));
+ if_ok!(self.write_removed());
+ if_ok!(self.write_plain(format!(": {}\n", *k)));
}
Improvement(pct) => {
improved += 1;
- self.write_plain(format!(": {}", *k));
- self.write_improved();
- self.write_plain(format!(" by {:.2f}%\n", pct as f64));
+ if_ok!(self.write_plain(format!(": {}", *k)));
+ if_ok!(self.write_improved());
+ if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
}
Regression(pct) => {
regressed += 1;
- self.write_plain(format!(": {}", *k));
- self.write_regressed();
- self.write_plain(format!(" by {:.2f}%\n", pct as f64));
+ if_ok!(self.write_plain(format!(": {}", *k)));
+ if_ok!(self.write_regressed());
+ if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
}
}
}
- self.write_plain(format!("result of ratchet: {} matrics added, {} removed, \
- {} improved, {} regressed, {} noise\n",
- added, removed, improved, regressed, noise));
+ if_ok!(self.write_plain(format!("result of ratchet: {} matrics added, \
+ {} removed, {} improved, {} regressed, \
+ {} noise\n",
+ added, removed, improved, regressed,
+ noise)));
if regressed == 0 {
- self.write_plain("updated ratchet file\n");
+ if_ok!(self.write_plain("updated ratchet file\n"));
} else {
- self.write_plain("left ratchet file untouched\n");
+ if_ok!(self.write_plain("left ratchet file untouched\n"));
}
+ Ok(())
}
pub fn write_run_finish(&mut self,
ratchet_metrics: &Option,
- ratchet_pct: Option) -> bool {
+ ratchet_pct: Option) -> io::IoResult {
assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
let ratchet_success = match *ratchet_metrics {
None => true,
Some(ref pth) => {
- self.write_plain(format!("\nusing metrics ratcher: {}\n", pth.display()));
+ if_ok!(self.write_plain(format!("\nusing metrics ratcher: {}\n",
+ pth.display())));
match ratchet_pct {
None => (),
Some(pct) =>
- self.write_plain(format!("with noise-tolerance forced to: {}%\n",
- pct))
+ if_ok!(self.write_plain(format!("with noise-tolerance \
+ forced to: {}%\n",
+ pct)))
}
let (diff, ok) = self.metrics.ratchet(pth, ratchet_pct);
- self.write_metric_diff(&diff);
+ if_ok!(self.write_metric_diff(&diff));
ok
}
};
let test_success = self.failed == 0u;
if !test_success {
- self.write_failures();
+ if_ok!(self.write_failures());
}
let success = ratchet_success && test_success;
- self.write_plain("\ntest result: ");
+ if_ok!(self.write_plain("\ntest result: "));
if success {
// There's no parallelism at this point so it's safe to use color
- self.write_ok();
+ if_ok!(self.write_ok());
} else {
- self.write_failed();
+ if_ok!(self.write_failed());
}
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
self.passed, self.failed, self.ignored, self.measured);
- self.write_plain(s);
- return success;
+ if_ok!(self.write_plain(s));
+ return Ok(success);
}
}
@@ -611,15 +625,16 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> ~str {
// A simple console test runner
pub fn run_tests_console(opts: &TestOpts,
- tests: ~[TestDescAndFn]) -> bool {
- fn callback(event: &TestEvent, st: &mut ConsoleTestState) {
+ tests: ~[TestDescAndFn]) -> io::IoResult {
+ fn callback(event: &TestEvent,
+ st: &mut ConsoleTestState) -> io::IoResult<()> {
debug!("callback(event={:?})", event);
match (*event).clone() {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeWait(ref test, padding) => st.write_test_start(test, padding),
TeResult(test, result) => {
- st.write_log(&test, &result);
- st.write_result(&result);
+ if_ok!(st.write_log(&test, &result));
+ if_ok!(st.write_result(&result));
match result {
TrOk => st.passed += 1,
TrIgnored => st.ignored += 1,
@@ -643,10 +658,11 @@ pub fn run_tests_console(opts: &TestOpts,
st.failures.push(test);
}
}
+ Ok(())
}
}
}
- let mut st = ConsoleTestState::new(opts, None::);
+ let mut st = if_ok!(ConsoleTestState::new(opts, None::));
fn len_if_padded(t: &TestDescAndFn) -> uint {
match t.testfn.padding() {
PadNone => 0u,
@@ -661,12 +677,13 @@ pub fn run_tests_console(opts: &TestOpts,
},
None => {}
}
- run_tests(opts, tests, |x| callback(&x, &mut st));
+ if_ok!(run_tests(opts, tests, |x| callback(&x, &mut st)));
match opts.save_metrics {
None => (),
Some(ref pth) => {
- st.metrics.save(pth);
- st.write_plain(format!("\nmetrics saved to: {}", pth.display()));
+ if_ok!(st.metrics.save(pth));
+ if_ok!(st.write_plain(format!("\nmetrics saved to: {}",
+ pth.display())));
}
}
return st.write_run_finish(&opts.ratchet_metrics, opts.ratchet_noise_percent);
@@ -703,7 +720,7 @@ fn should_sort_failures_before_printing_them() {
failures: ~[test_b, test_a]
};
- st.write_failures();
+ st.write_failures().unwrap();
let s = match st.out {
Raw(ref m) => str::from_utf8(m.get_ref()).unwrap(),
Pretty(_) => unreachable!()
@@ -728,11 +745,11 @@ pub type MonitorMsg = (TestDesc, TestResult);
fn run_tests(opts: &TestOpts,
tests: ~[TestDescAndFn],
- callback: |e: TestEvent|) {
+ callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> {
let filtered_tests = filter_tests(opts, tests);
let filtered_descs = filtered_tests.map(|t| t.desc.clone());
- callback(TeFiltered(filtered_descs));
+ if_ok!(callback(TeFiltered(filtered_descs)));
let (filtered_tests, filtered_benchs_and_metrics) =
filtered_tests.partition(|e| {
@@ -760,7 +777,7 @@ fn run_tests(opts: &TestOpts,
// We are doing one test at a time so we can print the name
// of the test before we run it. Useful for debugging tests
// that hang forever.
- callback(TeWait(test.desc.clone(), test.testfn.padding()));
+ if_ok!(callback(TeWait(test.desc.clone(), test.testfn.padding())));
}
run_test(!opts.run_tests, test, ch.clone());
pending += 1;
@@ -768,20 +785,21 @@ fn run_tests(opts: &TestOpts,
let (desc, result) = p.recv();
if concurrency != 1 {
- callback(TeWait(desc.clone(), PadNone));
+ if_ok!(callback(TeWait(desc.clone(), PadNone)));
}
- callback(TeResult(desc, result));
+ if_ok!(callback(TeResult(desc, result)));
pending -= 1;
}
// All benchmarks run at the end, in serial.
// (this includes metric fns)
for b in filtered_benchs_and_metrics.move_iter() {
- callback(TeWait(b.desc.clone(), b.testfn.padding()));
+ if_ok!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
run_test(!opts.run_benchmarks, b, ch.clone());
let (test, result) = p.recv();
- callback(TeResult(test, result));
+ if_ok!(callback(TeResult(test, result)));
}
+ Ok(())
}
fn get_concurrency() -> uint {
@@ -943,17 +961,22 @@ impl MetricMap {
}
/// Load MetricDiff from a file.
+ ///
+ /// # Failure
+ ///
+ /// This function will fail if the path does not exist or the path does not
+ /// contain a valid metric map.
pub fn load(p: &Path) -> MetricMap {
assert!(p.exists());
- let mut f = File::open(p);
+ let mut f = File::open(p).unwrap();
let value = json::from_reader(&mut f as &mut io::Reader).unwrap();
let mut decoder = json::Decoder::new(value);
MetricMap(Decodable::decode(&mut decoder))
}
/// Write MetricDiff to a file.
- pub fn save(&self, p: &Path) {
- let mut file = File::create(p);
+ pub fn save(&self, p: &Path) -> io::IoResult<()> {
+ let mut file = if_ok!(File::create(p));
let MetricMap(ref map) = *self;
map.to_json().to_pretty_writer(&mut file)
}
@@ -1060,7 +1083,7 @@ impl MetricMap {
if ok {
debug!("rewriting file '{:?}' with updated metrics", p);
- self.save(p);
+ self.save(p).unwrap();
}
return (diff, ok)
}
@@ -1462,7 +1485,7 @@ mod tests {
m2.insert_metric("runtime", 1100.0, 2.0);
m2.insert_metric("throughput", 50.0, 2.0);
- m1.save(&pth);
+ m1.save(&pth).unwrap();
// Ask for a ratchet that should fail to advance.
let (diff1, ok1) = m2.ratchet(&pth, None);
diff --git a/src/libextra/time.rs b/src/libextra/time.rs
index 3e5b9b797d31b..0a122ad58bd33 100644
--- a/src/libextra/time.rs
+++ b/src/libextra/time.rs
@@ -766,14 +766,14 @@ pub fn strptime(s: &str, format: &str) -> Result {
let mut buf = [0];
let c = match rdr.read(buf) {
- Some(..) => buf[0] as char,
- None => break
+ Ok(..) => buf[0] as char,
+ Err(..) => break
};
match c {
'%' => {
let ch = match rdr.read(buf) {
- Some(..) => buf[0] as char,
- None => break
+ Ok(..) => buf[0] as char,
+ Err(..) => break
};
match parse_type(s, pos, ch, &mut tm) {
Ok(next) => pos = next,
@@ -787,7 +787,7 @@ pub fn strptime(s: &str, format: &str) -> Result {
}
}
- if pos == len && rdr.tell() as uint == format.len() {
+ if pos == len && rdr.tell().unwrap() == format.len() as u64 {
Ok(Tm {
tm_sec: tm.tm_sec,
tm_min: tm.tm_min,
@@ -1017,12 +1017,12 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str {
loop {
let mut b = [0];
let ch = match rdr.read(b) {
- Some(..) => b[0],
- None => break,
+ Ok(..) => b[0],
+ Err(..) => break,
};
match ch as char {
'%' => {
- rdr.read(b);
+ rdr.read(b).unwrap();
let s = parse_type(b[0] as char, tm);
buf.push_all(s.as_bytes());
}
diff --git a/src/libextra/url.rs b/src/libextra/url.rs
index 35c53c9307c49..6138c5416f2b4 100644
--- a/src/libextra/url.rs
+++ b/src/libextra/url.rs
@@ -102,8 +102,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 {
@@ -166,14 +166,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!() // FIXME: malformed url?
}
let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
@@ -228,8 +228,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' | '_' | '.' | '-' => {
@@ -282,8 +282,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 {
'&' | ';' => {
@@ -307,7 +307,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!() // FIXME: malformed?
}
uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
@@ -347,12 +347,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/uuid.rs b/src/libextra/uuid.rs
index 9163a89203913..29d3066b2f590 100644
--- a/src/libextra/uuid.rs
+++ b/src/libextra/uuid.rs
@@ -821,7 +821,7 @@ mod bench {
pub fn parse_str(bh: &mut BenchHarness) {
let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
bh.iter(|| {
- Uuid::parse_string(s);
+ Uuid::parse_string(s).unwrap();
})
}
}
diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs
index 70bbe02d32f17..4d8e7e50dcfd5 100644
--- a/src/libextra/workcache.rs
+++ b/src/libextra/workcache.rs
@@ -172,20 +172,19 @@ impl Database {
}
// FIXME #4330: This should have &mut self and should set self.db_dirty to false.
- fn save(&self) {
+ fn save(&self) -> io::IoResult<()> {
let mut f = File::create(&self.db_filename);
- self.db_cache.to_json().to_pretty_writer(&mut f);
+ self.db_cache.to_json().to_pretty_writer(&mut f)
}
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) => {
- let mut stream = r.unwrap();
+ e),
+ Ok(mut stream) => {
match json::from_reader(&mut stream) {
Err(e) => fail!("Couldn't parse workcache database (from file {}): {}",
self.db_filename.display(), e.to_str()),
@@ -203,7 +202,8 @@ impl Database {
impl Drop for Database {
fn drop(&mut self) {
if self.db_dirty {
- self.save();
+ // FIXME: is failing the right thing to do here
+ self.save().unwrap();
}
}
}
@@ -473,13 +473,13 @@ fn test() {
fn make_path(filename: ~str) -> Path {
let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename);
if pth.exists() {
- fs::unlink(&pth);
+ fs::unlink(&pth).unwrap();
}
return pth;
}
let pth = make_path(~"foo.c");
- File::create(&pth).write(bytes!("int main() { return 0; }"));
+ File::create(&pth).write(bytes!("int main() { return 0; }")).unwrap();
let db_path = make_path(~"db.json");
@@ -491,7 +491,8 @@ fn test() {
let subcx = cx.clone();
let pth = pth.clone();
- let file_content = from_utf8_owned(File::open(&pth).read_to_end()).unwrap();
+ let contents = File::open(&pth).read_to_end().unwrap();
+ let file_content = from_utf8_owned(contents).unwrap();
// FIXME (#9639): This needs to handle non-utf8 paths
prep.declare_input("file", pth.as_str().unwrap(), file_content);
@@ -500,7 +501,7 @@ fn test() {
// FIXME (#9639): This needs to handle non-utf8 paths
run::process_status("gcc", [pth.as_str().unwrap().to_owned(),
~"-o",
- out.as_str().unwrap().to_owned()]);
+ out.as_str().unwrap().to_owned()]).unwrap();
let _proof_of_concept = subcx.prep("subfn");
// Could run sub-rules inside here.
diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs
index 98bf5533210ee..c6ecb7697da4e 100644
--- a/src/libglob/lib.rs
+++ b/src/libglob/lib.rs
@@ -29,7 +29,6 @@
#[license = "MIT/ASL2"];
use std::{os, path};
-use std::io;
use std::io::fs;
use std::path::is_sep;
@@ -153,7 +152,7 @@ impl Iterator for Paths {
}
fn list_dir_sorted(path: &Path) -> ~[Path] {
- match io::result(|| fs::readdir(path)) {
+ match fs::readdir(path) {
Ok(mut children) => {
children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
children
diff --git a/src/libgreen/macros.rs b/src/libgreen/macros.rs
index e07cc1ca00088..ef2c77fc8e25f 100644
--- a/src/libgreen/macros.rs
+++ b/src/libgreen/macros.rs
@@ -56,16 +56,17 @@ pub fn dumb_println(args: &fmt::Arguments) {
struct Stderr;
impl io::Writer for Stderr {
- fn write(&mut self, data: &[u8]) {
+ fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
unsafe {
libc::write(libc::STDERR_FILENO,
data.as_ptr() as *libc::c_void,
data.len() as libc::size_t);
}
+ Ok(()) // just ignore the result
}
}
let mut w = Stderr;
- fmt::writeln(&mut w as &mut io::Writer, args);
+ let _ = fmt::writeln(&mut w as &mut io::Writer, args);
}
pub fn abort(msg: &str) -> ! {
diff --git a/src/libnative/bookkeeping.rs b/src/libnative/bookkeeping.rs
index b07e4271ee448..868586b36911e 100644
--- a/src/libnative/bookkeeping.rs
+++ b/src/libnative/bookkeeping.rs
@@ -23,7 +23,7 @@ static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut TASK_LOCK: Mutex = MUTEX_INIT;
pub fn increment() {
- unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst); }
+ let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) };
}
pub fn decrement() {
diff --git a/src/libnative/io/file.rs b/src/libnative/io/file.rs
index acab7ce3a91b4..cc5b0770d4d20 100644
--- a/src/libnative/io/file.rs
+++ b/src/libnative/io/file.rs
@@ -111,17 +111,14 @@ impl FileDesc {
}
impl io::Reader for FileDesc {
- fn read(&mut self, buf: &mut [u8]) -> Option {
- match self.inner_read(buf) { Ok(n) => Some(n), Err(..) => None }
+ fn read(&mut self, buf: &mut [u8]) -> io::IoResult {
+ self.inner_read(buf)
}
}
impl io::Writer for FileDesc {
- fn write(&mut self, buf: &[u8]) {
- match self.inner_write(buf) {
- Ok(()) => {}
- Err(e) => { io::io_error::cond.raise(e); }
- }
+ fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
+ self.inner_write(buf)
}
}
@@ -425,7 +422,7 @@ impl rtio::RtioFileStream for CFile {
impl Drop for CFile {
fn drop(&mut self) {
- unsafe { libc::fclose(self.file); }
+ unsafe { let _ = libc::fclose(self.file); }
}
}
@@ -515,7 +512,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
paths.push(Path::new(cstr));
entry_ptr = readdir(dir_ptr);
}
- closedir(dir_ptr);
+ assert_eq!(closedir(dir_ptr), 0);
Ok(paths)
} else {
Err(super::last_error())
@@ -564,7 +561,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
}
more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
}
- FindClose(find_handle);
+ assert!(FindClose(find_handle) != 0);
free(wfd_ptr as *mut c_void);
Ok(paths)
} else {
@@ -686,7 +683,9 @@ pub fn readlink(p: &CString) -> IoResult {
ptr::mut_null())
})
};
- if handle == ptr::mut_null() { return Err(super::last_error()) }
+ if handle as int == libc::INVALID_HANDLE_VALUE as int {
+ return Err(super::last_error())
+ }
let ret = fill_utf16_buf_and_decode(|buf, sz| {
unsafe {
libc::GetFinalPathNameByHandleW(handle, buf as *u16, sz,
@@ -697,7 +696,7 @@ pub fn readlink(p: &CString) -> IoResult {
Some(s) => Ok(Path::new(s)),
None => Err(super::last_error()),
};
- unsafe { libc::CloseHandle(handle) };
+ assert!(unsafe { libc::CloseHandle(handle) } != 0);
return ret;
}
@@ -935,7 +934,7 @@ mod tests {
let mut reader = FileDesc::new(input, true);
let mut writer = FileDesc::new(out, true);
- writer.inner_write(bytes!("test"));
+ writer.inner_write(bytes!("test")).unwrap();
let mut buf = [0u8, ..4];
match reader.inner_read(buf) {
Ok(4) => {
@@ -960,9 +959,9 @@ mod tests {
assert!(!f.is_null());
let mut file = CFile::new(f);
- file.write(bytes!("test"));
+ file.write(bytes!("test")).unwrap();
let mut buf = [0u8, ..4];
- file.seek(0, io::SeekSet);
+ let _ = file.seek(0, io::SeekSet).unwrap();
match file.read(buf) {
Ok(4) => {
assert_eq!(buf[0], 't' as u8);
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index 2f4bec22755f6..ac68b1523d7d9 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -112,8 +112,8 @@ fn setsockopt(fd: sock_t, opt: libc::c_int, val: libc::c_int,
}
}
-#[cfg(windows)] unsafe fn close(sock: sock_t) { libc::closesocket(sock); }
-#[cfg(unix)] unsafe fn close(sock: sock_t) { libc::close(sock); }
+#[cfg(windows)] unsafe fn close(sock: sock_t) { let _ = libc::closesocket(sock); }
+#[cfg(unix)] unsafe fn close(sock: sock_t) { let _ = libc::close(sock); }
fn sockname(fd: sock_t,
f: extern "system" unsafe fn(sock_t, *mut libc::sockaddr,
diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs
index 13dd4298777c6..2a061c5f9b204 100644
--- a/src/libnative/io/process.rs
+++ b/src/libnative/io/process.rs
@@ -102,9 +102,9 @@ impl Process {
cwd.as_ref(), in_fd, out_fd, err_fd);
unsafe {
- for pipe in in_pipe.iter() { libc::close(pipe.input); }
- for pipe in out_pipe.iter() { libc::close(pipe.out); }
- for pipe in err_pipe.iter() { libc::close(pipe.out); }
+ for pipe in in_pipe.iter() { let _ = libc::close(pipe.input); }
+ for pipe in out_pipe.iter() { let _ = libc::close(pipe.out); }
+ for pipe in err_pipe.iter() { let _ = libc::close(pipe.out); }
}
match res {
@@ -149,9 +149,8 @@ impl rtio::RtioProcess for Process {
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
match signal {
io::process::PleaseExitSignal | io::process::MustDieSignal => {
- libc::funcs::extra::kernel32::TerminateProcess(
- cast::transmute(pid), 1);
- Ok(())
+ let ret = libc::TerminateProcess(pid as libc::HANDLE, 1);
+ super::mkerr_winbool(ret)
}
_ => Err(io::IoError {
kind: io::OtherIoError,
@@ -163,8 +162,8 @@ impl rtio::RtioProcess for Process {
#[cfg(not(windows))]
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
- libc::funcs::posix88::signal::kill(pid, signal as c_int);
- Ok(())
+ let r = libc::funcs::posix88::signal::kill(pid, signal as c_int);
+ super::mkerr_libc(r)
}
}
}
@@ -255,9 +254,9 @@ fn spawn_process_os(prog: &str, args: &[~str],
})
});
- CloseHandle(si.hStdInput);
- CloseHandle(si.hStdOutput);
- CloseHandle(si.hStdError);
+ assert!(CloseHandle(si.hStdInput) != 0);
+ assert!(CloseHandle(si.hStdOutput) != 0);
+ assert!(CloseHandle(si.hStdError) != 0);
match create_err {
Some(err) => return Err(err),
@@ -269,7 +268,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
// able to close it later. We don't close the process handle however
// because std::we want the process id to stay valid at least until the
// calling code closes the process handle.
- CloseHandle(pi.hThread);
+ assert!(CloseHandle(pi.hThread) != 0);
Ok(SpawnProcessResult {
pid: pi.dwProcessId as pid_t,
@@ -445,24 +444,24 @@ fn spawn_process_os(prog: &str, args: &[~str],
rustrt::rust_unset_sigprocmask();
if in_fd == -1 {
- libc::close(libc::STDIN_FILENO);
+ let _ = libc::close(libc::STDIN_FILENO);
} else if retry(|| dup2(in_fd, 0)) == -1 {
fail!("failure in dup2(in_fd, 0): {}", os::last_os_error());
}
if out_fd == -1 {
- libc::close(libc::STDOUT_FILENO);
+ let _ = libc::close(libc::STDOUT_FILENO);
} else if retry(|| dup2(out_fd, 1)) == -1 {
fail!("failure in dup2(out_fd, 1): {}", os::last_os_error());
}
if err_fd == -1 {
- libc::close(libc::STDERR_FILENO);
+ let _ = libc::close(libc::STDERR_FILENO);
} else if retry(|| dup2(err_fd, 2)) == -1 {
fail!("failure in dup3(err_fd, 2): {}", os::last_os_error());
}
// close all other fds
for fd in range(3, getdtablesize()).rev() {
if fd != output.fd() {
- close(fd as c_int);
+ let _ = close(fd as c_int);
}
}
@@ -478,7 +477,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
}
});
with_argv(prog, args, |argv| {
- execvp(*argv, argv);
+ let _ = execvp(*argv, argv);
let errno = os::errno();
let bytes = [
(errno << 24) as u8,
@@ -576,9 +575,9 @@ fn with_dirp(d: Option<&Path>, cb: |*libc::c_char| -> T) -> T {
#[cfg(windows)]
fn free_handle(handle: *()) {
- unsafe {
- libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
- }
+ assert!(unsafe {
+ libc::CloseHandle(cast::transmute(handle)) != 0
+ })
}
#[cfg(unix)]
@@ -629,15 +628,15 @@ fn waitpid(pid: pid_t) -> p::ProcessExit {
loop {
let mut status = 0;
if GetExitCodeProcess(process, &mut status) == FALSE {
- CloseHandle(process);
+ assert!(CloseHandle(process) != 0);
fail!("failure in GetExitCodeProcess: {}", os::last_os_error());
}
if status != STILL_ACTIVE {
- CloseHandle(process);
+ assert!(CloseHandle(process) != 0);
return p::ExitStatus(status as int);
}
if WaitForSingleObject(process, INFINITE) == WAIT_FAILED {
- CloseHandle(process);
+ assert!(CloseHandle(process) != 0);
fail!("failure in WaitForSingleObject: {}", os::last_os_error());
}
}
diff --git a/src/libnative/io/timer_helper.rs b/src/libnative/io/timer_helper.rs
index 74759b467d4a7..7311be46e8bd2 100644
--- a/src/libnative/io/timer_helper.rs
+++ b/src/libnative/io/timer_helper.rs
@@ -126,11 +126,11 @@ mod imp {
}
pub fn signal(handle: HANDLE) {
- unsafe { SetEvent(handle); }
+ assert!(unsafe { SetEvent(handle) != 0 });
}
pub fn close(handle: HANDLE) {
- unsafe { CloseHandle(handle); }
+ assert!(unsafe { CloseHandle(handle) != 0 });
}
extern "system" {
diff --git a/src/libnative/io/timer_other.rs b/src/libnative/io/timer_other.rs
index bc005f2fe8dd3..cda239329dcc0 100644
--- a/src/libnative/io/timer_other.rs
+++ b/src/libnative/io/timer_other.rs
@@ -187,7 +187,7 @@ fn helper(input: libc::c_int, messages: Port) {
// drain the file descriptor
let mut buf = [0];
- fd.inner_read(buf).unwrap();
+ assert_eq!(fd.inner_read(buf).unwrap(), 1);
}
-1 if os::errno() == libc::EINTR as int => {}
@@ -216,7 +216,8 @@ impl Timer {
}
pub fn sleep(ms: u64) {
- unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
+ // FIXME: this can fail because of EINTR, what do do?
+ let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
}
fn inner(&mut self) -> ~Inner {
diff --git a/src/libnative/io/timer_timerfd.rs b/src/libnative/io/timer_timerfd.rs
index ca20314997e8c..7c22e90bbffe2 100644
--- a/src/libnative/io/timer_timerfd.rs
+++ b/src/libnative/io/timer_timerfd.rs
@@ -96,7 +96,7 @@ fn helper(input: libc::c_int, messages: Port) {
if fd == input {
let mut buf = [0, ..1];
// drain the input file descriptor of its input
- FileDesc::new(fd, false).inner_read(buf).unwrap();
+ let _ = FileDesc::new(fd, false).inner_read(buf).unwrap();
incoming = true;
} else {
let mut bits = [0, ..8];
@@ -104,7 +104,7 @@ fn helper(input: libc::c_int, messages: Port) {
//
// FIXME: should this perform a send() this number of
// times?
- FileDesc::new(fd, false).inner_read(bits).unwrap();
+ let _ = FileDesc::new(fd, false).inner_read(bits).unwrap();
let remove = {
match map.find(&fd).expect("fd unregistered") {
&(ref c, oneshot) => !c.try_send(()) || oneshot
@@ -166,7 +166,8 @@ impl Timer {
}
pub fn sleep(ms: u64) {
- unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
+ // FIXME: this can fail because of EINTR, what do do?
+ let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
}
fn remove(&mut self) {
diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs
index e359d99eedf65..6b472d2f46d59 100644
--- a/src/libnative/io/timer_win32.rs
+++ b/src/libnative/io/timer_win32.rs
@@ -62,8 +62,8 @@ fn helper(input: libc::HANDLE, messages: Port) {
c.send(());
match objs.iter().position(|&o| o == obj) {
Some(i) => {
- objs.remove(i);
- chans.remove(i - 1);
+ drop(objs.remove(i));
+ drop(chans.remove(i - 1));
}
None => {}
}
@@ -83,8 +83,8 @@ fn helper(input: libc::HANDLE, messages: Port) {
}
};
if remove {
- objs.remove(idx as uint);
- chans.remove(idx as uint - 1);
+ drop(objs.remove(idx as uint));
+ drop(chans.remove(idx as uint - 1));
}
}
}
@@ -133,7 +133,7 @@ impl rtio::RtioTimer for Timer {
ptr::mut_null(), 0)
}, 1);
- unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE); }
+ let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
}
fn oneshot(&mut self, msecs: u64) -> Port<()> {
@@ -173,7 +173,7 @@ impl rtio::RtioTimer for Timer {
impl Drop for Timer {
fn drop(&mut self) {
self.remove();
- unsafe { libc::CloseHandle(self.obj); }
+ assert!(unsafe { libc::CloseHandle(self.obj) != 0 });
}
}
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index f69ad8fc1aa7f..1e4317af39758 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -21,6 +21,7 @@
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://static.rust-lang.org/doc/master")];
+#[deny(unused_result, unused_must_use)];
// NB this crate explicitly does *not* allow glob imports, please seriously
// consider whether they're needed before adding that feature here (the
@@ -61,9 +62,10 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
rt::init(argc, argv);
let mut exit_code = None;
let mut main = Some(main);
- task::new((my_stack_bottom, my_stack_top)).run(|| {
+ let t = task::new((my_stack_bottom, my_stack_top)).run(|| {
exit_code = Some(run(main.take_unwrap()));
});
+ drop(t);
unsafe { rt::cleanup(); }
// If the exit code wasn't set, then the task block must have failed.
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index 3742517970118..0def5cb405338 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -103,7 +103,8 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
let mut f = Some(f);
let mut task = task;
task.put_runtime(ops as ~rt::Runtime);
- task.run(|| { f.take_unwrap()() });
+ let t = task.run(|| { f.take_unwrap()() });
+ drop(t);
bookkeeping::decrement();
})
}
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs
index 661ae5b7297b2..18aef17b9eb77 100644
--- a/src/librustc/back/archive.rs
+++ b/src/librustc/back/archive.rs
@@ -17,6 +17,7 @@ use lib::llvm::{ArchiveRef, llvm};
use std::cast;
use std::io::fs;
+use std::io;
use std::libc;
use std::os;
use std::run::{ProcessOptions, Process, ProcessOutput};
@@ -50,9 +51,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
Some(p) => { debug!("inside {}", p.display()); }
None => {}
}
- let mut opt_prog = Process::new(ar, args.as_slice(), opts);
- match opt_prog {
- Some(ref mut prog) => {
+ match Process::new(ar, args.as_slice(), opts) {
+ Ok(mut prog) => {
let o = prog.finish_with_output();
if !o.status.success() {
sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
@@ -63,8 +63,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
}
o
},
- None => {
- sess.err(format!("could not exec `{}`", ar));
+ Err(e) => {
+ sess.err(format!("could not exec `{}`: {}", ar, e));
sess.abort_if_errors();
fail!("rustc::back::archive::run_ar() should not reach this point");
}
@@ -94,7 +94,7 @@ impl Archive {
let archive = os::make_absolute(&self.dst);
run_ar(self.sess, "x", Some(loc.path()), [&archive,
&Path::new(file)]);
- fs::File::open(&loc.path().join(file)).read_to_end()
+ fs::File::open(&loc.path().join(file)).read_to_end().unwrap()
} else {
run_ar(self.sess, "p", None, [&self.dst, &Path::new(file)]).output
}
@@ -102,9 +102,9 @@ impl Archive {
/// Adds all of the contents of a native library to this archive. This will
/// search in the relevant locations for a library named `name`.
- pub fn add_native_library(&mut self, name: &str) {
+ pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
let location = self.find_library(name);
- self.add_archive(&location, name, []);
+ self.add_archive(&location, name, [])
}
/// Adds all of the contents of the rlib at the specified path to this
@@ -112,14 +112,15 @@ impl Archive {
///
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
/// then the object file also isn't added.
- pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool) {
+ pub fn add_rlib(&mut self, rlib: &Path, name: &str,
+ lto: bool) -> io::IoResult<()> {
let object = format!("{}.o", name);
let bytecode = format!("{}.bc", name);
let mut ignore = ~[METADATA_FILENAME, bytecode.as_slice()];
if lto {
ignore.push(object.as_slice());
}
- self.add_archive(rlib, name, ignore);
+ self.add_archive(rlib, name, ignore)
}
/// Adds an arbitrary file to this archive
@@ -144,7 +145,8 @@ impl Archive {
str::from_utf8(output.output).unwrap().lines().map(|s| s.to_owned()).collect()
}
- fn add_archive(&mut self, archive: &Path, name: &str, skip: &[&str]) {
+ fn add_archive(&mut self, archive: &Path, name: &str,
+ skip: &[&str]) -> io::IoResult<()> {
let loc = TempDir::new("rsar").unwrap();
// First, extract the contents of the archive to a temporary directory
@@ -159,7 +161,7 @@ impl Archive {
// We skip any files explicitly desired for skipping, and we also skip
// all SYMDEF files as these are just magical placeholders which get
// re-created when we make a new archive anyway.
- let files = fs::readdir(loc.path());
+ let files = if_ok!(fs::readdir(loc.path()));
let mut inputs = ~[];
for file in files.iter() {
let filename = file.filename_str().unwrap();
@@ -168,7 +170,7 @@ impl Archive {
let filename = format!("r-{}-{}", name, filename);
let new_filename = file.with_filename(filename);
- fs::rename(file, &new_filename);
+ if_ok!(fs::rename(file, &new_filename));
inputs.push(new_filename);
}
@@ -176,6 +178,7 @@ impl Archive {
let mut args = ~[&self.dst];
args.extend(&mut inputs.iter());
run_ar(self.sess, "r", None, args.as_slice());
+ Ok(())
}
fn find_library(&self, name: &str) -> Path {
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index fc38fa25a2146..4d6576fed3462 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -100,7 +100,6 @@ pub mod write {
use util::common::time;
use std::c_str::ToCStr;
- use std::io;
use std::libc::{c_uint, c_int};
use std::path::Path;
use std::run;
@@ -297,12 +296,8 @@ pub mod write {
assembly.as_str().unwrap().to_owned()];
debug!("{} '{}'", cc, args.connect("' '"));
- let opt_prog = {
- let _guard = io::ignore_io_error();
- run::process_output(cc, args)
- };
- match opt_prog {
- Some(prog) => {
+ match run::process_output(cc, args) {
+ Ok(prog) => {
if !prog.status.success() {
sess.err(format!("linking with `{}` failed: {}", cc, prog.status));
sess.note(format!("{} arguments: '{}'", cc, args.connect("' '")));
@@ -310,8 +305,8 @@ pub mod write {
sess.abort_if_errors();
}
},
- None => {
- sess.err(format!("could not exec the linker `{}`", cc));
+ Err(e) => {
+ sess.err(format!("could not exec the linker `{}`: {}", cc, e));
sess.abort_if_errors();
}
}
@@ -768,6 +763,15 @@ fn get_system_tool(sess: Session, tool: &str) -> ~str {
}
}
+fn remove(sess: Session, path: &Path) {
+ match fs::unlink(path) {
+ Ok(..) => {}
+ Err(e) => {
+ sess.err(format!("failed to remove {}: {}", path.display(), e));
+ }
+ }
+}
+
/// Perform the linkage portion of the compilation phase. This will generate all
/// of the requested outputs for this compilation session.
pub fn link_binary(sess: Session,
@@ -785,17 +789,15 @@ pub fn link_binary(sess: Session,
// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.save_temps {
- fs::unlink(obj_filename);
- fs::unlink(&obj_filename.with_extension("metadata.o"));
+ remove(sess, obj_filename);
+ remove(sess, &obj_filename.with_extension("metadata.o"));
}
out_filenames
}
fn is_writeable(p: &Path) -> bool {
- use std::io;
-
- match io::result(|| p.stat()) {
+ match p.stat() {
Err(..) => true,
Ok(m) => m.perm & io::UserWrite == io::UserWrite
}
@@ -884,7 +886,7 @@ fn link_rlib(sess: Session,
for &(ref l, kind) in used_libraries.get().iter() {
match kind {
cstore::NativeStatic => {
- a.add_native_library(l.as_slice());
+ a.add_native_library(l.as_slice()).unwrap();
}
cstore::NativeFramework | cstore::NativeUnknown => {}
}
@@ -919,16 +921,23 @@ fn link_rlib(sess: Session,
// the same filename for metadata (stomping over one another)
let tmpdir = TempDir::new("rustc").expect("needs a temp dir");
let metadata = tmpdir.path().join(METADATA_FILENAME);
- fs::File::create(&metadata).write(trans.metadata);
+ match fs::File::create(&metadata).write(trans.metadata) {
+ Ok(..) => {}
+ Err(e) => {
+ sess.err(format!("failed to write {}: {}",
+ metadata.display(), e));
+ sess.abort_if_errors();
+ }
+ }
a.add_file(&metadata, false);
- fs::unlink(&metadata);
+ remove(sess, &metadata);
// For LTO purposes, the bytecode of this library is also inserted
// into the archive.
let bc = obj_filename.with_extension("bc");
a.add_file(&bc, false);
if !sess.opts.save_temps {
- fs::unlink(&bc);
+ remove(sess, &bc);
}
// After adding all files to the archive, we need to update the
@@ -959,7 +968,7 @@ fn link_rlib(sess: Session,
// metadata file).
fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
let mut a = link_rlib(sess, None, obj_filename, out_filename);
- a.add_native_library("morestack");
+ a.add_native_library("morestack").unwrap();
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
for &(cnum, ref path) in crates.iter() {
@@ -970,7 +979,7 @@ fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
continue
}
};
- a.add_rlib(&p, name, sess.lto());
+ a.add_rlib(&p, name, sess.lto()).unwrap();
let native_libs = csearch::get_native_libraries(sess.cstore, cnum);
for &(kind, ref lib) in native_libs.iter() {
let name = match kind {
@@ -1004,14 +1013,10 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
// Invoke the system linker
debug!("{} {}", cc_prog, cc_args.connect(" "));
- let opt_prog = {
- let _guard = io::ignore_io_error();
- time(sess.time_passes(), "running linker", (), |()|
- run::process_output(cc_prog, cc_args))
- };
-
- match opt_prog {
- Some(prog) => {
+ let prog = time(sess.time_passes(), "running linker", (), |()|
+ run::process_output(cc_prog, cc_args));
+ match prog {
+ Ok(prog) => {
if !prog.status.success() {
sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
sess.note(format!("{} arguments: '{}'", cc_prog, cc_args.connect("' '")));
@@ -1019,8 +1024,8 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
sess.abort_if_errors();
}
},
- None => {
- sess.err(format!("could not exec the linker `{}`", cc_prog));
+ Err(e) => {
+ sess.err(format!("could not exec the linker `{}`: {}", cc_prog, e));
sess.abort_if_errors();
}
}
@@ -1030,8 +1035,14 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
// the symbols
if sess.targ_cfg.os == abi::OsMacos && sess.opts.debuginfo {
// FIXME (#9639): This needs to handle non-utf8 paths
- run::process_status("dsymutil",
- [out_filename.as_str().unwrap().to_owned()]);
+ match run::process_status("dsymutil",
+ [out_filename.as_str().unwrap().to_owned()]) {
+ Ok(..) => {}
+ Err(e) => {
+ sess.err(format!("failed to run dsymutil: {}", e));
+ sess.abort_if_errors();
+ }
+ }
}
}
@@ -1225,7 +1236,16 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
time(sess.time_passes(), format!("altering {}.rlib", name),
(), |()| {
let dst = tmpdir.join(cratepath.filename().unwrap());
- fs::copy(&cratepath, &dst);
+ match fs::copy(&cratepath, &dst) {
+ Ok(..) => {}
+ Err(e) => {
+ sess.err(format!("failed to copy {} to {}: {}",
+ cratepath.display(),
+ dst.display(),
+ e));
+ sess.abort_if_errors();
+ }
+ }
let dst_str = dst.as_str().unwrap().to_owned();
let mut archive = Archive::open(sess, dst);
archive.remove_file(format!("{}.o", name));
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index b779c7e73b1c9..a61c297956d78 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -399,7 +399,7 @@ pub fn phase_5_run_llvm_passes(sess: Session,
// Remove assembly source, unless --save-temps was specified
if !sess.opts.save_temps {
- fs::unlink(&asm_filename);
+ fs::unlink(&asm_filename).unwrap();
}
} else {
time(sess.time_passes(), "LLVM passes", (), |_|
@@ -455,33 +455,39 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
return false;
}
-fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate: &ast::Crate)
+fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames,
+ crate: &ast::Crate) -> io::IoResult<()>
{
let lm = link::build_link_meta(sess, crate.attrs, &outputs.obj_filename,
- &mut ::util::sha2::Sha256::new());
+ &mut ::util::sha2::Sha256::new());
let sess_outputs = sess.outputs.borrow();
let out_filenames = sess_outputs.get().iter()
- .map(|&output| link::filename_for_input(&sess, output, &lm, &outputs.out_filename))
+ .map(|&output| link::filename_for_input(&sess, output, &lm,
+ &outputs.out_filename))
.to_owned_vec();
- // Write out dependency rules to the dep-info file if requested with --dep-info
+ // Write out dependency rules to the dep-info file if requested with
+ // --dep-info
let deps_filename = match sess.opts.write_dependency_info {
// Use filename from --dep-file argument if given
(true, Some(ref filename)) => filename.clone(),
- // Use default filename: crate source filename with extension replaced by ".d"
+ // Use default filename: crate source filename with extension replaced
+ // by ".d"
(true, None) => match *input {
FileInput(ref input_path) => {
- let filestem = input_path.filestem().expect("input file must have stem");
- let filename = out_filenames[0].dir_path().join(filestem).with_extension("d");
- filename
+ let filestem = input_path.filestem().expect("input file must \
+ have stem");
+ let filename = out_filenames[0].dir_path().join(filestem);
+ filename.with_extension("d")
},
StrInput(..) => {
- sess.warn("can not write --dep-info without a filename when compiling stdin.");
- return;
+ sess.warn("can not write --dep-info without a filename \
+ when compiling stdin.");
+ return Ok(());
},
},
- _ => return,
+ _ => return Ok(()),
};
// Build a list of files used to compile the output and
@@ -499,11 +505,12 @@ fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate
})
.collect()
};
- let mut file = io::File::create(&deps_filename);
+ let mut file = if_ok!(io::File::create(&deps_filename));
for path in out_filenames.iter() {
- write!(&mut file as &mut Writer,
- "{}: {}\n\n", path.display(), files.connect(" "));
+ if_ok!(write!(&mut file as &mut Writer,
+ "{}: {}\n\n", path.display(), files.connect(" ")));
}
+ Ok(())
}
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
@@ -521,7 +528,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
let outputs = build_output_filenames(input, outdir, output,
expanded_crate.attrs, sess);
- write_out_deps(sess, input, outputs, &expanded_crate);
+ write_out_deps(sess, input, outputs, &expanded_crate).unwrap();
if stop_after_phase_2(sess) { return; }
@@ -541,32 +548,33 @@ struct IdentifiedAnnotation {
}
impl pprust::PpAnn for IdentifiedAnnotation {
- fn pre(&self, node: pprust::AnnNode) {
+ fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
match node {
pprust::NodeExpr(s, _) => pprust::popen(s),
- _ => ()
+ _ => Ok(())
}
}
- fn post(&self, node: pprust::AnnNode) {
+ fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
match node {
pprust::NodeItem(s, item) => {
- pp::space(&mut s.s);
- pprust::synth_comment(s, item.id.to_str());
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pprust::synth_comment(s, item.id.to_str()));
}
pprust::NodeBlock(s, blk) => {
- pp::space(&mut s.s);
- pprust::synth_comment(s, ~"block " + blk.id.to_str());
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pprust::synth_comment(s, ~"block " + blk.id.to_str()));
}
pprust::NodeExpr(s, expr) => {
- pp::space(&mut s.s);
- pprust::synth_comment(s, expr.id.to_str());
- pprust::pclose(s);
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pprust::synth_comment(s, expr.id.to_str()));
+ if_ok!(pprust::pclose(s));
}
pprust::NodePat(s, pat) => {
- pp::space(&mut s.s);
- pprust::synth_comment(s, ~"pat " + pat.id.to_str());
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pprust::synth_comment(s, ~"pat " + pat.id.to_str()));
}
}
+ Ok(())
}
}
@@ -575,24 +583,26 @@ struct TypedAnnotation {
}
impl pprust::PpAnn for TypedAnnotation {
- fn pre(&self, node: pprust::AnnNode) {
+ fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
match node {
pprust::NodeExpr(s, _) => pprust::popen(s),
- _ => ()
+ _ => Ok(())
}
}
- fn post(&self, node: pprust::AnnNode) {
+ fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
let tcx = self.analysis.ty_cx;
match node {
pprust::NodeExpr(s, expr) => {
- pp::space(&mut s.s);
- pp::word(&mut s.s, "as");
- pp::space(&mut s.s);
- pp::word(&mut s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
- pprust::pclose(s);
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pp::word(&mut s.s, "as"));
+ if_ok!(pp::space(&mut s.s));
+ if_ok!(pp::word(&mut s.s,
+ ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))));
+ if_ok!(pprust::pclose(s));
}
_ => ()
}
+ Ok(())
}
}
@@ -638,7 +648,7 @@ pub fn pretty_print_input(sess: Session,
&mut rdr,
~stdout as ~io::Writer,
annotation,
- is_expanded);
+ is_expanded).unwrap();
}
pub fn get_os(triple: &str) -> Option {
@@ -1167,10 +1177,11 @@ pub fn early_error(emitter: &diagnostic::Emitter, msg: &str) -> ! {
fail!(diagnostic::FatalError);
}
-pub fn list_metadata(sess: Session, path: &Path, out: &mut io::Writer) {
+pub fn list_metadata(sess: Session, path: &Path,
+ out: &mut io::Writer) -> io::IoResult<()> {
metadata::loader::list_file_metadata(
token::get_ident_interner(),
- session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);
+ session::sess_os_to_meta_os(sess.targ_cfg.os), path, out)
}
#[cfg(test)]
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 7ba96516bf91b..c5f7d61c224a5 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -54,6 +54,11 @@ use syntax::diagnostic::Emitter;
use syntax::diagnostic;
use syntax::parse;
+#[cfg(stage0)]
+macro_rules! if_ok (
+ ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
pub mod middle {
pub mod trans;
pub mod ty;
@@ -236,8 +241,8 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
1u => {
let ifile = matches.free[0].as_slice();
if ifile == "-" {
- let src =
- str::from_utf8_owned(io::stdin().read_to_end()).unwrap();
+ let contents = io::stdin().read_to_end().unwrap();
+ let src = str::from_utf8_owned(contents).unwrap();
(d::StrInput(src), None)
} else {
(d::FileInput(Path::new(ifile)), Some(Path::new(ifile)))
@@ -267,7 +272,7 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
d::FileInput(ref ifile) => {
let mut stdout = io::stdout();
d::list_metadata(sess, &(*ifile),
- &mut stdout as &mut io::Writer);
+ &mut stdout as &mut io::Writer).unwrap();
}
d::StrInput(_) => {
d::early_error(demitter, "can not list metadata for stdin");
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index deae31abdcb5e..8ba98e84dfa50 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -1111,15 +1111,15 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::Attribute] {
}
fn list_crate_attributes(intr: @IdentInterner, md: ebml::Doc, hash: &str,
- out: &mut io::Writer) {
- write!(out, "=Crate Attributes ({})=\n", hash);
+ out: &mut io::Writer) -> io::IoResult<()> {
+ if_ok!(write!(out, "=Crate Attributes ({})=\n", hash));
let r = get_attributes(md);
for attr in r.iter() {
- write!(out, "{}\n", pprust::attribute_to_str(attr, intr));
+ if_ok!(write!(out, "{}\n", pprust::attribute_to_str(attr, intr)));
}
- write!(out, "\n\n");
+ write!(out, "\n\n")
}
pub fn get_crate_attributes(data: &[u8]) -> ~[ast::Attribute] {
@@ -1154,21 +1154,22 @@ pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
return deps;
}
-fn list_crate_deps(data: &[u8], out: &mut io::Writer) {
- write!(out, "=External Dependencies=\n");
+fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
+ if_ok!(write!(out, "=External Dependencies=\n"));
let r = get_crate_deps(data);
for dep in r.iter() {
let string = token::get_ident(dep.name.name);
- write!(out,
- "{} {}-{}-{}\n",
- dep.cnum,
- string.get(),
- dep.hash,
- dep.vers);
+ if_ok!(write!(out,
+ "{} {}-{}-{}\n",
+ dep.cnum,
+ string.get(),
+ dep.hash,
+ dep.vers));
}
- write!(out, "\n");
+ if_ok!(write!(out, "\n"));
+ Ok(())
}
pub fn get_crate_hash(data: &[u8]) -> ~str {
@@ -1186,11 +1187,11 @@ pub fn get_crate_vers(data: &[u8]) -> ~str {
}
pub fn list_crate_metadata(intr: @IdentInterner, bytes: &[u8],
- out: &mut io::Writer) {
+ out: &mut io::Writer) -> io::IoResult<()> {
let hash = get_crate_hash(bytes);
let md = reader::Doc(bytes);
- list_crate_attributes(intr, md, hash, out);
- list_crate_deps(bytes, out);
+ if_ok!(list_crate_attributes(intr, md, hash, out));
+ list_crate_deps(bytes, out)
}
// Translates a def_id from an external crate to a def_id for the current
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 6a1c3dd4b62e0..d56d211b713ee 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -10,6 +10,7 @@
// Metadata encoding
+#[allow(unused_must_use)]; // everything is just a MemWriter, can't fail
use metadata::common::*;
use metadata::cstore;
@@ -350,7 +351,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().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);
@@ -668,10 +669,10 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
// Encode the base self type.
match explicit_self {
- SelfStatic => ebml_w.writer.write(&[ 's' as u8 ]),
- SelfValue => ebml_w.writer.write(&[ 'v' as u8 ]),
- SelfBox => ebml_w.writer.write(&[ '@' as u8 ]),
- SelfUniq => ebml_w.writer.write(&[ '~' as u8 ]),
+ SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
+ SelfValue => { ebml_w.writer.write(&[ 'v' as u8 ]); }
+ SelfBox => { ebml_w.writer.write(&[ '@' as u8 ]); }
+ SelfUniq => { ebml_w.writer.write(&[ '~' as u8 ]); }
SelfRegion(_, m) => {
// FIXME(#4846) encode custom lifetime
ebml_w.writer.write(&['&' as u8]);
@@ -684,8 +685,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
fn encode_mutability(ebml_w: &writer::Encoder,
m: ast::Mutability) {
match m {
- MutImmutable => ebml_w.writer.write(&[ 'i' as u8 ]),
- MutMutable => ebml_w.writer.write(&[ 'm' as u8 ]),
+ MutImmutable => { ebml_w.writer.write(&[ 'i' as u8 ]); }
+ MutMutable => { ebml_w.writer.write(&[ 'm' as u8 ]); }
}
}
}
@@ -726,12 +727,12 @@ fn encode_info_for_struct(ecx: &EncodeContext,
};
let id = field.node.id;
- index.push(entry {val: id as i64, pos: ebml_w.writer.tell()});
+ index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
{
let mut global_index = global_index.borrow_mut();
global_index.get().push(entry {
val: id as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
ebml_w.start_tag(tag_items_data_item);
@@ -758,7 +759,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().push(entry {
val: ctor_id as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
@@ -921,7 +922,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().push(entry {
val: item.id as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
let add_to_index: || = || add_to_index(item, ebml_w, index);
@@ -1157,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().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,
@@ -1219,7 +1220,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().push(entry {
val: method_def_id.node as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
@@ -1294,7 +1295,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().push(entry {
val: nitem.id as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
@@ -1418,7 +1419,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
let mut index = index.borrow_mut();
index.get().push(entry {
val: CRATE_NODE_ID as i64,
- pos: ebml_w.writer.tell(),
+ pos: ebml_w.writer.tell().unwrap(),
});
}
encode_info_for_mod(ecx,
@@ -1478,7 +1479,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);
@@ -1895,58 +1896,58 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
encode_hash(&mut ebml_w, ecx.link_meta.crate_hash);
- let mut i = ebml_w.writer.tell();
+ let mut i = ebml_w.writer.tell().unwrap();
let crate_attrs = synthesize_crate_attrs(&ecx, crate);
encode_attributes(&mut ebml_w, crate_attrs);
- ecx.stats.attr_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.attr_bytes.set(ebml_w.writer.tell().unwrap() - i);
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_crate_deps(&ecx, &mut ebml_w, ecx.cstore);
- ecx.stats.dep_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.dep_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode the language items.
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_lang_items(&ecx, &mut ebml_w);
- ecx.stats.lang_item_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.lang_item_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode the native libraries used
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_native_libraries(&ecx, &mut ebml_w);
- ecx.stats.native_lib_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.native_lib_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode the macro registrar function
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_macro_registrar_fn(&ecx, &mut ebml_w);
- ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode macro definitions
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_macro_defs(&ecx, crate, &mut ebml_w);
- ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode the def IDs of impls, for coherence checking.
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_impls(&ecx, crate, &mut ebml_w);
- ecx.stats.impl_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.impl_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode miscellaneous info.
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
encode_misc_info(&ecx, crate, &mut ebml_w);
- ecx.stats.misc_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.misc_bytes.set(ebml_w.writer.tell().unwrap() - i);
// Encode and index the items.
ebml_w.start_tag(tag_items);
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
let items_index = encode_info_for_items(&ecx, &mut ebml_w, crate);
- ecx.stats.item_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.item_bytes.set(ebml_w.writer.tell().unwrap() - i);
- i = ebml_w.writer.tell();
+ i = ebml_w.writer.tell().unwrap();
let items_buckets = create_index(items_index);
encode_index(&mut ebml_w, items_buckets, write_i64);
- ecx.stats.index_bytes.set(ebml_w.writer.tell() - i);
+ ecx.stats.index_bytes.set(ebml_w.writer.tell().unwrap() - i);
ebml_w.end_tag();
- ecx.stats.total_bytes.set(ebml_w.writer.tell());
+ ecx.stats.total_bytes.set(ebml_w.writer.tell().unwrap());
if tcx.sess.meta_stats() {
for e in ebml_w.writer.get_ref().iter() {
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index fd8c620dc4e96..7e04a36ee2e08 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -11,7 +11,6 @@
use std::cell::RefCell;
use std::option;
use std::os;
-use std::io;
use std::io::fs;
use std::hashmap::HashSet;
@@ -93,7 +92,7 @@ impl FileSearch {
pub fn search(&self, pick: pick) {
self.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;
let is_rlib = |p: & &Path| {
@@ -163,8 +162,8 @@ pub fn get_or_default_sysroot() -> Path {
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: Option) -> Option {
path.and_then(|mut path|
- match io::io_error::cond.trap(|_| ()).inside(|| fs::readlink(&path)) {
- Some(canon) => {
+ match fs::readlink(&path) {
+ Ok(canon) => {
if canon.is_absolute() {
Some(canon)
} else {
@@ -172,7 +171,7 @@ pub fn get_or_default_sysroot() -> Path {
Some(path.join(canon))
}
},
- None => Some(path),
+ Err(..) => Some(path),
})
}
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 8e557560b95f1..abcd650ced131 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -381,13 +381,13 @@ pub fn read_meta_section_name(os: Os) -> &'static str {
pub fn list_file_metadata(intr: @IdentInterner,
os: Os,
path: &Path,
- out: &mut io::Writer) {
+ out: &mut io::Writer) -> io::IoResult<()> {
match get_metadata_section(os, path) {
option::Some(bytes) => decoder::list_crate_metadata(intr,
bytes.as_slice(),
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 d17a45165432c..913c5dac46039 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -10,6 +10,8 @@
// Type encoding
+#[allow(unused_must_use)]; // as with encoding, everything is a no-fail MemWriter
+
use std::cell::RefCell;
use std::hashmap::HashMap;
use std::io;
@@ -92,9 +94,9 @@ pub fn enc_ty(w: &mut MemWriter, cx: @ctxt, t: ty::t) {
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/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index a957b8c7ef5f2..78221d2adb341 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -88,7 +88,7 @@ struct LoopScope<'a> {
}
impl pprust::PpAnn for DataFlowContext {
- fn pre(&self, node: pprust::AnnNode) {
+ fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
let (ps, id) = match node {
pprust::NodeExpr(ps, expr) => (ps, expr.id),
pprust::NodeBlock(ps, blk) => (ps, blk.id),
@@ -117,9 +117,10 @@ impl pprust::PpAnn for DataFlowContext {
let comment_str = format!("id {}: {}{}{}",
id, entry_str, gens_str, kills_str);
- pprust::synth_comment(ps, comment_str);
- pp::space(&mut ps.s);
+ if_ok!(pprust::synth_comment(ps, comment_str));
+ if_ok!(pp::space(&mut ps.s));
}
+ Ok(())
}
}
@@ -347,18 +348,20 @@ impl DataFlowContext {
debug!("Dataflow result:");
debug!("{}", {
let this = @(*self).clone();
- this.pretty_print_to(~io::stderr() as ~io::Writer, blk);
+ this.pretty_print_to(~io::stderr() as ~io::Writer, blk).unwrap();
""
});
}
- fn pretty_print_to(@self, wr: ~io::Writer, blk: &ast::Block) {
+ fn pretty_print_to(@self, wr: ~io::Writer,
+ blk: &ast::Block) -> io::IoResult<()> {
let mut ps = pprust::rust_printer_annotated(wr, self.tcx.sess.intr(),
self as @pprust::PpAnn);
- pprust::cbox(&mut ps, pprust::indent_unit);
- pprust::ibox(&mut ps, 0u);
- pprust::print_block(&mut ps, blk);
- pp::eof(&mut ps.s);
+ if_ok!(pprust::cbox(&mut ps, pprust::indent_unit));
+ if_ok!(pprust::ibox(&mut ps, 0u));
+ if_ok!(pprust::print_block(&mut ps, blk));
+ if_ok!(pp::eof(&mut ps.s));
+ Ok(())
}
}
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index fb5e548e12f6e..26e4a11ae49a2 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -736,14 +736,15 @@ impl Liveness {
pub fn write_vars(&self,
wr: &mut io::Writer,
ln: LiveNode,
- test: |uint| -> LiveNode) {
+ test: |uint| -> LiveNode) -> io::IoResult<()> {
let node_base_idx = self.idx(ln, Variable(0));
for var_idx in range(0u, self.ir.num_vars.get()) {
let idx = node_base_idx + var_idx;
if test(idx).is_valid() {
- write!(wr, " {}", Variable(var_idx).to_str());
+ if_ok!(write!(wr, " {}", Variable(var_idx).to_str()));
}
}
+ Ok(())
}
pub fn find_loop_scope(&self,
@@ -781,6 +782,7 @@ impl Liveness {
*loop_scope.get().last().unwrap()
}
+ #[allow(unused_must_use)]
pub fn ln_str(&self, ln: LiveNode) -> ~str {
let mut wr = io::MemWriter::new();
{
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index 1aaa446fc6cf3..82850dffa2b14 100644
--- a/src/librustdoc/html/escape.rs
+++ b/src/librustdoc/html/escape.rs
@@ -20,7 +20,7 @@ use std::fmt;
pub struct Escape<'a>(&'a str);
impl<'a> fmt::Show for Escape<'a> {
- fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) {
+ fn fmt(s: &Escape<'a>, 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 Escape(s) = *s;
@@ -29,7 +29,7 @@ impl<'a> fmt::Show for Escape<'a> {
for (i, ch) in s.bytes().enumerate() {
match ch as char {
'<' | '>' | '&' | '\'' | '"' => {
- fmt.buf.write(pile_o_bits.slice(last, i).as_bytes());
+ if_ok!(fmt.buf.write(pile_o_bits.slice(last, i).as_bytes()));
let s = match ch as char {
'>' => ">",
'<' => "<",
@@ -38,7 +38,7 @@ impl<'a> fmt::Show for Escape<'a> {
'"' => """,
_ => unreachable!()
};
- fmt.buf.write(s.as_bytes());
+ if_ok!(fmt.buf.write(s.as_bytes()));
last = i + 1;
}
_ => {}
@@ -46,7 +46,8 @@ impl<'a> fmt::Show for Escape<'a> {
}
if last < s.len() {
- fmt.buf.write(pile_o_bits.slice_from(last).as_bytes());
+ if_ok!(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 6b09072ff080e..92d15fbcd672d 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -48,85 +48,104 @@ impl PuritySpace {
}
impl fmt::Show for clean::Generics {
- fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) {
- if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return }
- f.buf.write("<".as_bytes());
+ fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result {
+ if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) }
+ if_ok!(f.buf.write("<".as_bytes()));
for (i, life) in g.lifetimes.iter().enumerate() {
- if i > 0 { f.buf.write(", ".as_bytes()); }
- write!(f.buf, "{}", *life);
+ if i > 0 {
+ if_ok!(f.buf.write(", ".as_bytes()));
+ }
+ if_ok!(write!(f.buf, "{}", *life));
}
if g.type_params.len() > 0 {
- if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); }
+ if g.lifetimes.len() > 0 {
+ if_ok!(f.buf.write(", ".as_bytes()));
+ }
for (i, tp) in g.type_params.iter().enumerate() {
- if i > 0 { f.buf.write(", ".as_bytes()) }
- f.buf.write(tp.name.as_bytes());
+ if i > 0 {
+ if_ok!(f.buf.write(", ".as_bytes()))
+ }
+ if_ok!(f.buf.write(tp.name.as_bytes()));
if tp.bounds.len() > 0 {
- f.buf.write(": ".as_bytes());
+ if_ok!(f.buf.write(": ".as_bytes()));
for (i, bound) in tp.bounds.iter().enumerate() {
- if i > 0 { f.buf.write(" + ".as_bytes()); }
- write!(f.buf, "{}", *bound);
+ if i > 0 {
+ if_ok!(f.buf.write(" + ".as_bytes()));
+ }
+ if_ok!(write!(f.buf, "{}", *bound));
}
}
}
}
- f.buf.write(">".as_bytes());
+ if_ok!(f.buf.write(">".as_bytes()));
+ Ok(())
}
}
impl fmt::Show for clean::Lifetime {
- fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) {
- f.buf.write("'".as_bytes());
- f.buf.write(l.get_ref().as_bytes());
+ fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result {
+ if_ok!(f.buf.write("'".as_bytes()));
+ if_ok!(f.buf.write(l.get_ref().as_bytes()));
+ Ok(())
}
}
impl fmt::Show 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())
}
clean::TraitBound(ref ty) => {
- write!(f.buf, "{}", *ty);
+ write!(f.buf, "{}", *ty)
}
}
}
}
impl fmt::Show 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 {
+ if_ok!(f.buf.write("::".as_bytes()))
+ }
for (i, seg) in path.segments.iter().enumerate() {
- if i > 0 { f.buf.write("::".as_bytes()) }
- f.buf.write(seg.name.as_bytes());
+ if i > 0 {
+ if_ok!(f.buf.write("::".as_bytes()))
+ }
+ if_ok!(f.buf.write(seg.name.as_bytes()));
if seg.lifetimes.len() > 0 || seg.types.len() > 0 {
- f.buf.write("<".as_bytes());
+ if_ok!(f.buf.write("<".as_bytes()));
let mut comma = false;
for lifetime in seg.lifetimes.iter() {
- if comma { f.buf.write(", ".as_bytes()); }
+ if comma {
+ if_ok!(f.buf.write(", ".as_bytes()));
+ }
comma = true;
- write!(f.buf, "{}", *lifetime);
+ if_ok!(write!(f.buf, "{}", *lifetime));
}
for ty in seg.types.iter() {
- if comma { f.buf.write(", ".as_bytes()); }
+ if comma {
+ if_ok!(f.buf.write(", ".as_bytes()));
+ }
comma = true;
- write!(f.buf, "{}", *ty);
+ if_ok!(write!(f.buf, "{}", *ty));
}
- f.buf.write(">".as_bytes());
+ if_ok!(f.buf.write(">".as_bytes()));
}
}
+ Ok(())
}
}
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
/// rendering function with the necessary arguments for linking to a local path.
fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
- print_all: bool) {
+ print_all: bool) -> fmt::Result {
path(w, p, print_all,
|_cache, loc| { Some("../".repeat(loc.len())) },
|cache| {
@@ -134,13 +153,14 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
None => None,
Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
}
- });
+ })
}
/// Used when rendering an `ExternalPath` structure. Like `resolved_path` this
/// will invoke `path` with proper linking-style arguments.
fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
- fqn: &[~str], kind: clean::TypeKind, crate: ast::CrateNum) {
+ fqn: &[~str], kind: clean::TypeKind,
+ crate: ast::CrateNum) -> fmt::Result {
path(w, p, print_all,
|cache, loc| {
match *cache.extern_locations.get(&crate) {
@@ -161,7 +181,9 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
root: |&render::Cache, &[~str]| -> Option<~str>,
- info: |&render::Cache| -> Option<(~[~str], &'static str)>) {
+ info: |&render::Cache| -> Option<(~[~str], &'static str)>)
+ -> fmt::Result
+{
// The generics will get written to both the title and link
let mut generics = ~"";
let last = path.segments.last().unwrap();
@@ -200,20 +222,20 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
let mut root = root;
for seg in path.segments.slice_to(amt).iter() {
if "super" == seg.name || "self" == seg.name {
- write!(w, "{}::", seg.name);
+ if_ok!(write!(w, "{}::", seg.name));
} else {
root.push_str(seg.name);
root.push_str("/");
- write!(w, "{} ::",
- root,
- seg.name);
+ if_ok!(write!(w, "{} ::",
+ root,
+ seg.name));
}
}
}
None => {
for seg in path.segments.slice_to(amt).iter() {
- write!(w, "{}::", seg.name);
+ if_ok!(write!(w, "{}::", seg.name));
}
}
}
@@ -241,51 +263,57 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
}
}
- write!(w, "{} ",
- shortty, url, fqp.connect("::"), last.name);
+ if_ok!(write!(w, "{} ",
+ shortty, url, fqp.connect("::"), last.name));
}
_ => {
- write!(w, "{}", last.name);
+ if_ok!(write!(w, "{}", last.name));
}
}
- write!(w, "{}", generics);
+ if_ok!(write!(w, "{}", generics));
+ Ok(())
})
})
}
/// Helper to render type parameters
-fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) {
+fn typarams(w: &mut io::Writer,
+ typarams: &Option<~[clean::TyParamBound]>) -> fmt::Result {
match *typarams {
Some(ref params) => {
- write!(w, "<");
+ if_ok!(write!(w, "<"));
for (i, param) in params.iter().enumerate() {
- if i > 0 { write!(w, ", "); }
- write!(w, "{}", *param);
+ if i > 0 {
+ if_ok!(write!(w, ", "));
+ }
+ if_ok!(write!(w, "{}", *param));
}
- write!(w, ">");
+ if_ok!(write!(w, ">"));
+ Ok(())
}
- None => {}
+ None => Ok(())
}
}
impl fmt::Show 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| {
let m = cache.unwrap().get();
- f.buf.write(m.typarams.get(&id).as_bytes());
+ f.buf.write(m.typarams.get(&id).as_bytes())
})
}
clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
- resolved_path(f.buf, id, path, false);
- typarams(f.buf, tp);
+ if_ok!(resolved_path(f.buf, id, path, false));
+ typarams(f.buf, tp)
}
clean::ExternalPath{path: ref path, typarams: ref tp,
fqn: ref fqn, kind, crate} => {
- external_path(f.buf, path, false, fqn.as_slice(), kind, crate);
- typarams(f.buf, tp);
+ if_ok!(external_path(f.buf, path, false, fqn.as_slice(), kind,
+ crate))
+ typarams(f.buf, tp)
}
clean::Self(..) => f.buf.write("Self".as_bytes()),
clean::Primitive(prim) => {
@@ -306,7 +334,7 @@ impl fmt::Show for clean::Type {
ast::TyBool => "bool",
ast::TyChar => "char",
};
- f.buf.write(s.as_bytes());
+ f.buf.write(s.as_bytes())
}
clean::Closure(ref decl) => {
let region = match decl.region {
@@ -322,7 +350,7 @@ impl fmt::Show for clean::Type {
ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
},
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
- ret = decl.decl.output);
+ ret = decl.decl.output)
// FIXME: where are bounds and lifetimes printed?!
}
clean::BareFunction(ref decl) => {
@@ -333,19 +361,21 @@ impl fmt::Show for clean::Type {
ref s => " " + *s + " ",
},
decl.generics,
- decl.decl);
+ decl.decl)
}
clean::Tuple(ref typs) => {
- f.buf.write("(".as_bytes());
+ if_ok!(f.buf.write("(".as_bytes()));
for (i, typ) in typs.iter().enumerate() {
- if i > 0 { f.buf.write(", ".as_bytes()) }
- write!(f.buf, "{}", *typ);
+ if i > 0 {
+ if_ok!(f.buf.write(", ".as_bytes()))
+ }
+ if_ok!(write!(f.buf, "{}", *typ));
}
- f.buf.write(")".as_bytes());
+ f.buf.write(")".as_bytes())
}
clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
clean::FixedVector(ref t, ref s) => {
- write!(f.buf, "[{}, ..{}]", **t, *s);
+ write!(f.buf, "[{}, ..{}]", **t, *s)
}
clean::String => f.buf.write("str".as_bytes()),
clean::Bool => f.buf.write("bool".as_bytes()),
@@ -368,23 +398,23 @@ impl fmt::Show for clean::Type {
clean::Mutable => "mut ",
clean::Immutable => "",
},
- **ty);
+ **ty)
}
}
}
}
impl fmt::Show 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::Show 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(", "); }
@@ -393,12 +423,12 @@ impl fmt::Show for ~[clean::Argument] {
}
args.push_str(format!("{}", input.type_));
}
- f.buf.write(args.as_bytes());
+ f.buf.write(args.as_bytes())
}
}
impl<'a> fmt::Show for Method<'a> {
- fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) {
+ fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result {
let Method(selfty, d) = *m;
let mut args = ~"";
match *selfty {
@@ -429,74 +459,79 @@ impl<'a> fmt::Show for Method<'a> {
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
args = args,
arrow = match d.output { clean::Unit => "no", _ => "yes" },
- ret = d.output);
+ ret = d.output)
}
}
impl fmt::Show for VisSpace {
- fn fmt(v: &VisSpace, f: &mut fmt::Formatter) {
+ fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result {
match v.get() {
- Some(ast::Public) => { write!(f.buf, "pub "); }
- Some(ast::Private) => { write!(f.buf, "priv "); }
- Some(ast::Inherited) | None => {}
+ Some(ast::Public) => write!(f.buf, "pub "),
+ Some(ast::Private) => write!(f.buf, "priv "),
+ Some(ast::Inherited) | None => Ok(())
}
}
}
impl fmt::Show for PuritySpace {
- fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) {
+ fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result {
match p.get() {
ast::UnsafeFn => write!(f.buf, "unsafe "),
ast::ExternFn => write!(f.buf, "extern "),
- ast::ImpureFn => {}
+ ast::ImpureFn => Ok(())
}
}
}
impl fmt::Show 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().unwrap().name {
- write!(f.buf, "use {};", *src);
+ write!(f.buf, "use {};", *src)
} else {
- write!(f.buf, "use {} = {};", *name, *src);
+ write!(f.buf, "use {} = {};", *name, *src)
}
}
clean::GlobImport(ref src) => {
- write!(f.buf, "use {}::*;", *src);
+ write!(f.buf, "use {}::*;", *src)
}
clean::ImportList(ref src, ref names) => {
- write!(f.buf, "use {}::\\{", *src);
+ if_ok!(write!(f.buf, "use {}::\\{", *src));
for (i, n) in names.iter().enumerate() {
- if i > 0 { write!(f.buf, ", "); }
- write!(f.buf, "{}", *n);
+ if i > 0 {
+ if_ok!(write!(f.buf, ", "));
+ }
+ if_ok!(write!(f.buf, "{}", *n));
}
- write!(f.buf, "\\};");
+ write!(f.buf, "\\};")
}
}
}
}
impl fmt::Show 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 {
// FIXME: shouldn't be restricted to just local imports
Some(did) if ast_util::is_local(did) => {
- resolved_path(f.buf, did.node, &v.path, true);
+ resolved_path(f.buf, did.node, &v.path, true)
}
_ => {
for (i, seg) in v.path.segments.iter().enumerate() {
- if i > 0 { write!(f.buf, "::") }
- write!(f.buf, "{}", seg.name);
+ if i > 0 {
+ if_ok!(write!(f.buf, "::"))
+ }
+ if_ok!(write!(f.buf, "{}", seg.name));
}
+ Ok(())
}
}
}
}
impl fmt::Show 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 {
// FIXME: shouldn't be limited to just local imports
Some(did) if ast_util::is_local(did) => {
@@ -508,7 +543,7 @@ impl fmt::Show for clean::ViewListIdent {
types: ~[],
}]
};
- resolved_path(f.buf, did.node, &path, false);
+ resolved_path(f.buf, did.node, &path, false)
}
_ => write!(f.buf, "{}", v.name),
}
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 4565facea0211..db7c882ab4203 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -26,6 +26,7 @@ pub struct Page<'a> {
pub fn render(
dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
+ -> fmt::Result
{
write!(dst,
"
@@ -121,7 +122,7 @@ pub fn render(
favicon = nonestr(layout.favicon),
sidebar = *sidebar,
crate = layout.crate,
- );
+ )
}
fn nonestr<'a>(s: &'a str) -> &'a str {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 254d65ae2f604..c2203a352c53f 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -109,7 +109,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
}
}
-pub fn render(w: &mut io::Writer, s: &str) {
+pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result {
extern fn block(ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
unsafe {
let my_opaque: &my_opaque = cast::transmute(opaque);
@@ -159,11 +159,12 @@ pub fn render(w: &mut io::Writer, s: &str) {
sd_markdown_render(ob, s.as_ptr(), s.len() as libc::size_t, markdown);
sd_markdown_free(markdown);
- vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
- w.write(buf);
+ let ret = vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
+ w.write(buf)
});
bufrelease(ob);
+ ret
}
}
@@ -210,10 +211,10 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
}
impl<'a> fmt::Show for Markdown<'a> {
- fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) {
+ fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
let Markdown(md) = *md;
// This is actually common enough to special-case
- if md.len() == 0 { return; }
- render(fmt.buf, md.as_slice());
+ if md.len() == 0 { return Ok(()) }
+ render(fmt.buf, md.as_slice())
}
}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 0b2c568c723ae..65696528a6fa1 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -195,7 +195,7 @@ local_data_key!(pub cache_key: Arc)
local_data_key!(pub current_location_key: ~[~str])
/// Generates the documentation for `crate` into the directory `dst`
-pub fn run(mut crate: clean::Crate, dst: Path) {
+pub fn run(mut crate: clean::Crate, dst: Path) -> io::IoResult<()> {
let mut cx = Context {
dst: dst,
current: ~[],
@@ -208,7 +208,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
},
include_sources: true,
};
- mkdir(&cx.dst);
+ if_ok!(mkdir(&cx.dst));
match crate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
Some(attrs) => {
@@ -248,47 +248,55 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
// Add all the static files
let mut dst = cx.dst.join(crate.name.as_slice());
- mkdir(&dst);
- write(dst.join("jquery.js"), include_str!("static/jquery-2.0.3.min.js"));
- write(dst.join("main.js"), include_str!("static/main.js"));
- write(dst.join("main.css"), include_str!("static/main.css"));
- write(dst.join("normalize.css"), include_str!("static/normalize.css"));
+ if_ok!(mkdir(&dst));
+ if_ok!(write(dst.join("jquery.js"),
+ include_str!("static/jquery-2.0.3.min.js")));
+ if_ok!(write(dst.join("main.js"), include_str!("static/main.js")));
+ if_ok!(write(dst.join("main.css"), include_str!("static/main.css")));
+ if_ok!(write(dst.join("normalize.css"),
+ include_str!("static/normalize.css")));
// Publish the search index
{
dst.push("search-index.js");
let mut w = BufferedWriter::new(File::create(&dst).unwrap());
let w = &mut w as &mut Writer;
- write!(w, "var searchIndex = [");
+ if_ok!(write!(w, "var searchIndex = ["));
for (i, item) in cache.search_index.iter().enumerate() {
- if i > 0 { write!(w, ","); }
- write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
- item.ty, item.name, item.path,
- item.desc.to_json().to_str())
+ if i > 0 {
+ if_ok!(write!(w, ","));
+ }
+ if_ok!(write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
+ item.ty, item.name, item.path,
+ item.desc.to_json().to_str()));
match item.parent {
- Some(id) => { write!(w, ",parent:'{}'", id); }
+ Some(id) => {
+ if_ok!(write!(w, ",parent:'{}'", id));
+ }
None => {}
}
- write!(w, "\\}");
+ if_ok!(write!(w, "\\}"));
}
- write!(w, "];");
- write!(w, "var allPaths = \\{");
+ if_ok!(write!(w, "];"));
+ if_ok!(write!(w, "var allPaths = \\{"));
for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() {
- if i > 0 { write!(w, ","); }
- write!(w, "'{}':\\{type:'{}',name:'{}'\\}",
- id, short, *fqp.last().unwrap());
+ if i > 0 {
+ if_ok!(write!(w, ","));
+ }
+ if_ok!(write!(w, "'{}':\\{type:'{}',name:'{}'\\}",
+ id, short, *fqp.last().unwrap()));
}
- write!(w, "\\};");
- w.flush();
+ if_ok!(write!(w, "\\};"));
+ if_ok!(w.flush());
}
// Render all source files (this may turn into a giant no-op)
{
info!("emitting source files");
let dst = cx.dst.join("src");
- mkdir(&dst);
+ if_ok!(mkdir(&dst));
let dst = dst.join(crate.name.as_slice());
- mkdir(&dst);
+ if_ok!(mkdir(&dst));
let mut folder = SourceCollector {
dst: dst,
seen: HashSet::new(),
@@ -302,27 +310,23 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
}
// And finally render the whole crate's documentation
- cx.crate(crate, cache);
+ cx.crate(crate, cache)
}
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
-fn write(dst: Path, contents: &str) {
- File::create(&dst).write(contents.as_bytes());
+fn write(dst: Path, contents: &str) -> io::IoResult<()> {
+ File::create(&dst).write(contents.as_bytes())
}
/// 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);
- }
- })
+fn mkdir(path: &Path) -> io::IoResult<()> {
+ if !path.exists() {
+ fs::mkdir(path, io::UserRWX)
+ } else {
+ Ok(())
+ }
}
/// Takes a path to a source file and cleans the path to it. This canonicalizes
@@ -387,15 +391,17 @@ impl<'a> DocFolder for SourceCollector<'a> {
// something like that), so just don't include sources for the
// entire crate. The other option is maintaining this mapping on a
// per-file basis, but that's probably not worth it...
- self.cx.include_sources = self.emit_source(item.source.filename);
+ self.cx.include_sources = match self.emit_source(item.source.filename) {
+ Ok(()) => true,
+ Err(e) => {
+ println!("warning: source code was requested to be rendered, \
+ but processing `{}` had an error: {}",
+ item.source.filename, e);
+ println!(" skipping rendering of source code");
+ false
+ }
+ };
self.seen.insert(item.source.filename.clone());
-
- if !self.cx.include_sources {
- println!("warning: source code was requested to be rendered, \
- but `{}` is a missing source file.",
- item.source.filename);
- println!(" skipping rendering of source code");
- }
}
self.fold_item_recur(item)
@@ -404,30 +410,18 @@ impl<'a> DocFolder for SourceCollector<'a> {
impl<'a> SourceCollector<'a> {
/// Renders the given filename into its corresponding HTML source file.
- fn emit_source(&mut self, filename: &str) -> bool {
+ fn emit_source(&mut self, filename: &str) -> io::IoResult<()> {
let p = Path::new(filename);
- // Read the contents of the file
- 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)) {
- 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
- }
- }
- }
+ // 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 contents = match File::open(&p).read_to_end() {
+ Ok(r) => r,
+ // eew macro hacks
+ Err(..) if filename == "" => return Ok(()),
+ Err(e) => return Err(e)
+ };
let contents = str::from_utf8_owned(contents).unwrap();
// Create the intermediate directories
@@ -435,12 +429,12 @@ impl<'a> SourceCollector<'a> {
let mut root_path = ~"../../";
clean_srcpath(p.dirname(), |component| {
cur.push(component);
- mkdir(&cur);
+ mkdir(&cur).unwrap();
root_path.push_str("../");
});
cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
- let mut w = BufferedWriter::new(File::create(&cur).unwrap());
+ let mut w = BufferedWriter::new(if_ok!(File::create(&cur)));
let title = cur.filename_display().with_str(|s| format!("{} -- source", s));
let page = layout::Page {
@@ -448,10 +442,10 @@ impl<'a> SourceCollector<'a> {
ty: "source",
root_path: root_path,
};
- layout::render(&mut w as &mut Writer, &self.cx.layout,
- &page, &(""), &Source(contents.as_slice()));
- w.flush();
- return true;
+ if_ok!(layout::render(&mut w as &mut Writer, &self.cx.layout,
+ &page, &(""), &Source(contents.as_slice())));
+ if_ok!(w.flush());
+ return Ok(());
}
}
@@ -665,7 +659,7 @@ impl Context {
info!("Recursing into {}", self.dst.display());
- mkdir(&self.dst);
+ mkdir(&self.dst).unwrap();
let ret = f(self);
info!("Recursed; leaving {}", self.dst.display());
@@ -683,10 +677,10 @@ impl Context {
///
/// This currently isn't parallelized, but it'd be pretty easy to add
/// parallelization to this function.
- fn crate(self, mut crate: clean::Crate, cache: Cache) {
+ fn crate(self, mut crate: clean::Crate, cache: Cache) -> io::IoResult<()> {
let mut item = match crate.module.take() {
Some(i) => i,
- None => return
+ None => return Ok(())
};
item.name = Some(crate.name);
@@ -696,12 +690,13 @@ impl Context {
let mut work = ~[(self, item)];
loop {
match work.pop() {
- Some((mut cx, item)) => cx.item(item, |cx, item| {
+ Some((mut cx, item)) => if_ok!(cx.item(item, |cx, item| {
work.push((cx.clone(), item));
- }),
+ })),
None => break,
}
}
+ Ok(())
}
/// Non-parellelized version of rendering an item. This will take the input
@@ -709,9 +704,10 @@ impl Context {
/// all sub-items which need to be rendered.
///
/// The rendering driver uses this closure to queue up more work.
- fn item(&mut self, item: clean::Item, f: |&mut Context, clean::Item|) {
+ fn item(&mut self, item: clean::Item,
+ f: |&mut Context, clean::Item|) -> io::IoResult<()> {
fn render(w: io::File, cx: &mut Context, it: &clean::Item,
- pushname: bool) {
+ pushname: bool) -> io::IoResult<()> {
info!("Rendering an item to {}", w.path().display());
// A little unfortunate that this is done like this, but it sure
// does make formatting *a lot* nicer.
@@ -733,10 +729,10 @@ impl Context {
// of the pain by using a buffered writer instead of invoking the
// write sycall all the time.
let mut writer = BufferedWriter::new(w);
- layout::render(&mut writer as &mut Writer, &cx.layout, &page,
- &Sidebar{ cx: cx, item: it },
- &Item{ cx: cx, item: it });
- writer.flush();
+ if_ok!(layout::render(&mut writer as &mut Writer, &cx.layout, &page,
+ &Sidebar{ cx: cx, item: it },
+ &Item{ cx: cx, item: it }));
+ writer.flush()
}
match item.inner {
@@ -748,7 +744,8 @@ impl Context {
self.recurse(name, |this| {
let item = item.take_unwrap();
let dst = this.dst.join("index.html");
- render(File::create(&dst).unwrap(), this, &item, false);
+ let dst = if_ok!(File::create(&dst));
+ if_ok!(render(dst, this, &item, false));
let m = match item.inner {
clean::ModuleItem(m) => m,
@@ -758,6 +755,7 @@ impl Context {
for item in m.items.move_iter() {
f(this,item);
}
+ Ok(())
})
}
@@ -765,10 +763,11 @@ impl Context {
// pages dedicated to them.
_ if item.name.is_some() => {
let dst = self.dst.join(item_path(&item));
- render(File::create(&dst).unwrap(), self, &item, true);
+ let dst = if_ok!(File::create(&dst));
+ render(dst, self, &item, true)
}
- _ => {}
+ _ => Ok(())
}
}
}
@@ -802,16 +801,16 @@ impl<'a> Item<'a> {
}
impl<'a> fmt::Show for Item<'a> {
- fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) {
+ fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
match attr::find_stability(it.item.attrs.iter()) {
Some(ref stability) => {
- write!(fmt.buf,
+ if_ok!(write!(fmt.buf,
"{lvl} ",
lvl = stability.level.to_str(),
reason = match stability.text {
Some(ref s) => (*s).clone(),
None => InternedString::new(""),
- });
+ }));
}
None => {}
}
@@ -826,23 +825,24 @@ impl<'a> fmt::Show for Item<'a> {
} else {
format!("{}-{}", it.item.source.loline, it.item.source.hiline)
};
- write!(fmt.buf,
- "[src] ",
- root = it.cx.root_path,
- crate = it.cx.layout.crate,
- path = path.connect("/"),
- href = href);
+ if_ok!(write!(fmt.buf,
+ "\
+ [src] ",
+ root = it.cx.root_path,
+ crate = it.cx.layout.crate,
+ path = path.connect("/"),
+ href = href));
}
// Write the breadcrumb trail header for the top
- write!(fmt.buf, "");
+ if_ok!(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(..) => if_ok!(write!(fmt.buf, "Module ")),
+ clean::FunctionItem(..) => if_ok!(write!(fmt.buf, "Function ")),
+ clean::TraitItem(..) => if_ok!(write!(fmt.buf, "Trait ")),
+ clean::StructItem(..) => if_ok!(write!(fmt.buf, "Struct ")),
+ clean::EnumItem(..) => if_ok!(write!(fmt.buf, "Enum ")),
_ => {}
}
let cur = it.cx.current.as_slice();
@@ -852,11 +852,11 @@ impl<'a> fmt::Show for Item<'a> {
for _ in range(0, cur.len() - i - 1) {
trail.push_str("../");
}
- write!(fmt.buf, "{} ::",
- trail, component.as_slice());
+ if_ok!(write!(fmt.buf, "{} ::",
+ trail, component.as_slice()));
}
- write!(fmt.buf, "{} ",
- shortty(it.item), it.item.name.get_ref().as_slice());
+ if_ok!(write!(fmt.buf, "{} ",
+ shortty(it.item), it.item.name.get_ref().as_slice()));
match it.item.inner {
clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
@@ -867,7 +867,7 @@ impl<'a> fmt::Show for Item<'a> {
clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t),
- _ => {}
+ _ => Ok(())
}
}
}
@@ -903,18 +903,19 @@ fn shorter<'a>(s: Option<&'a str>) -> &'a str {
}
}
-fn document(w: &mut Writer, item: &clean::Item) {
+fn document(w: &mut Writer, item: &clean::Item) -> fmt::Result {
match item.doc_value() {
Some(s) => {
- write!(w, "{}
", Markdown(s));
+ if_ok!(write!(w, "{}
", Markdown(s)));
}
None => {}
}
+ Ok(())
}
fn item_module(w: &mut Writer, cx: &Context,
- item: &clean::Item, items: &[clean::Item]) {
- document(w, item);
+ item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
+ if_ok!(document(w, item));
debug!("{:?}", items);
let mut indices = vec::from_fn(items.len(), |i| i);
@@ -965,10 +966,10 @@ fn item_module(w: &mut Writer, cx: &Context,
let myty = shortty(myitem);
if myty != curty {
if curty != "" {
- write!(w, "");
+ if_ok!(write!(w, ""));
}
curty = myty;
- write!(w, "{} \n", match myitem.inner {
+ if_ok!(write!(w, "{} \n", match myitem.inner {
clean::ModuleItem(..) => "Modules",
clean::StructItem(..) => "Structs",
clean::EnumItem(..) => "Enums",
@@ -984,24 +985,26 @@ fn item_module(w: &mut Writer, cx: &Context,
clean::VariantItem(..) => "Variants",
clean::ForeignFunctionItem(..) => "Foreign Functions",
clean::ForeignStaticItem(..) => "Foreign Statics",
- });
+ }));
}
match myitem.inner {
clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
struct Initializer<'a>(&'a str);
impl<'a> fmt::Show for Initializer<'a> {
- fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) {
+ fn fmt(s: &Initializer<'a>,
+ f: &mut fmt::Formatter) -> fmt::Result {
let Initializer(s) = *s;
- if s.len() == 0 { return; }
- write!(f.buf, " =
");
+ if s.len() == 0 { return Ok(()); }
+ if_ok!(write!(f.buf, " =
"));
let tag = if s.contains("\n") { "pre" } else { "code" };
- write!(f.buf, "<{tag}>{}{tag}>",
- s.as_slice(), tag=tag);
+ if_ok!(write!(f.buf, "<{tag}>{}{tag}>",
+ s.as_slice(), tag=tag));
+ Ok(())
}
}
- write!(w, "
+ if_ok!(write!(w, "
{}static {}: {}
{}
{}
@@ -1011,27 +1014,27 @@ fn item_module(w: &mut Writer, cx: &Context,
*myitem.name.get_ref(),
s.type_,
Initializer(s.expr),
- Markdown(blank(myitem.doc_value())));
+ Markdown(blank(myitem.doc_value()))));
}
clean::ViewItemItem(ref item) => {
match item.inner {
clean::ExternMod(ref name, ref src, _) => {
- write!(w, " extern mod {}",
- name.as_slice());
+ if_ok!(write!(w, "extern mod {}",
+ name.as_slice()));
match *src {
- Some(ref src) => write!(w, " = \"{}\"",
- src.as_slice()),
+ Some(ref src) => if_ok!(write!(w, " = \"{}\"",
+ src.as_slice())),
None => {}
}
- write!(w, ";
");
+ if_ok!(write!(w, ";
"));
}
clean::Import(ref imports) => {
for import in imports.iter() {
- write!(w, "{}{}
",
- VisSpace(myitem.visibility),
- *import);
+ if_ok!(write!(w, "{}{}
",
+ VisSpace(myitem.visibility),
+ *import));
}
}
}
@@ -1040,7 +1043,7 @@ fn item_module(w: &mut Writer, cx: &Context,
_ => {
if myitem.name.is_none() { continue }
- write!(w, "
+ if_ok!(write!(w, "
{}
@@ -1051,24 +1054,26 @@ fn item_module(w: &mut Writer, cx: &Context,
Markdown(shorter(myitem.doc_value())),
class = shortty(myitem),
href = item_path(myitem),
- title = full_path(cx, myitem));
+ title = full_path(cx, myitem)));
}
}
}
- write!(w, "
");
+ write!(w, "
")
}
-fn item_function(w: &mut Writer, it: &clean::Item, f: &clean::Function) {
- write!(w, "{vis}{purity}fn {name}{generics}{decl} ",
+fn item_function(w: &mut Writer, it: &clean::Item,
+ f: &clean::Function) -> fmt::Result {
+ if_ok!(write!(w, "{vis}{purity}fn {name}{generics}{decl} ",
vis = VisSpace(it.visibility),
purity = PuritySpace(f.purity),
name = it.name.get_ref().as_slice(),
generics = f.generics,
- decl = f.decl);
- document(w, it);
+ decl = f.decl));
+ document(w, it)
}
-fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) {
+fn item_trait(w: &mut Writer, it: &clean::Item,
+ t: &clean::Trait) -> fmt::Result {
let mut parents = ~"";
if t.parents.len() > 0 {
parents.push_str(": ");
@@ -1079,99 +1084,102 @@ fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) {
}
// Output the trait definition
- write!(w, "{}trait {}{}{} ",
- VisSpace(it.visibility),
- it.name.get_ref().as_slice(),
- t.generics,
- parents);
+ if_ok!(write!(w, "{}trait {}{}{} ",
+ VisSpace(it.visibility),
+ it.name.get_ref().as_slice(),
+ t.generics,
+ parents));
let required = t.methods.iter().filter(|m| m.is_req()).to_owned_vec();
let provided = t.methods.iter().filter(|m| !m.is_req()).to_owned_vec();
if t.methods.len() == 0 {
- write!(w, "\\{ \\}");
+ if_ok!(write!(w, "\\{ \\}"));
} else {
- write!(w, "\\{\n");
+ if_ok!(write!(w, "\\{\n"));
for m in required.iter() {
- write!(w, " ");
- render_method(w, m.item(), true);
- write!(w, ";\n");
+ if_ok!(write!(w, " "));
+ if_ok!(render_method(w, m.item(), true));
+ if_ok!(write!(w, ";\n"));
}
if required.len() > 0 && provided.len() > 0 {
- w.write("\n".as_bytes());
+ if_ok!(w.write("\n".as_bytes()));
}
for m in provided.iter() {
- write!(w, " ");
- render_method(w, m.item(), true);
- write!(w, " \\{ ... \\}\n");
+ if_ok!(write!(w, " "));
+ if_ok!(render_method(w, m.item(), true));
+ if_ok!(write!(w, " \\{ ... \\}\n"));
}
- write!(w, "\\}");
+ if_ok!(write!(w, "\\}"));
}
- write!(w, " ");
+ if_ok!(write!(w, " "));
// Trait documentation
- document(w, it);
-
- fn meth(w: &mut Writer, m: &clean::TraitMethod) {
- write!(w, "",
- shortty(m.item()),
- *m.item().name.get_ref());
- render_method(w, m.item(), false);
- write!(w, "
");
- document(w, m.item());
+ if_ok!(document(w, it));
+
+ fn meth(w: &mut Writer, m: &clean::TraitMethod) -> fmt::Result {
+ if_ok!(write!(w, "",
+ shortty(m.item()),
+ *m.item().name.get_ref()));
+ if_ok!(render_method(w, m.item(), false));
+ if_ok!(write!(w, "
"));
+ if_ok!(document(w, m.item()));
+ Ok(())
}
// Output the documentation for each function individually
if required.len() > 0 {
- write!(w, "
+ if_ok!(write!(w, "
Required Methods
- ");
+ "));
for m in required.iter() {
- meth(w, *m);
+ if_ok!(meth(w, *m));
}
- write!(w, "
");
+ if_ok!(write!(w, ""));
}
if provided.len() > 0 {
- write!(w, "
+ if_ok!(write!(w, "
Provided Methods
- ");
+ "));
for m in provided.iter() {
- meth(w, *m);
+ if_ok!(meth(w, *m));
}
- write!(w, "
");
+ if_ok!(write!(w, ""));
}
local_data::get(cache_key, |cache| {
let cache = cache.unwrap().get();
match cache.implementors.find(&it.id) {
Some(implementors) => {
- write!(w, "
+ if_ok!(write!(w, "
Implementors
- ");
+ "));
for i in implementors.iter() {
match *i {
PathType(ref ty) => {
- write!(w, "{}
", *ty);
+ if_ok!(write!(w, "{}
", *ty));
}
OtherType(ref generics, ref trait_, ref for_) => {
- write!(w, "impl{} {} for {}
",
- *generics, *trait_, *for_);
+ if_ok!(write!(w, "impl{} {} for {}
",
+ *generics, *trait_, *for_));
}
}
}
- write!(w, " ");
+ if_ok!(write!(w, ""));
}
None => {}
}
+ Ok(())
})
}
-fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) {
+fn render_method(w: &mut Writer, meth: &clean::Item,
+ withlink: bool) -> fmt::Result {
fn fun(w: &mut Writer, it: &clean::Item, purity: ast::Purity,
g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
- withlink: bool) {
+ withlink: bool) -> fmt::Result {
write!(w, "{}fn {withlink, select,
true{{name} }
@@ -1185,118 +1193,125 @@ fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) {
name = it.name.get_ref().as_slice(),
generics = *g,
decl = Method(selfty, d),
- withlink = if withlink {"true"} else {"false"});
+ withlink = if withlink {"true"} else {"false"})
}
match meth.inner {
clean::TyMethodItem(ref m) => {
- fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+ fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
}
clean::MethodItem(ref m) => {
- fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+ fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
}
_ => unreachable!()
}
}
-fn item_struct(w: &mut Writer, it: &clean::Item, s: &clean::Struct) {
- write!(w, "");
- render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
- s.fields_stripped, "", true);
- write!(w, " ");
+fn item_struct(w: &mut Writer, it: &clean::Item,
+ s: &clean::Struct) -> fmt::Result {
+ if_ok!(write!(w, ""));
+ if_ok!(render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
+ s.fields_stripped, "", true));
+ if_ok!(write!(w, " "));
- document(w, it);
+ if_ok!(document(w, it));
match s.struct_type {
doctree::Plain if s.fields.len() > 0 => {
- write!(w, "Fields \n");
+ if_ok!(write!(w, "Fields \n"));
for field in s.fields.iter() {
- write!(w, "\
- {name}
",
- name = field.name.get_ref().as_slice());
- document(w, field);
- write!(w, " ");
+ if_ok!(write!(w, "\
+ {name}
",
+ name = field.name.get_ref().as_slice()));
+ if_ok!(document(w, field));
+ if_ok!(write!(w, " "));
}
- write!(w, "
");
+ if_ok!(write!(w, "
"));
}
_ => {}
}
- render_methods(w, it);
+ render_methods(w, it)
}
-fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) {
- write!(w, "{}enum {}{}",
- VisSpace(it.visibility),
- it.name.get_ref().as_slice(),
- e.generics);
+fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) -> fmt::Result {
+ if_ok!(write!(w, "{}enum {}{}",
+ VisSpace(it.visibility),
+ it.name.get_ref().as_slice(),
+ e.generics));
if e.variants.len() == 0 && !e.variants_stripped {
- write!(w, " \\{\\}");
+ if_ok!(write!(w, " \\{\\}"));
} else {
- write!(w, " \\{\n");
+ if_ok!(write!(w, " \\{\n"));
for v in e.variants.iter() {
- write!(w, " ");
+ if_ok!(write!(w, " "));
let name = v.name.get_ref().as_slice();
match v.inner {
clean::VariantItem(ref var) => {
match var.kind {
- clean::CLikeVariant => write!(w, "{}", name),
+ clean::CLikeVariant => if_ok!(write!(w, "{}", name)),
clean::TupleVariant(ref tys) => {
- write!(w, "{}(", name);
+ if_ok!(write!(w, "{}(", name));
for (i, ty) in tys.iter().enumerate() {
- if i > 0 { write!(w, ", ") }
- write!(w, "{}", *ty);
+ if i > 0 {
+ if_ok!(write!(w, ", "))
+ }
+ if_ok!(write!(w, "{}", *ty));
}
- write!(w, ")");
+ if_ok!(write!(w, ")"));
}
clean::StructVariant(ref s) => {
- render_struct(w, v, None, s.struct_type, s.fields,
- s.fields_stripped, " ", false);
+ if_ok!(render_struct(w, v, None, s.struct_type,
+ s.fields, s.fields_stripped,
+ " ", false));
}
}
}
_ => unreachable!()
}
- write!(w, ",\n");
+ if_ok!(write!(w, ",\n"));
}
if e.variants_stripped {
- write!(w, " // some variants omitted\n");
+ if_ok!(write!(w, " // some variants omitted\n"));
}
- write!(w, "\\}");
+ if_ok!(write!(w, "\\}"));
}
- write!(w, " ");
+ if_ok!(write!(w, " "));
- document(w, it);
+ if_ok!(document(w, it));
if e.variants.len() > 0 {
- write!(w, "Variants \n");
+ if_ok!(write!(w, "Variants \n"));
for variant in e.variants.iter() {
- write!(w, "{name}
",
- name = variant.name.get_ref().as_slice());
- document(w, variant);
+ if_ok!(write!(w, " {name}
",
+ name = variant.name.get_ref().as_slice()));
+ if_ok!(document(w, variant));
match variant.inner {
clean::VariantItem(ref var) => {
match var.kind {
clean::StructVariant(ref s) => {
- write!(w, "Fields \n");
+ if_ok!(write!(w, "Fields \n
+ "));
for field in s.fields.iter() {
- write!(w, "\
- {f}
",
- v = variant.name.get_ref().as_slice(),
- f = field.name.get_ref().as_slice());
- document(w, field);
- write!(w, " ");
+ if_ok!(write!(w, "\
+ {f}
",
+ v = variant.name.get_ref().as_slice(),
+ f = field.name.get_ref().as_slice()));
+ if_ok!(document(w, field));
+ if_ok!(write!(w, " "));
}
- write!(w, "
");
+ if_ok!(write!(w, "
"));
}
_ => ()
}
}
_ => ()
}
- write!(w, " ");
+ if_ok!(write!(w, ""));
}
- write!(w, "
");
+ if_ok!(write!(w, "
"));
}
- render_methods(w, it);
+ if_ok!(render_methods(w, it));
+ Ok(())
}
fn render_struct(w: &mut Writer, it: &clean::Item,
@@ -1305,54 +1320,59 @@ fn render_struct(w: &mut Writer, it: &clean::Item,
fields: &[clean::Item],
fields_stripped: bool,
tab: &str,
- structhead: bool) {
- write!(w, "{}{}{}",
- VisSpace(it.visibility),
- if structhead {"struct "} else {""},
- it.name.get_ref().as_slice());
+ structhead: bool) -> fmt::Result {
+ if_ok!(write!(w, "{}{}{}",
+ VisSpace(it.visibility),
+ if structhead {"struct "} else {""},
+ it.name.get_ref().as_slice()));
match g {
- Some(g) => write!(w, "{}", *g),
+ Some(g) => if_ok!(write!(w, "{}", *g)),
None => {}
}
match ty {
doctree::Plain => {
- write!(w, " \\{\n{}", tab);
+ if_ok!(write!(w, " \\{\n{}", tab));
for field in fields.iter() {
match field.inner {
clean::StructFieldItem(ref ty) => {
- write!(w, " {}{}: {},\n{}",
- VisSpace(field.visibility),
- field.name.get_ref().as_slice(),
- ty.type_,
- tab);
+ if_ok!(write!(w, " {}{}: {},\n{}",
+ VisSpace(field.visibility),
+ field.name.get_ref().as_slice(),
+ ty.type_,
+ tab));
}
_ => unreachable!()
}
}
if fields_stripped {
- write!(w, " // some fields omitted\n{}", tab);
+ if_ok!(write!(w, " // some fields omitted\n{}", tab));
}
- write!(w, "\\}");
+ if_ok!(write!(w, "\\}"));
}
doctree::Tuple | doctree::Newtype => {
- write!(w, "(");
+ if_ok!(write!(w, "("));
for (i, field) in fields.iter().enumerate() {
- if i > 0 { write!(w, ", ") }
+ if i > 0 {
+ if_ok!(write!(w, ", "));
+ }
match field.inner {
clean::StructFieldItem(ref field) => {
- write!(w, "{}", field.type_);
+ if_ok!(write!(w, "{}", field.type_));
}
_ => unreachable!()
}
}
- write!(w, ");");
+ if_ok!(write!(w, ");"));
+ }
+ doctree::Unit => {
+ if_ok!(write!(w, ";"));
}
- doctree::Unit => { write!(w, ";"); }
}
+ Ok(())
}
-fn render_methods(w: &mut Writer, it: &clean::Item) {
+fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result {
local_data::get(cache_key, |cache| {
let c = cache.unwrap().get();
match c.impls.find(&it.id) {
@@ -1367,29 +1387,31 @@ fn render_methods(w: &mut Writer, it: &clean::Item) {
let traits = traits.to_owned_vec();
if non_trait.len() > 0 {
- write!(w, "Methods ");
+ if_ok!(write!(w, "Methods "));
for &(ref i, ref dox) in non_trait.move_iter() {
- render_impl(w, i, dox);
+ if_ok!(render_impl(w, i, dox));
}
}
if traits.len() > 0 {
- write!(w, "Trait \
- Implementations ");
+ if_ok!(write!(w, "Trait \
+ Implementations "));
for &(ref i, ref dox) in traits.move_iter() {
- render_impl(w, i, dox);
+ if_ok!(render_impl(w, i, dox));
}
}
}
None => {}
}
+ Ok(())
})
}
-fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
- write!(w, "impl{} ", i.generics);
+fn render_impl(w: &mut Writer, i: &clean::Impl,
+ dox: &Option<~str>) -> fmt::Result {
+ if_ok!(write!(w, "impl{} ", i.generics));
let trait_id = match i.trait_ {
Some(ref ty) => {
- write!(w, "{} for ", *ty);
+ if_ok!(write!(w, "{} for ", *ty));
match *ty {
clean::ResolvedPath { id, .. } => Some(id),
_ => None,
@@ -1397,32 +1419,32 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
}
None => None
};
- write!(w, "{}
", i.for_);
+ if_ok!(write!(w, "{}
", i.for_));
match *dox {
Some(ref dox) => {
- write!(w, "{}
",
- Markdown(dox.as_slice()));
+ if_ok!(write!(w, "{}
",
+ Markdown(dox.as_slice())));
}
None => {}
}
- fn docmeth(w: &mut Writer, item: &clean::Item) -> bool {
- write!(w, "",
- *item.name.get_ref());
- render_method(w, item, false);
- write!(w, "
\n");
+ fn docmeth(w: &mut Writer, item: &clean::Item) -> io::IoResult {
+ if_ok!(write!(w, "",
+ *item.name.get_ref()));
+ if_ok!(render_method(w, item, false));
+ if_ok!(write!(w, "
\n"));
match item.doc_value() {
Some(s) => {
- write!(w, "{}
", Markdown(s));
- true
+ if_ok!(write!(w, "{}
", Markdown(s)));
+ Ok(true)
}
- None => false
+ None => Ok(false)
}
}
- write!(w, "");
+ if_ok!(write!(w, "
"));
for meth in i.methods.iter() {
- if docmeth(w, meth) {
+ if if_ok!(docmeth(w, meth)) {
continue
}
@@ -1431,7 +1453,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
None => continue,
Some(id) => id,
};
- local_data::get(cache_key, |cache| {
+ if_ok!(local_data::get(cache_key, |cache| {
let cache = cache.unwrap().get();
match cache.traits.find(&trait_id) {
Some(t) => {
@@ -1440,9 +1462,9 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
Some(method) => {
match method.item().doc_value() {
Some(s) => {
- write!(w,
- "
{}
",
- Markdown(s));
+ if_ok!(write!(w,
+ "
{}
",
+ Markdown(s)));
}
None => {}
}
@@ -1452,7 +1474,8 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
}
None => {}
}
- })
+ Ok(())
+ }))
}
// If we've implemented a trait, then also emit documentation for all
@@ -1460,7 +1483,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
match trait_id {
None => {}
Some(id) => {
- local_data::get(cache_key, |cache| {
+ if_ok!(local_data::get(cache_key, |cache| {
let cache = cache.unwrap().get();
match cache.traits.find(&id) {
Some(t) => {
@@ -1471,50 +1494,56 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
None => {}
}
- docmeth(w, method.item());
+ if_ok!(docmeth(w, method.item()));
}
}
None => {}
}
- })
+ Ok(())
+ }))
}
}
- write!(w, "
");
+ if_ok!(write!(w, "
"));
+ Ok(())
}
-fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) {
- write!(w, "type {}{} = {}; ",
- it.name.get_ref().as_slice(),
- t.generics,
- t.type_);
+fn item_typedef(w: &mut Writer, it: &clean::Item,
+ t: &clean::Typedef) -> fmt::Result {
+ if_ok!(write!(w, "type {}{} = {}; ",
+ it.name.get_ref().as_slice(),
+ t.generics,
+ t.type_));
- document(w, it);
+ document(w, it)
}
impl<'a> fmt::Show for Sidebar<'a> {
- fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) {
+ fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
let cx = s.cx;
let it = s.item;
- write!(fmt.buf, "");
+ if_ok!(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;::") }
- write!(fmt.buf, "{} ",
- cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name);
+ if i > 0 {
+ if_ok!(write!(fmt.buf, "&\\#8203;::"));
+ }
+ if_ok!(write!(fmt.buf, "{} ",
+ cx.root_path.slice_to((cx.current.len() - i - 1) * 3),
+ *name));
}
- write!(fmt.buf, "
");
+ if_ok!(write!(fmt.buf, "
"));
fn block(w: &mut Writer, short: &str, longty: &str,
- cur: &clean::Item, cx: &Context) {
+ cur: &clean::Item, cx: &Context) -> fmt::Result {
let items = match cx.sidebar.find_equiv(&short) {
Some(items) => items.as_slice(),
- None => return
+ None => return Ok(())
};
- write!(w, "{} ", short, longty);
+ if_ok!(write!(w, "
");
+ if_ok!(write!(w, "
"));
+ Ok(())
}
- block(fmt.buf, "mod", "Modules", it, cx);
- block(fmt.buf, "struct", "Structs", it, cx);
- block(fmt.buf, "enum", "Enums", it, cx);
- block(fmt.buf, "trait", "Traits", it, cx);
- block(fmt.buf, "fn", "Functions", it, cx);
+ if_ok!(block(fmt.buf, "mod", "Modules", it, cx));
+ if_ok!(block(fmt.buf, "struct", "Structs", it, cx));
+ if_ok!(block(fmt.buf, "enum", "Enums", it, cx));
+ if_ok!(block(fmt.buf, "trait", "Traits", it, cx));
+ if_ok!(block(fmt.buf, "fn", "Functions", it, cx));
+ Ok(())
}
}
@@ -1557,7 +1588,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> {
}
impl<'a> fmt::Show for Source<'a> {
- fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) {
+ fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
let Source(s) = *s;
let lines = s.lines().len();
let mut cols = 0;
@@ -1566,13 +1597,14 @@ impl<'a> fmt::Show for Source<'a> {
cols += 1;
tmp /= 10;
}
- write!(fmt.buf, "");
+ if_ok!(write!(fmt.buf, ""));
for i in range(1, lines + 1) {
- write!(fmt.buf, "{0:1$u} \n", i, cols);
+ if_ok!(write!(fmt.buf, "{0:1$u} \n", i, cols));
}
- write!(fmt.buf, " ");
- write!(fmt.buf, "");
- write!(fmt.buf, "{}", Escape(s.as_slice()));
- write!(fmt.buf, " ");
+ if_ok!(write!(fmt.buf, " "));
+ if_ok!(write!(fmt.buf, ""));
+ if_ok!(write!(fmt.buf, "{}", Escape(s.as_slice())));
+ if_ok!(write!(fmt.buf, " "));
+ Ok(())
}
}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index f7a484e3d3e00..fe989279e7147 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -162,10 +162,16 @@ pub fn main_args(args: &[~str]) -> int {
let output = matches.opt_str("o").map(|s| Path::new(s));
match matches.opt_str("w") {
Some(~"html") | None => {
- html::render::run(crate, output.unwrap_or(Path::new("doc")))
+ match html::render::run(crate, output.unwrap_or(Path::new("doc"))) {
+ Ok(()) => {}
+ Err(e) => fail!("failed to generate documentation: {}", e),
+ }
}
Some(~"json") => {
- json_output(crate, res, output.unwrap_or(Path::new("doc.json")))
+ match json_output(crate, res, output.unwrap_or(Path::new("doc.json"))) {
+ Ok(()) => {}
+ Err(e) => fail!("failed to write json: {}", e),
+ }
}
Some(s) => {
println!("unknown output format: {}", s);
@@ -276,8 +282,8 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
/// run over the deserialized output.
fn json_input(input: &str) -> Result {
let mut 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 {}: {}", input, e)),
};
match json::from_reader(&mut input) {
Err(s) => Err(s.to_str()),
@@ -312,7 +318,8 @@ fn json_input(input: &str) -> Result {
/// Outputs the crate/plugin json as a giant json blob at the specified
/// destination.
-fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
+fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson],
+ dst: Path) -> io::IoResult<()> {
// {
// "schema": version,
// "crate": { parsed crate ... },
@@ -340,6 +347,7 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
json.insert(~"crate", crate_json);
json.insert(~"plugins", json::Object(plugins_json));
- let mut file = File::create(&dst).unwrap();
- json::Object(json).to_writer(&mut file);
+ let mut file = if_ok!(File::create(&dst));
+ if_ok!(json::Object(json).to_writer(&mut file));
+ Ok(())
}
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 12874d1b502a2..9e3b217f69f68 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -127,8 +127,8 @@ fn runtest(test: &str, cratename: &str, libs: HashSet) {
let exe = outdir.path().join("rust_out");
let out = run::process_output(exe.as_str().unwrap(), []);
match out {
- None => fail!("couldn't run the test"),
- Some(out) => {
+ Err(e) => fail!("couldn't run the test: {}", e),
+ Ok(out) => {
if !out.status.success() {
fail!("test executable failed:\n{}",
str::from_utf8(out.error));
diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs
index 31afa7b5c7c80..2cef2664c2fc4 100644
--- a/src/librustuv/file.rs
+++ b/src/librustuv/file.rs
@@ -140,9 +140,9 @@ impl FsRequest {
let mut paths = ~[];
let path = CString::new(path.with_ref(|p| p), false);
let parent = Path::new(path);
- c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
- Some(req.get_result() as uint),
- |rel| {
+ let _ = c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
+ Some(req.get_result() as uint),
+ |rel| {
let p = rel.as_bytes();
paths.push(parent.join(p.slice_to(rel.len())));
});
@@ -378,7 +378,8 @@ impl Drop for FileWatcher {
rtio::CloseAsynchronously => {
unsafe {
let req = uvll::malloc_req(uvll::UV_FS);
- uvll::uv_fs_close(self.loop_.handle, req, self.fd, close_cb);
+ assert_eq!(uvll::uv_fs_close(self.loop_.handle, req,
+ self.fd, close_cb), 0);
}
extern fn close_cb(req: *uvll::uv_fs_t) {
diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs
index 8d3e71312cd95..a2f3457a9430c 100644
--- a/src/librustuv/homing.rs
+++ b/src/librustuv/homing.rs
@@ -176,7 +176,7 @@ mod test {
});
let task = pool.task(TaskOpts::new(), proc() {
- port.recv();
+ drop(port.recv());
});
pool.spawn_sched().send(sched::TaskFromFriend(task));
@@ -197,7 +197,7 @@ mod test {
let listener = UdpWatcher::bind(local_loop(), addr2);
chan.send((listener.unwrap(), addr1));
let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
- listener.sendto([1, 2, 3, 4], addr2);
+ listener.sendto([1, 2, 3, 4], addr2).unwrap();
});
let task = pool.task(TaskOpts::new(), proc() {
diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs
index 3d6e81d0d6fd5..dafd3dbe1bc96 100644
--- a/src/librustuv/idle.rs
+++ b/src/librustuv/idle.rs
@@ -52,7 +52,7 @@ impl IdleWatcher {
let data = uvll::get_data_for_uv_handle(handle);
let f: ~proc() = cast::transmute(data);
(*f)();
- uvll::uv_idle_stop(handle);
+ assert_eq!(uvll::uv_idle_stop(handle), 0);
uvll::uv_close(handle, close_cb);
}
}
@@ -122,7 +122,7 @@ mod test {
}
}
};
- task.wake().map(|t| t.reawaken(true));
+ let _ = task.wake().map(|t| t.reawaken(true));
}
}
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index 0b889e17a445e..f945c0972ca39 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -40,6 +40,7 @@ via `close` and `delete` methods.
#[crate_type = "dylib"];
#[feature(macro_rules)];
+#[deny(unused_result, unused_must_use)];
#[cfg(test)] extern mod green;
@@ -207,7 +208,7 @@ fn wait_until_woken_after(slot: *mut Option, f: ||) {
fn wakeup(slot: &mut Option) {
assert!(slot.is_some());
- slot.take_unwrap().wake().map(|t| t.reawaken(true));
+ let _ = slot.take_unwrap().wake().map(|t| t.reawaken(true));
}
pub struct Request {
@@ -276,7 +277,7 @@ impl Loop {
pub fn wrap(handle: *uvll::uv_loop_t) -> Loop { Loop { handle: handle } }
pub fn run(&mut self) {
- unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) };
+ assert_eq!(unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) }, 0);
}
pub fn close(&mut self) {
diff --git a/src/librustuv/macros.rs b/src/librustuv/macros.rs
index 6c8c16784a12b..75b68e3a52885 100644
--- a/src/librustuv/macros.rs
+++ b/src/librustuv/macros.rs
@@ -33,14 +33,15 @@ pub fn dumb_println(args: &fmt::Arguments) {
struct Stderr;
impl io::Writer for Stderr {
- fn write(&mut self, data: &[u8]) {
- unsafe {
+ fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
+ let _ = unsafe {
libc::write(libc::STDERR_FILENO,
data.as_ptr() as *libc::c_void,
- data.len() as libc::size_t);
- }
+ data.len() as libc::size_t)
+ };
+ Ok(()) // just ignore the errors
}
}
let mut w = Stderr;
- fmt::writeln(&mut w as &mut io::Writer, args);
+ let _ = fmt::writeln(&mut w as &mut io::Writer, args);
}
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index 8919ecfa97ef4..5461fc6272d35 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -953,11 +953,11 @@ mod test {
spawn(proc() {
let port2 = port.recv();
let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
- stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
- stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
+ stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
+ stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
port2.recv();
- stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
- stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
+ stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
+ stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
port2.recv();
});
@@ -1008,7 +1008,7 @@ mod test {
while stream.is_err() {
stream = TcpWatcher::connect(local_loop(), addr);
}
- stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]);
+ stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
}
#[should_fail] #[test]
@@ -1028,7 +1028,7 @@ mod test {
let w = TcpListener::bind(local_loop(), addr).unwrap();
let mut w = w.listen().unwrap();
chan.send(());
- w.accept();
+ drop(w.accept().unwrap());
});
port.recv();
let _w = TcpWatcher::connect(local_loop(), addr).unwrap();
diff --git a/src/librustuv/pipe.rs b/src/librustuv/pipe.rs
index cfe86d739abcf..a021a13e2d98d 100644
--- a/src/librustuv/pipe.rs
+++ b/src/librustuv/pipe.rs
@@ -306,7 +306,7 @@ mod tests {
let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
let mut p = p.listen().unwrap();
chan.send(());
- p.accept();
+ drop(p.accept().unwrap());
});
port.recv();
let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
diff --git a/src/librustuv/queue.rs b/src/librustuv/queue.rs
index 32f8d8532a209..0e1c4225caa93 100644
--- a/src/librustuv/queue.rs
+++ b/src/librustuv/queue.rs
@@ -67,7 +67,7 @@ extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
loop {
match state.consumer.pop() {
mpsc::Data(Task(task)) => {
- task.wake().map(|t| t.reawaken(true));
+ let _ = task.wake().map(|t| t.reawaken(true));
}
mpsc::Data(Increment) => unsafe {
if state.refcnt == 0 {
diff --git a/src/librustuv/signal.rs b/src/librustuv/signal.rs
index 8cb0c1f0a52d7..2fcc61be79bdf 100644
--- a/src/librustuv/signal.rs
+++ b/src/librustuv/signal.rs
@@ -86,7 +86,7 @@ mod test {
chan);
spawn(proc() {
- port.try_recv();
+ let _ = port.recv_opt();
});
// when we drop the SignalWatcher we're going to destroy the channel,
diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs
index aeda1a45175ea..792414238fdaa 100644
--- a/src/librustuv/timer.rs
+++ b/src/librustuv/timer.rs
@@ -138,11 +138,11 @@ extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
match timer.action.take_unwrap() {
WakeTask(task) => {
- task.wake().map(|t| t.reawaken(true));
+ let _ = task.wake().map(|t| t.reawaken(true));
}
- SendOnce(chan) => { chan.try_send(()); }
+ SendOnce(chan) => { let _ = chan.try_send(()); }
SendMany(chan, id) => {
- chan.try_send(());
+ let _ = chan.try_send(());
// Note that the above operation could have performed some form of
// scheduling. This means that the timer may have decided to insert
@@ -246,7 +246,7 @@ mod test {
let timer_port = timer.period(1000);
spawn(proc() {
- timer_port.recv_opt();
+ let _ = timer_port.recv_opt();
});
// when we drop the TimerWatcher we're going to destroy the channel,
@@ -260,10 +260,10 @@ mod test {
let timer_port = timer.period(1000);
spawn(proc() {
- timer_port.recv_opt();
+ let _ = timer_port.recv_opt();
});
- timer.oneshot(1);
+ drop(timer.oneshot(1));
}
#[test]
fn reset_doesnt_switch_tasks2() {
@@ -272,7 +272,7 @@ mod test {
let timer_port = timer.period(1000);
spawn(proc() {
- timer_port.recv_opt();
+ let _ = timer_port.recv_opt();
});
timer.sleep(1);
@@ -299,7 +299,7 @@ mod test {
#[test]
fn receiver_goes_away_oneshot() {
let mut timer1 = TimerWatcher::new(local_loop());
- timer1.oneshot(1);
+ drop(timer1.oneshot(1));
let mut timer2 = TimerWatcher::new(local_loop());
// while sleeping, the prevous timer should fire and not have its
// callback do something terrible.
@@ -309,7 +309,7 @@ mod test {
#[test]
fn receiver_goes_away_period() {
let mut timer1 = TimerWatcher::new(local_loop());
- timer1.period(1);
+ drop(timer1.period(1));
let mut timer2 = TimerWatcher::new(local_loop());
// while sleeping, the prevous timer should fire and not have its
// callback do something terrible.
diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs
index e0bff059b0c91..8a8ef4a41ec4e 100644
--- a/src/librustuv/uvio.rs
+++ b/src/librustuv/uvio.rs
@@ -71,7 +71,7 @@ impl Drop for UvEventLoop {
// after the loop has been closed because during the closing of the loop
// the handle is required to be used apparently.
let handle = self.uvio.handle_pool.get_ref().handle();
- self.uvio.handle_pool.take();
+ drop(self.uvio.handle_pool.take());
self.uvio.loop_.close();
unsafe { uvll::free_handle(handle) }
}
diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs
index 7b1a6055542d0..bccebeaa79f6b 100644
--- a/src/libstd/comm/mod.rs
+++ b/src/libstd/comm/mod.rs
@@ -1252,7 +1252,7 @@ mod test {
spawn(proc() {
let _p = port;
});
- task::try(proc() {
+ let _ = task::try(proc() {
chan.send(1);
});
}
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index a17a030f4f792..06737e22007e4 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -163,9 +163,10 @@ method of the signature:
```rust
# use std;
+# mod fmt { pub type Result = (); }
# struct T;
# trait SomeName {
-fn fmt(value: &T, f: &mut std::fmt::Formatter);
+fn fmt(value: &T, f: &mut std::fmt::Formatter) -> fmt::Result;
# }
```
@@ -174,7 +175,14 @@ emit output into the `f.buf` stream. It is up to each format trait
implementation to correctly adhere to the requested formatting parameters. The
values of these parameters will be listed in the fields of the `Formatter`
struct. In order to help with this, the `Formatter` struct also provides some
-helper methods. An example of implementing the formatting traits would look
+helper methods.
+
+Additionally, the return value of this function is `fmt::Result` which is a
+typedef to `Result<(), IoError>` (also known as `IoError<()>`). Formatting
+implementations should ensure that they return errors from `write!` correctly
+(propagating errors upward).
+
+An example of implementing the formatting traits would look
like:
```rust
@@ -187,7 +195,7 @@ struct Vector2D {
}
impl fmt::Show for Vector2D {
- fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
+ fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
// The `f.buf` value is of the type `&mut io::Writer`, which is what th
// write! macro is expecting. Note that this formatting ignores the
// various flags provided to format strings.
@@ -198,7 +206,7 @@ impl fmt::Show for Vector2D {
// Different traits allow different forms of output of a type. The meaning of
// this format is to print the magnitude of a vector.
impl fmt::Binary for Vector2D {
- fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
+ fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64;
let magnitude = magnitude.sqrt();
@@ -207,7 +215,7 @@ impl fmt::Binary for Vector2D {
// for details, and the function `pad` can be used to pad strings.
let decimals = f.precision.unwrap_or(3);
let string = f64::to_str_exact(magnitude, decimals);
- f.pad_integral(string.as_bytes(), "", true);
+ f.pad_integral(string.as_bytes(), "", true)
}
}
@@ -242,6 +250,7 @@ strings and instead directly write the output. Under the hood, this function is
actually invoking the `write` function defined in this module. Example usage is:
```rust
+# #[allow(unused_must_use)];
use std::io;
let mut w = io::MemWriter::new();
@@ -468,16 +477,20 @@ will look like `"\\{"`.
*/
-#[cfg(not(stage0))]
-use prelude::*;
-
use cast;
use char::Char;
+use container::Container;
use io::MemWriter;
use io;
-use str;
+use iter::{Iterator, range};
+use num::Signed;
+use option::{Option,Some,None};
use repr;
+use result::{Ok, Err};
+use str::StrSlice;
+use str;
use util;
+use vec::ImmutableVector;
use vec;
// NOTE this is just because the `prelude::*` import above includes
@@ -485,22 +498,11 @@ use vec;
#[cfg(stage0)]
pub use Default = fmt::Show; // export required for `format!()` etc.
-#[cfg(stage0)]
-use container::Container;
-#[cfg(stage0)]
-use iter::{Iterator, range};
-#[cfg(stage0)]
-use option::{Option,Some,None};
-#[cfg(stage0)]
-use vec::ImmutableVector;
-#[cfg(stage0)]
-use str::StrSlice;
-#[cfg(stage0)]
-use num::Signed;
-
pub mod parse;
pub mod rt;
+pub type Result = io::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.
@@ -527,7 +529,7 @@ pub struct Formatter<'a> {
/// 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<'a> {
- priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
+ priv formatter: extern "Rust" fn(&util::Void, &mut Formatter) -> Result,
priv value: &'a util::Void,
}
@@ -561,50 +563,50 @@ pub struct Arguments<'a> {
/// 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 Show { fn fmt(&Self, &mut Formatter); }
+pub trait Show { 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; }
/// Format trait for the `e` character
#[allow(missing_doc)]
-pub trait LowerExp { fn fmt(&Self, &mut Formatter); }
+pub trait LowerExp { fn fmt(&Self, &mut Formatter) -> Result; }
/// Format trait for the `E` character
#[allow(missing_doc)]
-pub trait UpperExp { fn fmt(&Self, &mut Formatter); }
+pub trait UpperExp { fn fmt(&Self, &mut Formatter) -> Result; }
// FIXME #11938 - UFCS would make us able call the above methods
// directly Show::show(x, fmt).
@@ -617,7 +619,7 @@ macro_rules! uniform_fn_call_workaround {
($( $name: ident, $trait_: ident; )*) => {
$(
#[doc(hidden)]
- pub fn $name(x: &T, fmt: &mut Formatter) {
+ pub fn $name(x: &T, fmt: &mut Formatter) -> Result {
$trait_::fmt(x, fmt)
}
)*
@@ -653,21 +655,22 @@ uniform_fn_call_workaround! {
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::fmt;
/// use std::io;
///
/// let w = &mut io::stdout() as &mut io::Writer;
-/// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world");
+/// 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 {
+ let first = unsafe { write_unsafe(output, args.fmt, args.args) };
+ first.and_then(|()| output.write(['\n' as u8]))
}
/// The `write_unsafe` function takes an output stream, a precompiled format
@@ -692,7 +695,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,
@@ -704,8 +707,9 @@ pub unsafe fn write_unsafe(output: &mut io::Writer,
curarg: args.iter(),
};
for piece in fmt.iter() {
- formatter.run(piece, None);
+ if_ok!(formatter.run(piece, None));
}
+ Ok(())
}
/// The format function takes a precompiled format string and a list of
@@ -752,7 +756,7 @@ pub fn format(args: &Arguments) -> ~str {
/// format string.
pub unsafe fn format_unsafe(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
let mut output = MemWriter::new();
- write_unsafe(&mut output as &mut io::Writer, fmt, args);
+ write_unsafe(&mut output as &mut io::Writer, fmt, args).unwrap();
return str::from_utf8_owned(output.unwrap()).unwrap();
}
@@ -762,10 +766,10 @@ impl<'a> Formatter<'a> {
// 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;
@@ -782,8 +786,8 @@ impl<'a> Formatter<'a> {
// 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)
}
}
}
@@ -804,7 +808,7 @@ impl<'a> Formatter<'a> {
}
}
- 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.
@@ -847,7 +851,7 @@ impl<'a> Formatter<'a> {
}
}
- self.runplural(value, *default);
+ self.runplural(value, *default)
}
// Select is just a matching against the string specified.
@@ -860,24 +864,26 @@ impl<'a> Formatter<'a> {
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)));
}
+ Ok(())
}
}
}
- fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
+ fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) -> Result {
::uint::to_str_bytes(value, 10, |buf| {
let valuestr = str::from_utf8(buf).unwrap();
for piece in pieces.iter() {
- self.run(piece, Some(valuestr));
+ if_ok!(self.run(piece, Some(valuestr)));
}
+ Ok(())
})
}
@@ -899,7 +905,7 @@ impl<'a> Formatter<'a> {
/// 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();
@@ -916,32 +922,32 @@ impl<'a> Formatter<'a> {
let sign = |this: &mut Formatter| {
if !signprinted {
if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive {
- this.buf.write(['+' as u8]);
+ if_ok!(this.buf.write(['+' as u8]));
} else if !positive {
- this.buf.write(['-' as u8]);
+ if_ok!(this.buf.write(['-' as u8]));
}
if this.flags & 1 << (FlagAlternate as uint) != 0 {
- this.buf.write(alternate_prefix.as_bytes());
+ if_ok!(this.buf.write(alternate_prefix.as_bytes()));
}
signprinted = true;
}
+ Ok(())
};
let emit = |this: &mut Formatter| {
- sign(this);
- this.buf.write(s);
+ sign(this).and_then(|()| this.buf.write(s))
};
match self.width {
- None => { emit(self) }
- Some(min) if actual_len >= min => { emit(self) }
+ None => emit(self),
+ Some(min) if actual_len >= min => emit(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)
})
}
}
@@ -958,11 +964,10 @@ impl<'a> Formatter<'a> {
/// 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
@@ -974,8 +979,7 @@ impl<'a> Formatter<'a> {
let char_len = s.char_len();
if char_len >= max {
let nchars = ::cmp::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 => {}
@@ -985,7 +989,7 @@ impl<'a> Formatter<'a> {
match self.width {
// If we're under the maximum length, and there's no minimum length
// requirements, then we can just emit the string
- None => { self.buf.write(s.as_bytes()) }
+ None => self.buf.write(s.as_bytes()),
// If we're under the maximum width, check if we're over the minimum
// width, if so it's as easy as just emitting the string.
@@ -997,7 +1001,7 @@ impl<'a> Formatter<'a> {
// 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())
})
}
}
@@ -1006,29 +1010,30 @@ impl<'a> Formatter<'a> {
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 {
@@ -1055,41 +1060,41 @@ 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<'a, 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)
}
}
macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
$name:ident, $prefix:expr) => {
impl $name for $ty {
- fn fmt(c: &$ty, f: &mut Formatter) {
+ fn fmt(c: &$ty, f: &mut Formatter) -> Result {
::$into::to_str_bytes(*c as $into, $base, |buf| {
- f.pad_integral(buf, $prefix, true);
+ f.pad_integral(buf, $prefix, true)
})
}
}
})
macro_rules! upper_hex(($ty:ident, $into:ident) => {
impl UpperHex for $ty {
- fn fmt(c: &$ty, f: &mut Formatter) {
+ fn fmt(c: &$ty, f: &mut Formatter) -> Result {
::$into::to_str_bytes(*c as $into, 16, |buf| {
- upperhex(buf, f);
+ upperhex(buf, f)
})
}
}
@@ -1097,7 +1102,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 {
@@ -1105,16 +1110,16 @@ 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)
}
macro_rules! integer(($signed:ident, $unsigned:ident) => {
// Signed is special because it actuall emits the negative sign,
// nothing else should do that, however.
impl Signed for $signed {
- fn fmt(c: &$signed, f: &mut Formatter) {
+ fn fmt(c: &$signed, f: &mut Formatter) -> Result {
::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
- f.pad_integral(buf, "", *c >= 0);
+ f.pad_integral(buf, "", *c >= 0)
})
}
}
@@ -1138,35 +1143,35 @@ 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 {
// FIXME: 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)
}
}
impl LowerExp for $ty {
- fn fmt(f: &$ty, fmt: &mut Formatter) {
+ fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
// FIXME: this shouldn't perform an allocation
let s = match fmt.precision {
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false),
None => ::$ty::to_str_exp_digits(f.abs(), 6, false)
};
- fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
+ fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
}
}
impl UpperExp for $ty {
- fn fmt(f: &$ty, fmt: &mut Formatter) {
+ fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
// FIXME: this shouldn't perform an allocation
let s = match fmt.precision {
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true),
None => ::$ty::to_str_exp_digits(f.abs(), 6, true)
};
- fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
+ fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
}
}
})
@@ -1174,39 +1179,41 @@ 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);
+ 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(s)
}
}
}
}
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 Show for various core types
macro_rules! delegate(($ty:ty to $other:ident) => {
impl<'a> Show for $ty {
- fn fmt(me: &$ty, f: &mut Formatter) {
+ fn fmt(me: &$ty, f: &mut Formatter) -> Result {
$other::fmt(me, f)
}
}
@@ -1229,10 +1236,10 @@ delegate!(f32 to Float)
delegate!(f64 to Float)
impl Show 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 Show 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 1444f9b4129d8..4163d1e0c96e8 100644
--- a/src/libstd/hash.rs
+++ b/src/libstd/hash.rs
@@ -27,13 +27,14 @@
#[allow(missing_doc)];
use container::Container;
+use io::{Writer, IoResult};
use iter::Iterator;
+use num::ToStrRadix;
use option::{Some, None};
-use io::Writer;
+use result::Ok;
use str::OwnedStr;
use to_bytes::IterBytes;
use vec::ImmutableVector;
-use num::ToStrRadix;
// Alias `SipState` to `State`.
pub use State = hash::SipState;
@@ -164,7 +165,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;
@@ -180,7 +181,7 @@ impl Writer for SipState {
t += 1;
}
self.ntail += length;
- return;
+ return Ok(())
}
let mut t = 0;
@@ -222,17 +223,14 @@ impl Writer for SipState {
t += 1
}
self.ntail = left;
- }
-
- fn flush(&mut self) {
- // No-op
+ Ok(())
}
}
impl Streaming for SipState {
#[inline]
fn input(&mut self, buf: &[u8]) {
- self.write(buf);
+ self.write(buf).unwrap();
}
#[inline]
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 64e42c5480f28..256f9d325f3ed 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -11,10 +11,11 @@
//! Buffering wrappers for I/O traits
use container::Container;
-use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE};
+use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
use iter::ExactSize;
use num;
-use option::{Option, Some, None};
+use option::{Some, None};
+use result::{Ok, Err};
use vec::{OwnedVector, ImmutableVector, MutableVector};
use vec;
@@ -30,14 +31,13 @@ use vec;
/// ```rust
/// use std::io::{BufferedReader, File};
///
-/// # let _g = ::std::io::ignore_io_error();
/// let file = File::open(&Path::new("message.txt"));
/// let mut reader = BufferedReader::new(file);
///
/// let mut buf = [0, ..100];
/// match reader.read(buf) {
-/// Some(nread) => println!("Read {} bytes", nread),
-/// None => println!("At the end of the file!")
+/// Ok(nread) => println!("Read {} bytes", nread),
+/// Err(e) => println!("error reading: {}", e)
/// }
/// ```
pub struct BufferedReader {
@@ -86,17 +86,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.eof = true; }
- }
+ self.cap = if_ok!(self.inner.read(self.buf));
+ self.pos = 0;
}
- return self.buf.slice(self.pos, self.cap);
+ Ok(self.buf.slice(self.pos, self.cap))
}
fn consume(&mut self, amt: uint) {
@@ -106,18 +101,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();
+ let available = if_ok!(self.fill());
let nread = num::min(available.len(), buf.len());
vec::bytes::copy_memory(buf, available.slice_to(nread));
nread
};
self.pos += nread;
- if nread == 0 && buf.len() != 0 && self.eof {
- return None;
- }
- Some(nread)
+ Ok(nread)
}
}
@@ -128,9 +120,9 @@ impl Reader for BufferedReader {
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::{BufferedWriter, File};
///
-/// # let _g = ::std::io::ignore_io_error();
/// let file = File::open(&Path::new("message.txt"));
/// let mut writer = BufferedWriter::new(file);
///
@@ -161,10 +153,13 @@ impl BufferedWriter {
BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
}
- fn flush_buf(&mut self) {
+ fn flush_buf(&mut self) -> IoResult<()> {
if self.pos != 0 {
- self.inner.write(self.buf.slice_to(self.pos));
+ let ret = self.inner.write(self.buf.slice_to(self.pos));
self.pos = 0;
+ ret
+ } else {
+ Ok(())
}
}
@@ -178,29 +173,30 @@ impl BufferedWriter {
///
/// The buffer is flushed before returning the writer.
pub fn unwrap(mut self) -> W {
- self.flush_buf();
+ // FIXME: is failing the right thing to do if flushing fails?
+ self.flush_buf().unwrap();
self.inner
}
}
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_buf();
+ if_ok!(self.flush_buf());
}
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);
self.pos += buf.len();
+ Ok(())
}
}
- fn flush(&mut self) {
- self.flush_buf();
- self.inner.flush();
+ fn flush(&mut self) -> IoResult<()> {
+ self.flush_buf().and_then(|()| self.inner.flush())
}
}
@@ -234,18 +230,19 @@ impl LineBufferedWriter {
}
impl Writer for LineBufferedWriter {
- fn write(&mut self, buf: &[u8]) {
+ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
match buf.iter().rposition(|&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));
+ if_ok!(self.inner.write(buf.slice_to(i + 1)));
+ if_ok!(self.inner.flush());
+ if_ok!(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() }
}
struct InternalBufferedWriter(BufferedWriter);
@@ -258,7 +255,9 @@ impl InternalBufferedWriter {
}
impl Reader for InternalBufferedWriter {
- fn read(&mut self, buf: &mut [u8]) -> Option { self.get_mut_ref().inner.read(buf) }
+ fn read(&mut self, buf: &mut [u8]) -> IoResult {
+ self.get_mut_ref().inner.read(buf)
+ }
}
/// Wraps a Stream and buffers input and output to and from it
@@ -268,9 +267,9 @@ impl Reader for InternalBufferedWriter {
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::{BufferedStream, File};
///
-/// # let _g = ::std::io::ignore_io_error();
/// let file = File::open(&Path::new("message.txt"));
/// let mut stream = BufferedStream::new(file);
///
@@ -279,8 +278,8 @@ impl Reader for InternalBufferedWriter {
///
/// let mut buf = [0, ..100];
/// match stream.read(buf) {
-/// Some(nread) => println!("Read {} bytes", nread),
-/// None => println!("At the end of the stream!")
+/// Ok(nread) => println!("Read {} bytes", nread),
+/// Err(e) => println!("error reading: {}", e)
/// }
/// ```
pub struct BufferedStream {
@@ -326,17 +325,23 @@ 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)
+ }
}
impl Writer for BufferedStream {
- fn write(&mut self, buf: &[u8]) { self.inner.inner.get_mut_ref().write(buf) }
- fn flush(&mut self) { self.inner.inner.get_mut_ref().flush() }
+ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+ self.inner.inner.get_mut_ref().write(buf)
+ }
+ fn flush(&mut self) -> IoResult<()> {
+ self.inner.inner.get_mut_ref().flush()
+ }
}
#[cfg(test)]
@@ -354,13 +359,13 @@ mod test {
pub struct NullStream;
impl Reader for NullStream {
- fn read(&mut self, _: &mut [u8]) -> Option {
- None
+ fn read(&mut self, _: &mut [u8]) -> io::IoResult {
+ Err(io::standard_error(io::EndOfFile))
}
}
impl Writer for NullStream {
- fn write(&mut self, _: &[u8]) { }
+ fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
}
/// A dummy reader intended at testing short-reads propagation.
@@ -369,8 +374,11 @@ mod test {
}
impl Reader for ShortReader {
- fn read(&mut self, _: &mut [u8]) -> Option {
- self.lengths.shift()
+ fn read(&mut self, _: &mut [u8]) -> io::IoResult {
+ match self.lengths.shift() {
+ Some(i) => Ok(i),
+ None => Err(io::standard_error(io::EndOfFile))
+ }
}
}
@@ -381,24 +389,24 @@ 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);
let mut buf = [0];
let nread = reader.read(buf);
- assert_eq!(Some(1), nread);
+ assert_eq!(Ok(1), nread);
assert_eq!([2], buf);
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);
let nread = reader.read(buf);
- assert_eq!(Some(1), nread);
+ assert_eq!(Ok(1), nread);
assert_eq!([4, 0, 0], buf);
- assert_eq!(None, reader.read(buf));
+ assert!(reader.read(buf).is_err());
}
#[test]
@@ -406,35 +414,35 @@ mod test {
let inner = MemWriter::new();
let mut writer = BufferedWriter::with_capacity(2, inner);
- writer.write([0, 1]);
+ writer.write([0, 1]).unwrap();
assert_eq!([], writer.get_ref().get_ref());
- writer.write([2]);
+ writer.write([2]).unwrap();
assert_eq!([0, 1], writer.get_ref().get_ref());
- writer.write([3]);
+ writer.write([3]).unwrap();
assert_eq!([0, 1], writer.get_ref().get_ref());
- writer.flush();
+ writer.flush().unwrap();
assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
- writer.write([4]);
- writer.write([5]);
+ writer.write([4]).unwrap();
+ writer.write([5]).unwrap();
assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
- writer.write([6]);
+ writer.write([6]).unwrap();
assert_eq!([0, 1, 2, 3, 4, 5],
writer.get_ref().get_ref());
- writer.write([7, 8]);
+ writer.write([7, 8]).unwrap();
assert_eq!([0, 1, 2, 3, 4, 5, 6],
writer.get_ref().get_ref());
- writer.write([9, 10, 11]);
+ writer.write([9, 10, 11]).unwrap();
assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
writer.get_ref().get_ref());
- writer.flush();
+ writer.flush().unwrap();
assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
writer.get_ref().get_ref());
}
@@ -442,7 +450,7 @@ mod test {
#[test]
fn test_buffered_writer_inner_flushes() {
let mut w = BufferedWriter::with_capacity(3, MemWriter::new());
- w.write([0, 1]);
+ w.write([0, 1]).unwrap();
assert_eq!([], w.get_ref().get_ref());
let w = w.unwrap();
assert_eq!([0, 1], w.get_ref());
@@ -455,47 +463,49 @@ mod test {
struct S;
impl io::Writer for S {
- fn write(&mut self, _: &[u8]) {}
+ fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
}
impl io::Reader for S {
- fn read(&mut self, _: &mut [u8]) -> Option { None }
+ fn read(&mut self, _: &mut [u8]) -> io::IoResult {
+ Err(io::standard_error(io::EndOfFile))
+ }
}
let mut stream = BufferedStream::new(S);
let mut buf = [];
- stream.read(buf);
- stream.write(buf);
- stream.flush();
+ assert!(stream.read(buf).is_err());
+ stream.write(buf).unwrap();
+ stream.flush().unwrap();
}
#[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]
fn test_line_buffer() {
let mut writer = LineBufferedWriter::new(MemWriter::new());
- writer.write([0]);
+ writer.write([0]).unwrap();
assert_eq!(writer.get_ref().get_ref(), []);
- writer.write([1]);
+ writer.write([1]).unwrap();
assert_eq!(writer.get_ref().get_ref(), []);
- writer.flush();
+ writer.flush().unwrap();
assert_eq!(writer.get_ref().get_ref(), [0, 1]);
- writer.write([0, '\n' as u8, 1, '\n' as u8, 2]);
+ writer.write([0, '\n' as u8, 1, '\n' as u8, 2]).unwrap();
assert_eq!(writer.get_ref().get_ref(),
[0, 1, 0, '\n' as u8, 1, '\n' as u8]);
- writer.flush();
+ writer.flush().unwrap();
assert_eq!(writer.get_ref().get_ref(),
[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2]);
- writer.write([3, '\n' as u8]);
+ writer.write([3, '\n' as u8]).unwrap();
assert_eq!(writer.get_ref().get_ref(),
[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2, 3, '\n' as u8]);
}
@@ -504,10 +514,10 @@ mod test {
fn test_read_line() {
let in_buf = MemReader::new(bytes!("a\nb\nc").to_owned());
let mut reader = BufferedReader::with_capacity(2, in_buf);
- assert_eq!(reader.read_line(), Some(~"a\n"));
- assert_eq!(reader.read_line(), Some(~"b\n"));
- assert_eq!(reader.read_line(), Some(~"c"));
- assert_eq!(reader.read_line(), None);
+ assert_eq!(reader.read_line(), Ok(~"a\n"));
+ assert_eq!(reader.read_line(), Ok(~"b\n"));
+ assert_eq!(reader.read_line(), Ok(~"c"));
+ assert!(reader.read_line().is_err());
}
#[test]
@@ -526,20 +536,20 @@ mod test {
let inner = ShortReader{lengths: ~[0, 1, 2, 0, 1, 0]};
let mut reader = BufferedReader::new(inner);
let mut buf = [0, 0];
- assert_eq!(reader.read(buf), Some(0));
- assert_eq!(reader.read(buf), Some(1));
- assert_eq!(reader.read(buf), Some(2));
- assert_eq!(reader.read(buf), Some(0));
- assert_eq!(reader.read(buf), Some(1));
- assert_eq!(reader.read(buf), Some(0));
- assert_eq!(reader.read(buf), None);
+ assert_eq!(reader.read(buf), Ok(0));
+ assert_eq!(reader.read(buf), Ok(1));
+ assert_eq!(reader.read(buf), Ok(2));
+ assert_eq!(reader.read(buf), Ok(0));
+ assert_eq!(reader.read(buf), Ok(1));
+ assert_eq!(reader.read(buf), Ok(0));
+ assert!(reader.read(buf).is_err());
}
#[test]
fn read_char_buffered() {
let buf = [195u8, 159u8];
let mut reader = BufferedReader::with_capacity(1, BufReader::new(buf));
- assert_eq!(reader.read_char(), Some('ß'));
+ assert_eq!(reader.read_char(), Ok('ß'));
}
#[bench]
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index 1eaa752d2a31a..6ed588ac69fd4 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -14,7 +14,7 @@ use comm::{Port, Chan};
use cmp;
use io;
use option::{None, Option, Some};
-use super::{Reader, Writer};
+use super::{Reader, Writer, IoResult};
use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
/// Allows reading from a port.
@@ -49,7 +49,7 @@ impl PortReader {
}
impl Reader for PortReader {
- fn read(&mut self, buf: &mut [u8]) -> Option {
+ fn read(&mut self, buf: &mut [u8]) -> IoResult {
let mut num_read = 0;
loop {
match self.buf {
@@ -71,10 +71,9 @@ impl Reader for PortReader {
self.closed = self.buf.is_none();
}
if self.closed && num_read == 0 {
- io::io_error::cond.raise(io::standard_error(io::EndOfFile));
- None
+ Err(io::standard_error(io::EndOfFile))
} else {
- Some(num_read)
+ Ok(num_read)
}
}
}
@@ -98,13 +97,15 @@ impl ChanWriter {
}
impl Writer for ChanWriter {
- fn write(&mut self, buf: &[u8]) {
+ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
if !self.chan.try_send(buf.to_owned()) {
- io::io_error::cond.raise(io::IoError {
+ Err(io::IoError {
kind: io::BrokenPipe,
desc: "Pipe closed",
detail: None
- });
+ })
+ } else {
+ Ok(())
}
}
}
@@ -132,36 +133,28 @@ mod test {
let mut buf = ~[0u8, ..3];
- assert_eq!(Some(0), reader.read([]));
+ assert_eq!(Ok(0), reader.read([]));
- assert_eq!(Some(3), reader.read(buf));
+ assert_eq!(Ok(3), reader.read(buf));
assert_eq!(~[1,2,3], buf);
- assert_eq!(Some(3), reader.read(buf));
+ assert_eq!(Ok(3), reader.read(buf));
assert_eq!(~[4,5,6], buf);
- assert_eq!(Some(2), reader.read(buf));
+ assert_eq!(Ok(2), reader.read(buf));
assert_eq!(~[7,8,6], buf);
- let mut err = None;
- let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
- err = Some(k)
- }).inside(|| {
- reader.read(buf)
- });
- assert_eq!(Some(io::EndOfFile), err);
- assert_eq!(None, result);
+ match reader.read(buf) {
+ Ok(..) => fail!(),
+ Err(e) => assert_eq!(e.kind, io::EndOfFile),
+ }
assert_eq!(~[7,8,6], buf);
// Ensure it continues to fail in the same way.
- err = None;
- let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
- err = Some(k)
- }).inside(|| {
- reader.read(buf)
- });
- assert_eq!(Some(io::EndOfFile), err);
- assert_eq!(None, result);
+ match reader.read(buf) {
+ Ok(..) => fail!(),
+ Err(e) => assert_eq!(e.kind, io::EndOfFile),
+ }
assert_eq!(~[7,8,6], buf);
}
@@ -169,18 +162,15 @@ mod test {
fn test_chan_writer() {
let (port, chan) = Chan::new();
let mut writer = ChanWriter::new(chan);
- writer.write_be_u32(42);
+ writer.write_be_u32(42).unwrap();
let wanted = ~[0u8, 0u8, 0u8, 42u8];
let got = task::try(proc() { port.recv() }).unwrap();
assert_eq!(wanted, got);
- let mut err = None;
- io::io_error::cond.trap(|io::IoError { kind, .. } | {
- err = Some(kind)
- }).inside(|| {
- writer.write_u8(1)
- });
- assert_eq!(Some(io::BrokenPipe), err);
+ match writer.write_u8(1) {
+ Ok(..) => fail!(),
+ Err(e) => assert_eq!(e.kind, io::BrokenPipe),
+ }
}
}
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 548dc3efe92f0..49d51cbb26fc8 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -46,7 +46,7 @@ impl<'r, R: Reader> Bytes<'r, R> {
impl<'r, R: Reader> Iterator for Bytes<'r, R> {
#[inline]
fn next(&mut self) -> Option {
- self.reader.read_byte()
+ self.reader.read_byte().ok()
}
}
@@ -125,23 +125,22 @@ pub fn u64_from_be_bytes(data: &[u8],
#[cfg(test)]
mod test {
- use unstable::finally::Finally;
use prelude::*;
+ use io;
use io::{MemReader, MemWriter};
- use io::{io_error, placeholder_error};
struct InitialZeroByteReader {
count: int,
}
impl Reader for InitialZeroByteReader {
- fn read(&mut self, buf: &mut [u8]) -> Option {
+ fn read(&mut self, buf: &mut [u8]) -> io::IoResult {
if self.count == 0 {
self.count = 1;
- Some(0)
+ Ok(0)
} else {
buf[0] = 10;
- Some(1)
+ Ok(1)
}
}
}
@@ -149,17 +148,16 @@ mod test {
struct EofReader;
impl Reader for EofReader {
- fn read(&mut self, _: &mut [u8]) -> Option {
- None
+ fn read(&mut self, _: &mut [u8]) -> io::IoResult {
+ Err(io::standard_error(io::EndOfFile))
}
}
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]) -> io::IoResult {
+ Err(io::standard_error(io::InvalidInput))
}
}
@@ -168,16 +166,16 @@ mod test {
}
impl Reader for PartialReader {
- fn read(&mut self, buf: &mut [u8]) -> Option {
+ fn read(&mut self, buf: &mut [u8]) -> io::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)
}
}
}
@@ -187,14 +185,13 @@ mod test {
}
impl Reader for ErroringLaterReader {
- fn read(&mut self, buf: &mut [u8]) -> Option {
+ fn read(&mut self, buf: &mut [u8]) -> io::IoResult {
if self.count == 0 {
self.count = 1;
buf[0] = 10;
- Some(1)
+ Ok(1)
} else {
- io_error::cond.raise(placeholder_error());
- None
+ Err(io::standard_error(io::InvalidInput))
}
}
}
@@ -204,19 +201,19 @@ mod test {
}
impl Reader for ThreeChunkReader {
- fn read(&mut self, buf: &mut [u8]) -> Option {
+ fn read(&mut self, buf: &mut [u8]) -> io::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(io::standard_error(io::EndOfFile))
}
}
}
@@ -225,7 +222,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]
@@ -234,24 +231,21 @@ 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);
- });
+ let byte = reader.read_byte();
+ assert!(byte.is_err());
}
#[test]
@@ -267,23 +261,21 @@ mod test {
fn bytes_eof() {
let mut reader = EofReader;
let byte = reader.bytes().next();
- assert!(byte == None);
+ assert!(byte.is_none());
}
#[test]
fn bytes_error() {
let mut reader = ErroringReader;
let mut it = reader.bytes();
- io_error::cond.trap(|_| ()).inside(|| {
- let byte = it.next();
- assert!(byte == None);
- })
+ let byte = it.next();
+ assert!(byte.is_none());
}
#[test]
fn read_bytes() {
let mut reader = MemReader::new(~[10, 11, 12, 13]);
- let bytes = reader.read_bytes(4);
+ let bytes = reader.read_bytes(4).unwrap();
assert!(bytes == ~[10, 11, 12, 13]);
}
@@ -292,24 +284,21 @@ mod test {
let mut reader = PartialReader {
count: 0,
};
- let bytes = reader.read_bytes(4);
+ let bytes = reader.read_bytes(4).unwrap();
assert!(bytes == ~[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]);
- })
+ assert!(reader.read_bytes(4).is_err());
}
#[test]
fn push_bytes() {
let mut reader = MemReader::new(~[10, 11, 12, 13]);
let mut buf = ~[8, 9];
- reader.push_bytes(&mut buf, 4);
+ reader.push_bytes(&mut buf, 4).unwrap();
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
}
@@ -319,7 +308,7 @@ mod test {
count: 0,
};
let mut buf = ~[8, 9];
- reader.push_bytes(&mut buf, 4);
+ reader.push_bytes(&mut buf, 4).unwrap();
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
}
@@ -327,11 +316,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]);
- })
+ assert!(reader.push_bytes(&mut buf, 4).is_err());
+ assert!(buf == ~[8, 9, 10, 11]);
}
#[test]
@@ -340,38 +326,16 @@ mod test {
count: 0,
};
let mut buf = ~[8, 9];
- io_error::cond.trap(|_| { } ).inside(|| {
- reader.push_bytes(&mut buf, 4);
- });
+ assert!(reader.push_bytes(&mut buf, 4).is_err());
assert!(buf == ~[8, 9, 10]);
}
- #[test]
- #[should_fail]
- #[ignore] // borrow issues with RefCell
- fn push_bytes_fail_reset_len() {
- // push_bytes unsafely sets the vector length. This is testing that
- // upon failure the length is reset correctly.
- let _reader = ErroringLaterReader {
- count: 0,
- };
- // FIXME (#7049): Figure out some other way to do this.
- //let buf = RefCell::new(~[8, 9]);
- (|| {
- //reader.push_bytes(buf.borrow_mut().get(), 4);
- }).finally(|| {
- // NB: Using rtassert here to trigger abort on failure since this is a should_fail test
- // FIXME: #7049 This fails because buf is still borrowed
- //rtassert!(buf.borrow().get() == ~[8, 9, 10]);
- })
- }
-
#[test]
fn read_to_end() {
let mut reader = ThreeChunkReader {
count: 0,
};
- let buf = reader.read_to_end();
+ let buf = reader.read_to_end().unwrap();
assert!(buf == ~[10, 11, 12, 13]);
}
@@ -381,7 +345,7 @@ mod test {
let mut reader = ThreeChunkReader {
count: 0,
};
- let buf = reader.read_to_end();
+ let buf = reader.read_to_end().unwrap();
assert!(buf == ~[10, 11]);
}
@@ -391,12 +355,12 @@ mod test {
let mut writer = MemWriter::new();
for i in uints.iter() {
- writer.write_le_u64(*i);
+ writer.write_le_u64(*i).unwrap();
}
let mut reader = MemReader::new(writer.unwrap());
for i in uints.iter() {
- assert!(reader.read_le_u64() == *i);
+ assert!(reader.read_le_u64().unwrap() == *i);
}
}
@@ -407,12 +371,12 @@ mod test {
let mut writer = MemWriter::new();
for i in uints.iter() {
- writer.write_be_u64(*i);
+ writer.write_be_u64(*i).unwrap();
}
let mut reader = MemReader::new(writer.unwrap());
for i in uints.iter() {
- assert!(reader.read_be_u64() == *i);
+ assert!(reader.read_be_u64().unwrap() == *i);
}
}
@@ -422,14 +386,14 @@ mod test {
let mut writer = MemWriter::new();
for i in ints.iter() {
- writer.write_be_i32(*i);
+ writer.write_be_i32(*i).unwrap();
}
let mut reader = MemReader::new(writer.unwrap());
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).unwrap() == *i as i64);
}
}
@@ -439,10 +403,10 @@ mod test {
let buf = ~[0x41, 0x02, 0x00, 0x00];
let mut writer = MemWriter::new();
- writer.write(buf);
+ writer.write(buf).unwrap();
let mut reader = MemReader::new(writer.unwrap());
- let f = reader.read_be_f32();
+ let f = reader.read_be_f32().unwrap();
assert!(f == 8.1250);
}
@@ -451,12 +415,12 @@ mod test {
let f:f32 = 8.1250;
let mut writer = MemWriter::new();
- writer.write_be_f32(f);
- writer.write_le_f32(f);
+ writer.write_be_f32(f).unwrap();
+ writer.write_le_f32(f).unwrap();
let mut reader = MemReader::new(writer.unwrap());
- assert!(reader.read_be_f32() == 8.1250);
- assert!(reader.read_le_f32() == 8.1250);
+ assert!(reader.read_be_f32().unwrap() == 8.1250);
+ assert!(reader.read_le_f32().unwrap() == 8.1250);
}
#[test]
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 8904101dd05ed..ef1b1a56ec0e0 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -14,11 +14,11 @@ This module provides a set of functions and traits for working
with regular files & directories on a filesystem.
At the top-level of the module are a set of freestanding functions, associated
-with various filesystem operations. They all operate on a `Path` object.
+with various filesystem operations. They all operate on `Path` objects.
All operations in this module, including those as part of `File` et al
-block the task during execution. Most will raise `std::io::io_error`
-conditions in the event of failure.
+block the task during execution. In the event of failure, all functions/methods
+will return an `IoResult` type with an `Err` value.
Also included in this module is an implementation block on the `Path` object
defined in `std::path::Path`. The impl adds useful methods about inspecting the
@@ -27,21 +27,25 @@ particular bits of it, etc.
# Example
- use std::io::{File, fs};
+```rust
+# #[allow(unused_must_use)];
+use std::io::{File, fs};
- let path = Path::new("foo.txt");
+let path = Path::new("foo.txt");
- // create the file, whether it exists or not
- let mut file = File::create(&path);
- file.write(bytes!("foobar"));
+// create the file, whether it exists or not
+let mut file = File::create(&path);
+file.write(bytes!("foobar"));
+# drop(file);
- // open the file in read-only mode
- let mut file = File::open(&path);
- file.read_to_end();
+// open the file in read-only mode
+let mut file = File::open(&path);
+file.read_to_end();
- println!("{}", path.stat().size);
- fs::symlink(&path, &Path::new("bar.txt"));
- fs::unlink(&path);
+println!("{}", path.stat().unwrap().size);
+# drop(file);
+fs::unlink(&path);
+```
*/
@@ -50,7 +54,7 @@ use clone::Clone;
use iter::Iterator;
use super::{Reader, Writer, Seek};
use super::{SeekStyle, Read, Write, Open, IoError, Truncate,
- FileMode, FileAccess, FileStat, io_error, FilePermission};
+ FileMode, FileAccess, FileStat, IoResult, FilePermission};
use rt::rtio::{RtioFileStream, IoFactory, LocalIo};
use io;
use option::{Some, None, Option};
@@ -64,11 +68,12 @@ use vec::{OwnedVector, ImmutableVector};
/// Can be constructed via `File::open()`, `File::create()`, and
/// `File::open_mode()`.
///
-/// # Errors
+/// # Error
///
-/// This type will raise an io_error condition if operations are attempted against
-/// it for which its underlying file descriptor was not configured at creation
-/// time, via the `FileAccess` parameter to `File::open_mode()`.
+/// This type will return errors as an `IoResult` if operations are
+/// attempted against it for which its underlying file descriptor was not
+/// configured at creation time, via the `FileAccess` parameter to
+/// `File::open_mode()`.
pub struct File {
priv fd: ~RtioFileStream,
priv path: Path,
@@ -81,22 +86,19 @@ impl File {
///
/// # Example
///
- /// use std::io::{File, io_error, Open, ReadWrite};
+ /// ```rust,should_fail
+ /// use std::io::{File, Open, ReadWrite};
///
- /// let p = Path::new("/some/file/path.txt");
+ /// let p = Path::new("/some/file/path.txt");
///
- /// io_error::cond.trap(|_| {
- /// // hoo-boy...
- /// }).inside(|| {
- /// let file = match File::open_mode(&p, Open, ReadWrite) {
- /// Some(s) => s,
- /// None => fail!("whoops! I'm sure this raised, anyways..")
- /// };
- /// // do some stuff with that file
+ /// let file = match File::open_mode(&p, Open, ReadWrite) {
+ /// Ok(f) => f,
+ /// Err(e) => fail!("file error: {}", e),
+ /// };
+ /// // do some stuff with that file
///
- /// // the file will be closed at the end of this block
- /// })
- /// // ..
+ /// // the file will be closed at the end of this block
+ /// ```
///
/// `FileMode` and `FileAccess` provide information about the permissions
/// context in which a given stream is created. More information about them
@@ -106,12 +108,12 @@ impl File {
///
/// Note that, with this function, a `File` is returned regardless of the
/// access-limitations indicated by `FileAccess` (e.g. calling `write` on a
- /// `File` opened as `Read` will raise an `io_error` condition at runtime).
+ /// `File` opened as `Read` will return an error at runtime).
///
- /// # Errors
+ /// # Error
///
- /// This function will raise an `io_error` condition under a number of
- /// different circumstances, to include but not limited to:
+ /// This function will return an error under a number of different
+ /// circumstances, to include but not limited to:
///
/// * Opening a file that does not exist with `Read` access.
/// * Attempting to open a file with a `FileAccess` that the user lacks
@@ -119,7 +121,7 @@ impl File {
/// * Filesystem-level errors (full disk, etc)
pub fn open_mode(path: &Path,
mode: FileMode,
- access: FileAccess) -> Option {
+ access: FileAccess) -> IoResult {
LocalIo::maybe_raise(|io| {
io.fs_open(&path.to_c_str(), mode, access).map(|fd| {
File {
@@ -139,10 +141,12 @@ impl File {
///
/// # Example
///
- /// use std::io::File;
+ /// ```rust
+ /// use std::io::File;
///
- /// let contents = File::open(&Path::new("foo.txt")).read_to_end();
- pub fn open(path: &Path) -> Option {
+ /// let contents = File::open(&Path::new("foo.txt")).read_to_end();
+ /// ```
+ pub fn open(path: &Path) -> IoResult {
File::open_mode(path, Open, Read)
}
@@ -154,11 +158,16 @@ impl File {
///
/// # Example
///
- /// use std::io::File;
+ /// ```rust
+ /// # #[allow(unused_must_use)];
+ /// use std::io::File;
///
- /// let mut f = File::create(&Path::new("foo.txt"));
- /// f.write(bytes!("This is a sample file"));
- pub fn create(path: &Path) -> Option {
+ /// let mut f = File::create(&Path::new("foo.txt"));
+ /// f.write(bytes!("This is a sample file"));
+ /// # drop(f);
+ /// # ::std::io::fs::unlink(&Path::new("foo.txt"));
+ /// ```
+ pub fn create(path: &Path) -> IoResult {
File::open_mode(path, Truncate, Write)
}
@@ -170,24 +179,16 @@ impl File {
/// Synchronizes all modifications to this file to its permanent storage
/// device. This will flush any internal buffers necessary to perform this
/// operation.
- ///
- /// # Errors
- ///
- /// This function will raise on the `io_error` condition on failure.
- pub fn fsync(&mut self) {
- let _ = 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
/// file metadata to the filesystem. This is intended for use case which
/// must synchronize content, but don't need the metadata on disk. The goal
/// of this method is to reduce disk operations.
- ///
- /// # Errors
- ///
- /// This function will raise on the `io_error` condition on failure.
- pub fn datasync(&mut self) {
- let _ = 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
@@ -198,12 +199,8 @@ impl File {
/// be shrunk. If it is greater than the current file's size, then the file
/// will be extended to `size` and have all of the intermediate data filled
/// in with 0s.
- ///
- /// # Errors
- ///
- /// On error, this function will raise on the `io_error` condition.
- pub fn truncate(&mut self, size: i64) {
- let _ = self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
+ pub fn truncate(&mut self, size: i64) -> IoResult<()> {
+ self.fd.truncate(size)
}
/// Tests whether this stream has reached EOF.
@@ -219,24 +216,25 @@ impl File {
///
/// # Example
///
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
///
-/// let p = Path::new("/some/file/path.txt");
-/// fs::unlink(&p);
-/// // if we made it here without failing, then the
-/// // unlink operation was successful
+/// let p = Path::new("/some/file/path.txt");
+/// fs::unlink(&p);
+/// ```
///
/// Note that, just because an unlink call was successful, it is not
/// guaranteed that a file is immediately deleted (e.g. depending on
/// platform, other open file descriptors may prevent immediate removal)
///
-/// # Errors
+/// # Error
///
-/// 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) {
- LocalIo::maybe_raise(|io| io.fs_unlink(&path.to_c_str()));
+/// This function will return an error 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) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_unlink(&path.to_c_str()))
}
/// Given a path, query the file system to get information about a file,
@@ -249,48 +247,25 @@ pub fn unlink(path: &Path) {
///
/// # Example
///
-/// use std::io;
-/// use std::io::fs;
+/// ```rust
+/// use std::io::fs;
///
-/// let p = Path::new("/some/file/path.txt");
-/// match io::result(|| fs::stat(&p)) {
-/// Ok(stat) => { /* ... */ }
-/// Err(e) => { /* handle error */ }
-/// }
+/// let p = Path::new("/some/file/path.txt");
+/// match fs::stat(&p) {
+/// Ok(stat) => { /* ... */ }
+/// Err(e) => { /* handle error */ }
+/// }
+/// ```
///
-/// # Errors
+/// # Error
///
-/// 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 {
+/// This call will return an error 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) -> IoResult {
LocalIo::maybe_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,
- }
- }
+ })
}
/// Perform the same operation as the `stat` function, except that this
@@ -298,31 +273,33 @@ fn dummystat() -> FileStat {
/// information about the symlink file instead of the file that it points
/// to.
///
-/// # Errors
+/// # Error
///
/// See `stat`
-pub fn lstat(path: &Path) -> FileStat {
+pub fn lstat(path: &Path) -> IoResult {
LocalIo::maybe_raise(|io| {
io.fs_lstat(&path.to_c_str())
- }).unwrap_or_else(dummystat)
+ })
}
/// Rename a file or directory to a new name.
///
/// # Example
///
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
///
-/// fs::rename(&Path::new("foo"), &Path::new("bar"));
-/// // Oh boy, nothing was raised!
+/// fs::rename(&Path::new("foo"), &Path::new("bar"));
+/// ```
///
-/// # Errors
+/// # Error
///
-/// 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) {
- LocalIo::maybe_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()));
+/// Will return an error 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) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()))
}
/// Copies the contents of one file to another. This function will also
@@ -333,15 +310,17 @@ pub fn rename(from: &Path, to: &Path) {
///
/// # Example
///
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
///
-/// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
-/// // Oh boy, nothing was raised!
+/// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
+/// ```
///
-/// # Errors
+/// # Error
///
-/// Will raise an `io_error` condition is the following situations, but is
-/// not limited to just these cases:
+/// Will return an error in the following situations, but is not limited to
+/// just these cases:
///
/// * The `from` path is not a file
/// * The `from` file does not exist
@@ -351,27 +330,29 @@ 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
- }
+ let amt = match reader.read(buf) {
+ Ok(n) => n,
+ Err(ref e) if e.kind == io::EndOfFile => { break }
+ Err(e) => return Err(e)
+ };
+ if_ok!(writer.write(buf.slice_to(amt)));
}
- chmod(to, from.stat().perm)
+ chmod(to, if_ok!(from.stat()).perm)
}
/// Changes the permission mode bits found on a file or a directory. This
@@ -379,61 +360,51 @@ pub fn copy(from: &Path, to: &Path) {
///
/// # Example
///
-/// use std::io;
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io;
+/// use std::io::fs;
///
-/// fs::chmod(&Path::new("file.txt"), io::UserFile);
-/// fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite);
-/// fs::chmod(&Path::new("dir"), io::UserDir);
-/// fs::chmod(&Path::new("file.exe"), io::UserExec);
+/// fs::chmod(&Path::new("file.txt"), io::UserFile);
+/// fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite);
+/// fs::chmod(&Path::new("dir"), io::UserDir);
+/// fs::chmod(&Path::new("file.exe"), io::UserExec);
+/// ```
///
-/// # Errors
+/// # Error
///
-/// If this function encounters an I/O error, it will raise on the `io_error`
-/// condition. Some possible error situations are not having the permission to
+/// If this function encounters an I/O error, it will return an `Err` value.
+/// 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) {
- LocalIo::maybe_raise(|io| io.fs_chmod(&path.to_c_str(), mode));
+pub fn chmod(path: &Path, mode: io::FilePermission) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_chmod(&path.to_c_str(), mode))
}
/// Change the user and group owners of a file at the specified path.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn chown(path: &Path, uid: int, gid: int) {
- LocalIo::maybe_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid));
+pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid))
}
/// Creates a new hard link on the filesystem. The `dst` path will be a
/// link pointing to the `src` path. Note that systems often require these
/// two paths to both be located on the same filesystem.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn link(src: &Path, dst: &Path) {
- LocalIo::maybe_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str()));
+pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
+ LocalIo::maybe_raise(|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
/// symlink pointing to the `src` path.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn symlink(src: &Path, dst: &Path) {
- LocalIo::maybe_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()));
+pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()))
}
/// Reads a symlink, returning the file that the symlink points to.
///
-/// # Errors
+/// # Error
///
-/// 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 {
+/// This function will return an error 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) -> IoResult {
LocalIo::maybe_raise(|io| io.fs_readlink(&path.to_c_str()))
}
@@ -441,75 +412,85 @@ pub fn readlink(path: &Path) -> Option {
///
/// # Example
///
-/// use std::libc::S_IRWXU;
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io;
+/// use std::io::fs;
///
-/// let p = Path::new("/some/dir");
-/// fs::mkdir(&p, S_IRWXU as int);
-/// // If we got here, our directory exists! Hooray!
+/// let p = Path::new("/some/dir");
+/// fs::mkdir(&p, io::UserRWX);
+/// ```
///
-/// # Errors
+/// # Error
///
-/// 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) {
- LocalIo::maybe_raise(|io| io.fs_mkdir(&path.to_c_str(), mode));
+/// This call will return an error 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) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_mkdir(&path.to_c_str(), mode))
}
/// Remove an existing, empty directory
///
/// # Example
///
-/// use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
///
-/// let p = Path::new("/some/dir");
-/// fs::rmdir(&p);
-/// // good riddance, you mean ol' directory
+/// let p = Path::new("/some/dir");
+/// fs::rmdir(&p);
+/// ```
///
-/// # Errors
+/// # Error
///
-/// 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) {
- LocalIo::maybe_raise(|io| io.fs_rmdir(&path.to_c_str()));
+/// This call will return an error 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) -> IoResult<()> {
+ LocalIo::maybe_raise(|io| io.fs_rmdir(&path.to_c_str()))
}
/// Retrieve a vector containing all entries within a provided directory
///
/// # Example
///
-/// use std::io::fs;
-///
-/// // one possible implementation of fs::walk_dir only visiting files
-/// fn visit_dirs(dir: &Path, cb: |&Path|) {
-/// if dir.is_dir() {
-/// let contents = fs::readdir(dir).unwrap();
-/// for entry in contents.iter() {
-/// if entry.is_dir() { visit_dirs(entry, cb); }
-/// else { cb(entry); }
+/// ```rust
+/// use std::io;
+/// use std::io::fs;
+///
+/// // one possible implementation of fs::walk_dir only visiting files
+/// fn visit_dirs(dir: &Path, cb: |&Path|) -> io::IoResult<()> {
+/// if dir.is_dir() {
+/// let contents = if_ok!(fs::readdir(dir));
+/// for entry in contents.iter() {
+/// if entry.is_dir() {
+/// if_ok!(visit_dirs(entry, |p| cb(p)));
+/// } else {
+/// cb(entry);
/// }
/// }
-/// else { fail!("nope"); }
+/// Ok(())
+/// } else {
+/// Err(io::standard_error(io::InvalidInput))
/// }
+/// }
+/// ```
///
-/// # Errors
+/// # Error
///
-/// 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] {
+/// Will return an error 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) -> IoResult<~[Path]> {
LocalIo::maybe_raise(|io| {
io.fs_readdir(&path.to_c_str(), 0)
- }).unwrap_or_else(|| ~[])
+ })
}
/// 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) -> Directories {
- Directories { stack: readdir(path) }
+pub fn walk_dir(path: &Path) -> IoResult {
+ Ok(Directories { stack: if_ok!(readdir(path)) })
}
/// An iterator which walks over a directory
@@ -522,7 +503,10 @@ impl Iterator for Directories {
match self.stack.shift() {
Some(path) => {
if path.is_dir() {
- self.stack.push_all_move(readdir(&path));
+ match readdir(&path) {
+ Ok(dirs) => { self.stack.push_all_move(dirs); }
+ Err(..) => {}
+ }
}
Some(path)
}
@@ -534,19 +518,18 @@ impl Iterator for Directories {
/// Recursively create a directory and all of its parent components if they
/// are missing.
///
-/// # Errors
+/// # Error
///
-/// 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) {
+/// This function will return an `Err` value if an error happens, see
+/// `fs::mkdir` for more information about error conditions and performance.
+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)
}
@@ -554,92 +537,64 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) {
/// Removes a directory at this path, after removing all its contents. Use
/// carefully!
///
-/// # Errors
+/// # Error
///
-/// 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);
+/// This function will return an `Err` value if an error happens. See
+/// `file::unlink` and `fs::readdir` for possible error conditions.
+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.
/// The file at the path specified will have its last access time set to
/// `atime` and its modification time set to `mtime`. The times specified should
/// be in milliseconds.
-///
-/// # Errors
-///
-/// 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) {
- LocalIo::maybe_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime));
+pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
+ LocalIo::maybe_raise(|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(io::standard_error(io::EndOfFile)),
+ _ => Ok(read as uint)
}
},
- Err(ioerr) => {
- // EOF is indicated by returning None
- if ioerr.kind != io::EndOfFile {
- io_error::cond.raise(ioerr);
- }
- return None;
- }
+ Err(e) => Err(e),
}
}
}
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) {
+ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
match self.fd.seek(pos, style) {
Ok(_) => {
// successful seek resets EOF indicator
self.last_nread = -1;
- ()
- },
- Err(ioerr) => {
- io_error::cond.raise(ioerr);
+ Ok(())
}
+ Err(e) => Err(e),
}
}
}
@@ -650,17 +605,17 @@ 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
/// directory or a file.
///
- /// # Errors
+ /// # Error
///
/// Will not raise a condition
pub fn exists(&self) -> bool {
- io::result(|| self.stat()).is_ok()
+ self.stat().is_ok()
}
/// Whether the underlying implementation (be it a file path, or something
@@ -668,11 +623,11 @@ impl path::Path {
/// to non-existent locations or directories or other non-regular files
/// (named pipes, etc).
///
- /// # Errors
+ /// # Error
///
/// 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
}
@@ -683,11 +638,11 @@ impl path::Path {
/// Will return false for paths to non-existent locations or if the item is
/// not a directory (eg files, named pipes, links, etc)
///
- /// # Errors
+ /// # Error
///
/// 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
}
@@ -698,8 +653,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,
@@ -729,7 +683,7 @@ mod test {
// Gee, seeing how we're testing the fs module I sure hope that we
// at least implement this correctly!
let TempDir(ref p) = *self;
- io::fs::rmdir_recursive(p);
+ io::fs::rmdir_recursive(p).unwrap();
}
}
@@ -737,7 +691,7 @@ mod test {
use os;
use rand;
let ret = os::tmpdir().join(format!("rust-{}", rand::random::()));
- io::fs::mkdir(&ret, io::UserRWX);
+ io::fs::mkdir(&ret, io::UserRWX).unwrap();
TempDir(ret)
}
@@ -747,7 +701,7 @@ mod test {
let filename = &tmpdir.join("file_rt_io_file_test.txt");
{
let mut write_stream = File::open_mode(filename, Open, ReadWrite);
- write_stream.write(message.as_bytes());
+ write_stream.write(message.as_bytes()).unwrap();
}
{
let mut read_stream = File::open_mode(filename, Open, Read);
@@ -758,30 +712,20 @@ mod test {
};
assert_eq!(read_str, message.to_owned());
}
- unlink(filename);
+ unlink(filename).unwrap();
})
iotest!(fn invalid_path_raises() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_that_does_not_exist.txt");
- let mut called = false;
- io_error::cond.trap(|_| {
- called = true;
- }).inside(|| {
- let result = File::open_mode(filename, Open, Read);
- assert!(result.is_none());
- });
- assert!(called);
+ let result = File::open_mode(filename, Open, Read);
+ assert!(result.is_err());
})
iotest!(fn file_test_iounlinking_invalid_path_should_raise_condition() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
- let mut called = false;
- io_error::cond.trap(|_| {
- called = true;
- }).inside(|| unlink(filename));
- assert!(called);
+ assert!(unlink(filename).is_err());
})
iotest!(fn file_test_io_non_positional_read() {
@@ -791,20 +735,20 @@ mod test {
let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
{
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(message.as_bytes());
+ rw_stream.write(message.as_bytes()).unwrap();
}
{
let mut read_stream = File::open_mode(filename, Open, Read);
{
let read_buf = read_mem.mut_slice(0, 4);
- read_stream.read(read_buf);
+ read_stream.read(read_buf).unwrap();
}
{
let read_buf = read_mem.mut_slice(4, 8);
- read_stream.read(read_buf);
+ read_stream.read(read_buf).unwrap();
}
}
- unlink(filename);
+ unlink(filename).unwrap();
let read_str = str::from_utf8(read_mem).unwrap();
assert_eq!(read_str, message);
})
@@ -819,16 +763,16 @@ mod test {
let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
{
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(message.as_bytes());
+ rw_stream.write(message.as_bytes()).unwrap();
}
{
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();
- read_stream.read(read_mem);
- tell_pos_post_read = read_stream.tell();
+ read_stream.seek(set_cursor as i64, SeekSet).unwrap();
+ tell_pos_pre_read = read_stream.tell().unwrap();
+ read_stream.read(read_mem).unwrap();
+ tell_pos_post_read = read_stream.tell().unwrap();
}
- unlink(filename);
+ unlink(filename).unwrap();
let read_str = str::from_utf8(read_mem).unwrap();
assert_eq!(read_str, message.slice(4, 8));
assert_eq!(tell_pos_pre_read, set_cursor);
@@ -845,15 +789,15 @@ mod test {
let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
{
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(initial_msg.as_bytes());
- rw_stream.seek(seek_idx as i64, SeekSet);
- rw_stream.write(overwrite_msg.as_bytes());
+ rw_stream.write(initial_msg.as_bytes()).unwrap();
+ rw_stream.seek(seek_idx as i64, SeekSet).unwrap();
+ rw_stream.write(overwrite_msg.as_bytes()).unwrap();
}
{
let mut read_stream = File::open_mode(filename, Open, Read);
- read_stream.read(read_mem);
+ read_stream.read(read_mem).unwrap();
}
- unlink(filename);
+ unlink(filename).unwrap();
let read_str = str::from_utf8(read_mem).unwrap();
assert!(read_str == final_msg.to_owned());
})
@@ -869,24 +813,24 @@ mod test {
let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
{
let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
- rw_stream.write(initial_msg.as_bytes());
+ rw_stream.write(initial_msg.as_bytes()).unwrap();
}
{
let mut read_stream = File::open_mode(filename, Open, Read);
- read_stream.seek(-4, SeekEnd);
- read_stream.read(read_mem);
+ read_stream.seek(-4, SeekEnd).unwrap();
+ read_stream.read(read_mem).unwrap();
assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_three);
- read_stream.seek(-9, SeekCur);
- read_stream.read(read_mem);
+ read_stream.seek(-9, SeekCur).unwrap();
+ read_stream.read(read_mem).unwrap();
assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_two);
- read_stream.seek(0, SeekSet);
- read_stream.read(read_mem);
+ read_stream.seek(0, SeekSet).unwrap();
+ read_stream.read(read_mem).unwrap();
assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_one);
}
- unlink(filename);
+ unlink(filename).unwrap();
})
iotest!(fn file_test_stat_is_correct_on_is_file() {
@@ -895,36 +839,36 @@ mod test {
{
let mut fs = File::open_mode(filename, Open, ReadWrite);
let msg = "hw";
- fs.write(msg.as_bytes());
+ fs.write(msg.as_bytes()).unwrap();
}
- let stat_res = stat(filename);
+ let stat_res = stat(filename).unwrap();
assert_eq!(stat_res.kind, io::TypeFile);
- unlink(filename);
+ unlink(filename).unwrap();
})
iotest!(fn file_test_stat_is_correct_on_is_dir() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_stat_correct_on_is_dir");
- mkdir(filename, io::UserRWX);
- let stat_res = filename.stat();
+ mkdir(filename, io::UserRWX).unwrap();
+ let stat_res = filename.stat().unwrap();
assert!(stat_res.kind == io::TypeDirectory);
- rmdir(filename);
+ rmdir(filename).unwrap();
})
iotest!(fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
let tmpdir = tmpdir();
let dir = &tmpdir.join("fileinfo_false_on_dir");
- mkdir(dir, io::UserRWX);
+ mkdir(dir, io::UserRWX).unwrap();
assert!(dir.is_file() == false);
- rmdir(dir);
+ rmdir(dir).unwrap();
})
iotest!(fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
let tmpdir = tmpdir();
let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
- File::create(file).write(bytes!("foo"));
+ File::create(file).write(bytes!("foo")).unwrap();
assert!(file.exists());
- unlink(file);
+ unlink(file).unwrap();
assert!(!file.exists());
})
@@ -932,10 +876,10 @@ mod test {
let tmpdir = tmpdir();
let dir = &tmpdir.join("before_and_after_dir");
assert!(!dir.exists());
- mkdir(dir, io::UserRWX);
+ mkdir(dir, io::UserRWX).unwrap();
assert!(dir.exists());
assert!(dir.is_dir());
- rmdir(dir);
+ rmdir(dir).unwrap();
assert!(!dir.exists());
})
@@ -943,21 +887,21 @@ mod test {
use std::str;
let tmpdir = tmpdir();
let dir = &tmpdir.join("di_readdir");
- mkdir(dir, io::UserRWX);
+ mkdir(dir, io::UserRWX).unwrap();
let prefix = "foo";
for n in range(0,3) {
let f = dir.join(format!("{}.txt", n));
- let mut w = File::create(&f);
+ let mut w = File::create(&f).unwrap();
let msg_str = (prefix + n.to_str().to_owned()).to_owned();
let msg = msg_str.as_bytes();
- w.write(msg);
+ w.write(msg).unwrap();
}
- let files = readdir(dir);
+ let files = readdir(dir).unwrap();
let mut mem = [0u8, .. 4];
for f in files.iter() {
{
let n = f.filestem_str();
- File::open(f).read(mem);
+ File::open(f).read(mem).unwrap();
let read_str = str::from_utf8(mem).unwrap();
let expected = match n {
None|Some("") => fail!("really shouldn't happen.."),
@@ -965,13 +909,13 @@ mod test {
};
assert_eq!(expected.as_slice(), read_str);
}
- unlink(f);
+ unlink(f).unwrap();
}
- rmdir(dir);
+ rmdir(dir).unwrap();
})
iotest!(fn recursive_mkdir_slash() {
- mkdir_recursive(&Path::new("/"), io::UserRWX);
+ mkdir_recursive(&Path::new("/"), io::UserRWX).unwrap();
})
iotest!(fn unicode_path_is_dir() {
@@ -982,12 +926,12 @@ mod test {
let mut dirpath = tmpdir.path().clone();
dirpath.push(format!("test-가一ー你好"));
- mkdir(&dirpath, io::UserRWX);
+ mkdir(&dirpath, io::UserRWX).unwrap();
assert!(dirpath.is_dir());
let mut filepath = dirpath;
filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
- File::create(&filepath); // ignore return; touch only
+ File::create(&filepath).unwrap(); // ignore return; touch only
assert!(!filepath.is_dir());
assert!(filepath.exists());
})
@@ -999,7 +943,7 @@ mod test {
let tmpdir = tmpdir();
let unicode = tmpdir.path();
let unicode = unicode.join(format!("test-각丁ー再见"));
- mkdir(&unicode, io::UserRWX);
+ mkdir(&unicode, io::UserRWX).unwrap();
assert!(unicode.exists());
assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
})
@@ -1007,7 +951,7 @@ mod test {
iotest!(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());
@@ -1021,20 +965,20 @@ mod test {
let input = tmpdir.join("in.txt");
let out = tmpdir.join("out.txt");
- File::create(&input).write(bytes!("hello"));
- copy(&input, &out);
- let contents = File::open(&out).read_to_end();
+ File::create(&input).write(bytes!("hello")).unwrap();
+ copy(&input, &out).unwrap();
+ 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);
})
iotest!(fn copy_file_dst_dir() {
let tmpdir = tmpdir();
let out = tmpdir.join("out");
- File::create(&out);
- match io::result(|| copy(&out, tmpdir.path())) {
+ File::create(&out).unwrap();
+ match copy(&out, tmpdir.path()) {
Ok(..) => fail!(), Err(..) => {}
}
})
@@ -1044,11 +988,11 @@ mod test {
let input = tmpdir.join("in");
let output = tmpdir.join("out");
- File::create(&input).write("foo".as_bytes());
- File::create(&output).write("bar".as_bytes());
- copy(&input, &output);
+ File::create(&input).write("foo".as_bytes()).unwrap();
+ File::create(&output).write("bar".as_bytes()).unwrap();
+ copy(&input, &output).unwrap();
- assert_eq!(File::open(&output).read_to_end(),
+ assert_eq!(File::open(&output).read_to_end().unwrap(),
(bytes!("foo")).to_owned());
})
@@ -1056,7 +1000,7 @@ mod test {
let tmpdir = tmpdir();
let out = tmpdir.join("out");
- match io::result(|| copy(tmpdir.path(), &out)) {
+ match copy(tmpdir.path(), &out) {
Ok(..) => fail!(), Err(..) => {}
}
assert!(!out.exists());
@@ -1067,13 +1011,13 @@ mod test {
let input = tmpdir.join("in.txt");
let out = tmpdir.join("out.txt");
- File::create(&input);
- chmod(&input, io::UserRead);
- copy(&input, &out);
- assert!(out.stat().perm & io::UserWrite == 0);
+ File::create(&input).unwrap();
+ chmod(&input, io::UserRead).unwrap();
+ copy(&input, &out).unwrap();
+ assert!(out.stat().unwrap().perm & io::UserWrite == 0);
- chmod(&input, io::UserFile);
- chmod(&out, io::UserFile);
+ chmod(&input, io::UserFile).unwrap();
+ chmod(&out, io::UserFile).unwrap();
})
#[cfg(not(windows))] // FIXME(#10264) operation not permitted?
@@ -1082,26 +1026,27 @@ mod test {
let input = tmpdir.join("in.txt");
let out = tmpdir.join("out.txt");
- File::create(&input).write("foobar".as_bytes());
- symlink(&input, &out);
+ File::create(&input).write("foobar".as_bytes()).unwrap();
+ symlink(&input, &out).unwrap();
if cfg!(not(windows)) {
- assert_eq!(lstat(&out).kind, io::TypeSymlink);
+ assert_eq!(lstat(&out).unwrap().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!(stat(&out).unwrap().size, stat(&input).unwrap().size);
+ assert_eq!(File::open(&out).read_to_end().unwrap(),
+ (bytes!("foobar")).to_owned());
})
#[cfg(not(windows))] // apparently windows doesn't like symlinks
iotest!(fn symlink_noexist() {
let tmpdir = tmpdir();
// symlinks can point to things that don't exist
- symlink(&tmpdir.join("foo"), &tmpdir.join("bar"));
+ symlink(&tmpdir.join("foo"), &tmpdir.join("bar")).unwrap();
assert!(readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("foo"));
})
iotest!(fn readlink_not_symlink() {
let tmpdir = tmpdir();
- match io::result(|| readlink(tmpdir.path())) {
+ match readlink(tmpdir.path()) {
Ok(..) => fail!("wanted a failure"),
Err(..) => {}
}
@@ -1112,22 +1057,23 @@ mod test {
let input = tmpdir.join("in.txt");
let out = tmpdir.join("out.txt");
- File::create(&input).write("foobar".as_bytes());
- link(&input, &out);
+ File::create(&input).write("foobar".as_bytes()).unwrap();
+ link(&input, &out).unwrap();
if cfg!(not(windows)) {
- assert_eq!(lstat(&out).kind, io::TypeFile);
- assert_eq!(stat(&out).unstable.nlink, 2);
+ assert_eq!(lstat(&out).unwrap().kind, io::TypeFile);
+ assert_eq!(stat(&out).unwrap().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!(stat(&out).unwrap().size, stat(&input).unwrap().size);
+ assert_eq!(File::open(&out).read_to_end().unwrap(),
+ (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(..) => {}
}
@@ -1137,17 +1083,17 @@ mod test {
let tmpdir = tmpdir();
let file = tmpdir.join("in.txt");
- File::create(&file);
- assert!(stat(&file).perm & io::UserWrite == io::UserWrite);
- chmod(&file, io::UserRead);
- assert!(stat(&file).perm & io::UserWrite == 0);
+ File::create(&file).unwrap();
+ assert!(stat(&file).unwrap().perm & io::UserWrite == io::UserWrite);
+ chmod(&file, io::UserRead).unwrap();
+ 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(..) => {}
}
- chmod(&file, io::UserFile);
+ chmod(&file, io::UserFile).unwrap();
})
iotest!(fn sync_doesnt_kill_anything() {
@@ -1155,11 +1101,11 @@ mod test {
let path = tmpdir.join("in.txt");
let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
- file.fsync();
- file.datasync();
- file.write(bytes!("foo"));
- file.fsync();
- file.datasync();
+ file.fsync().unwrap();
+ file.datasync().unwrap();
+ file.write(bytes!("foo")).unwrap();
+ file.fsync().unwrap();
+ file.datasync().unwrap();
drop(file);
})
@@ -1168,28 +1114,28 @@ mod test {
let path = tmpdir.join("in.txt");
let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
- file.write(bytes!("foo"));
- file.fsync();
+ file.write(bytes!("foo")).unwrap();
+ file.fsync().unwrap();
// Do some simple things with truncation
- assert_eq!(stat(&path).size, 3);
- file.truncate(10);
- assert_eq!(stat(&path).size, 10);
- file.write(bytes!("bar"));
- file.fsync();
- assert_eq!(stat(&path).size, 10);
- assert_eq!(File::open(&path).read_to_end(),
+ assert_eq!(stat(&path).unwrap().size, 3);
+ file.truncate(10).unwrap();
+ assert_eq!(stat(&path).unwrap().size, 10);
+ file.write(bytes!("bar")).unwrap();
+ file.fsync().unwrap();
+ assert_eq!(stat(&path).unwrap().size, 10);
+ assert_eq!(File::open(&path).read_to_end().unwrap(),
(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);
- file.write(bytes!("wut"));
- file.fsync();
- assert_eq!(stat(&path).size, 9);
- assert_eq!(File::open(&path).read_to_end(),
+ file.truncate(2).unwrap();
+ assert_eq!(stat(&path).unwrap().size, 2);
+ file.write(bytes!("wut")).unwrap();
+ file.fsync().unwrap();
+ assert_eq!(stat(&path).unwrap().size, 9);
+ assert_eq!(File::open(&path).read_to_end().unwrap(),
(bytes!("fo", 0, 0, 0, 0, "wut")).to_owned());
drop(file);
})
@@ -1197,8 +1143,7 @@ mod test {
iotest!(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();
@@ -1208,46 +1153,46 @@ mod test {
File::open_mode(&tmpdir.join("f"), io::Truncate, io::Write).unwrap();
File::open_mode(&tmpdir.join("g"), io::Truncate, io::ReadWrite).unwrap();
- File::create(&tmpdir.join("h")).write("foo".as_bytes());
+ File::create(&tmpdir.join("h")).write("foo".as_bytes()).unwrap();
File::open_mode(&tmpdir.join("h"), io::Open, io::Read).unwrap();
{
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());
+ f.write("bar".as_bytes()).unwrap();
}
- 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());
+ f.write("bar".as_bytes()).unwrap();
}
- assert_eq!(stat(&tmpdir.join("h")).size, 3);
+ assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 3);
})
#[test]
fn utime() {
let tmpdir = tmpdir();
let path = tmpdir.join("a");
- File::create(&path);
+ File::create(&path).unwrap();
- change_file_times(&path, 1000, 2000);
- assert_eq!(path.stat().accessed, 1000);
- assert_eq!(path.stat().modified, 2000);
+ change_file_times(&path, 1000, 2000).unwrap();
+ assert_eq!(path.stat().unwrap().accessed, 1000);
+ assert_eq!(path.stat().unwrap().modified, 2000);
}
#[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 c185951fecac8..395ece17eded6 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -13,9 +13,10 @@
use cmp::max;
use cmp::min;
use container::Container;
-use option::{Option, Some, None};
-use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
- OtherIoError};
+use option::None;
+use result::{Err, Ok};
+use io;
+use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
use vec;
use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
@@ -24,6 +25,7 @@ use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::MemWriter;
///
/// let mut w = MemWriter::new();
@@ -59,7 +61,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;
@@ -86,14 +88,15 @@ impl Writer for MemWriter {
// Bump us forward
self.pos += buf.len();
+ Ok(())
}
}
// FIXME(#10432)
impl Seek for MemWriter {
- fn tell(&self) -> u64 { self.pos as u64 }
+ fn tell(&self) -> IoResult { Ok(self.pos as u64) }
- fn seek(&mut self, pos: i64, style: SeekStyle) {
+ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
// compute offset as signed and clamp to prevent overflow
let offset = match style {
SeekSet => { 0 }
@@ -102,6 +105,7 @@ impl Seek for MemWriter {
} as i64;
self.pos = max(0, offset+pos) as uint;
+ Ok(())
}
}
@@ -110,11 +114,12 @@ impl Seek for MemWriter {
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::MemReader;
///
/// let mut r = MemReader::new(~[0, 1, 2]);
///
-/// assert_eq!(r.read_to_end(), ~[0, 1, 2]);
+/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2]);
/// ```
pub struct MemReader {
priv buf: ~[u8],
@@ -148,8 +153,8 @@ impl MemReader {
}
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(io::standard_error(io::EndOfFile)) }
let write_len = min(buf.len(), self.buf.len() - self.pos);
{
@@ -161,28 +166,31 @@ impl Reader for MemReader {
self.pos += write_len;
assert!(self.pos <= self.buf.len());
- return Some(write_len);
+ return Ok(write_len);
}
}
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; }
}
/// Writes to a fixed-size byte slice
///
-/// If a write will not fit in the buffer, it raises the `io_error`
-/// condition and does not write any data.
+/// If a write will not fit in the buffer, it returns an error and does not
+/// write any data.
///
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::BufWriter;
///
/// let mut buf = [0, ..4];
@@ -207,28 +215,28 @@ impl<'a> BufWriter<'a> {
}
impl<'a> Writer for BufWriter<'a> {
- fn write(&mut self, buf: &[u8]) {
+ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
// raises a condition if the entire write does not fit in the buffer
let max_size = self.buf.len();
if self.pos >= max_size || (self.pos + buf.len()) > max_size {
- io_error::cond.raise(IoError {
- kind: OtherIoError,
+ return Err(IoError {
+ kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
- });
- return;
+ })
}
vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
self.pos += buf.len();
+ Ok(())
}
}
// FIXME(#10432)
impl<'a> Seek for BufWriter<'a> {
- fn tell(&self) -> u64 { self.pos as u64 }
+ fn tell(&self) -> IoResult { Ok(self.pos as u64) }
- fn seek(&mut self, pos: i64, style: SeekStyle) {
+ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
// compute offset as signed and clamp to prevent overflow
let offset = match style {
SeekSet => { 0 }
@@ -237,6 +245,7 @@ impl<'a> Seek for BufWriter<'a> {
} as i64;
self.pos = max(0, offset+pos) as uint;
+ Ok(())
}
}
@@ -246,12 +255,13 @@ impl<'a> Seek for BufWriter<'a> {
/// # Example
///
/// ```rust
+/// # #[allow(unused_must_use)];
/// use std::io::BufReader;
///
/// let mut buf = [0, 1, 2, 3];
/// let mut r = BufReader::new(buf);
///
-/// assert_eq!(r.read_to_end(), ~[0, 1, 2, 3]);
+/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2, 3]);
/// ```
pub struct BufReader<'a> {
priv buf: &'a [u8],
@@ -274,8 +284,8 @@ impl<'a> BufReader<'a> {
}
impl<'a> Reader for BufReader<'a> {
- 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(io::standard_error(io::EndOfFile)) }
let write_len = min(buf.len(), self.buf.len() - self.pos);
{
@@ -287,18 +297,19 @@ impl<'a> Reader for BufReader<'a> {
self.pos += write_len;
assert!(self.pos <= self.buf.len());
- return Some(write_len);
+ return Ok(write_len);
}
}
impl<'a> Seek for BufReader<'a> {
- 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<'a> Buffer for BufReader<'a> {
- 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; }
}
@@ -307,33 +318,34 @@ mod test {
use prelude::*;
use super::*;
use io::*;
+ use io;
#[test]
fn test_mem_writer() {
let mut writer = MemWriter::new();
- assert_eq!(writer.tell(), 0);
- writer.write([0]);
- assert_eq!(writer.tell(), 1);
- writer.write([1, 2, 3]);
- writer.write([4, 5, 6, 7]);
- assert_eq!(writer.tell(), 8);
+ assert_eq!(writer.tell(), Ok(0));
+ writer.write([0]).unwrap();
+ assert_eq!(writer.tell(), Ok(1));
+ writer.write([1, 2, 3]).unwrap();
+ writer.write([4, 5, 6, 7]).unwrap();
+ assert_eq!(writer.tell(), Ok(8));
assert_eq!(writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7]);
- writer.seek(0, SeekSet);
- assert_eq!(writer.tell(), 0);
- writer.write([3, 4]);
+ writer.seek(0, SeekSet).unwrap();
+ assert_eq!(writer.tell(), Ok(0));
+ writer.write([3, 4]).unwrap();
assert_eq!(writer.get_ref(), [3, 4, 2, 3, 4, 5, 6, 7]);
- writer.seek(1, SeekCur);
- writer.write([0, 1]);
+ writer.seek(1, SeekCur).unwrap();
+ writer.write([0, 1]).unwrap();
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 7]);
- writer.seek(-1, SeekEnd);
- writer.write([1, 2]);
+ writer.seek(-1, SeekEnd).unwrap();
+ writer.write([1, 2]).unwrap();
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2]);
- writer.seek(1, SeekEnd);
- writer.write([1]);
+ writer.seek(1, SeekEnd).unwrap();
+ writer.write([1]).unwrap();
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
}
@@ -342,12 +354,12 @@ mod test {
let mut buf = [0 as u8, ..8];
{
let mut writer = BufWriter::new(buf);
- assert_eq!(writer.tell(), 0);
- writer.write([0]);
- assert_eq!(writer.tell(), 1);
- writer.write([1, 2, 3]);
- writer.write([4, 5, 6, 7]);
- assert_eq!(writer.tell(), 8);
+ assert_eq!(writer.tell(), Ok(0));
+ writer.write([0]).unwrap();
+ assert_eq!(writer.tell(), Ok(1));
+ writer.write([1, 2, 3]).unwrap();
+ writer.write([4, 5, 6, 7]).unwrap();
+ assert_eq!(writer.tell(), Ok(8));
}
assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]);
}
@@ -357,24 +369,24 @@ mod test {
let mut buf = [0 as u8, ..8];
{
let mut writer = BufWriter::new(buf);
- assert_eq!(writer.tell(), 0);
- writer.write([1]);
- assert_eq!(writer.tell(), 1);
+ assert_eq!(writer.tell(), Ok(0));
+ writer.write([1]).unwrap();
+ assert_eq!(writer.tell(), Ok(1));
- writer.seek(2, SeekSet);
- assert_eq!(writer.tell(), 2);
- writer.write([2]);
- assert_eq!(writer.tell(), 3);
+ writer.seek(2, SeekSet).unwrap();
+ assert_eq!(writer.tell(), Ok(2));
+ writer.write([2]).unwrap();
+ assert_eq!(writer.tell(), Ok(3));
- writer.seek(-2, SeekCur);
- assert_eq!(writer.tell(), 1);
- writer.write([3]);
- assert_eq!(writer.tell(), 2);
+ writer.seek(-2, SeekCur).unwrap();
+ assert_eq!(writer.tell(), Ok(1));
+ writer.write([3]).unwrap();
+ assert_eq!(writer.tell(), Ok(2));
- writer.seek(-1, SeekEnd);
- assert_eq!(writer.tell(), 7);
- writer.write([4]);
- assert_eq!(writer.tell(), 8);
+ writer.seek(-1, SeekEnd).unwrap();
+ assert_eq!(writer.tell(), Ok(7));
+ writer.write([4]).unwrap();
+ assert_eq!(writer.tell(), Ok(8));
}
assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]);
@@ -384,35 +396,31 @@ mod test {
fn test_buf_writer_error() {
let mut buf = [0 as u8, ..2];
let mut writer = BufWriter::new(buf);
- writer.write([0]);
-
- let mut called = false;
- io_error::cond.trap(|err| {
- assert_eq!(err.kind, OtherIoError);
- called = true;
- }).inside(|| {
- writer.write([0, 0]);
- });
- assert!(called);
+ writer.write([0]).unwrap();
+
+ match writer.write([0, 0]) {
+ Ok(..) => fail!(),
+ Err(e) => assert_eq!(e.kind, io::OtherIoError),
+ }
}
#[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_eq!(reader.read(buf), None);
+ assert!(reader.read(buf).is_err());
}
#[test]
@@ -420,64 +428,64 @@ 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_eq!(reader.read(buf), None);
+ assert!(reader.read(buf).is_err());
}
#[test]
fn test_read_char() {
let b = bytes!("Việt");
let mut r = BufReader::new(b);
- assert_eq!(r.read_char(), Some('V'));
- assert_eq!(r.read_char(), Some('i'));
- assert_eq!(r.read_char(), Some('ệ'));
- assert_eq!(r.read_char(), Some('t'));
- assert_eq!(r.read_char(), None);
+ assert_eq!(r.read_char(), Ok('V'));
+ assert_eq!(r.read_char(), Ok('i'));
+ assert_eq!(r.read_char(), Ok('ệ'));
+ assert_eq!(r.read_char(), Ok('t'));
+ assert!(r.read_char().is_err());
}
#[test]
fn test_read_bad_char() {
let b = bytes!(0x80);
let mut r = BufReader::new(b);
- assert_eq!(r.read_char(), None);
+ assert!(r.read_char().is_err());
}
#[test]
fn test_write_strings() {
let mut writer = MemWriter::new();
- writer.write_str("testing");
- writer.write_line("testing");
- writer.write_str("testing");
+ writer.write_str("testing").unwrap();
+ writer.write_line("testing").unwrap();
+ writer.write_str("testing").unwrap();
let mut r = BufReader::new(writer.get_ref());
- assert_eq!(r.read_to_str(), ~"testingtesting\ntesting");
+ assert_eq!(r.read_to_str().unwrap(), ~"testingtesting\ntesting");
}
#[test]
fn test_write_char() {
let mut writer = MemWriter::new();
- writer.write_char('a');
- writer.write_char('\n');
- writer.write_char('ệ');
+ writer.write_char('a').unwrap();
+ writer.write_char('\n').unwrap();
+ writer.write_char('ệ').unwrap();
let mut r = BufReader::new(writer.get_ref());
- assert_eq!(r.read_to_str(), ~"a\nệ");
+ assert_eq!(r.read_to_str().unwrap(), ~"a\nệ");
}
#[test]
fn test_read_whole_string_bad() {
let buf = [0xff];
let mut r = BufReader::new(buf);
- match result(|| r.read_to_str()) {
+ match r.read_to_str() {
Ok(..) => fail!(),
Err(..) => {}
}
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 69f0cf96ffc34..7690c88478fde 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -29,7 +29,6 @@ Some examples of obvious things you might want to do
use std::io::BufferedReader;
use std::io::stdin;
- # let _g = ::std::io::ignore_io_error();
let mut stdin = BufferedReader::new(stdin());
for line in stdin.lines() {
print!("{}", line);
@@ -41,16 +40,15 @@ Some examples of obvious things you might want to do
```rust
use std::io::File;
- # let _g = ::std::io::ignore_io_error();
let contents = File::open(&Path::new("message.txt")).read_to_end();
```
* Write a line to a file
```rust
+ # #[allow(unused_must_use)];
use std::io::File;
- # let _g = ::std::io::ignore_io_error();
let mut file = File::create(&Path::new("message.txt"));
file.write(bytes!("hello, file!\n"));
# drop(file);
@@ -63,7 +61,6 @@ Some examples of obvious things you might want to do
use std::io::BufferedReader;
use std::io::File;
- # let _g = ::std::io::ignore_io_error();
let path = Path::new("message.txt");
let mut file = BufferedReader::new(File::open(&path));
for line in file.lines() {
@@ -77,7 +74,6 @@ Some examples of obvious things you might want to do
use std::io::BufferedReader;
use std::io::File;
- # let _g = ::std::io::ignore_io_error();
let path = Path::new("message.txt");
let mut file = BufferedReader::new(File::open(&path));
let lines: ~[~str] = file.lines().collect();
@@ -88,10 +84,10 @@ Some examples of obvious things you might want to do
`write_str` and `write_line` methods.
```rust,should_fail
+ # #[allow(unused_must_use)];
use std::io::net::ip::SocketAddr;
use std::io::net::tcp::TcpStream;
- # let _g = ::std::io::ignore_io_error();
let addr = from_str::("127.0.0.1:8080").unwrap();
let mut socket = TcpStream::connect(addr).unwrap();
socket.write(bytes!("GET / HTTP/1.0\n\n"));
@@ -168,72 +164,51 @@ asynchronous request completes.
# Error Handling
I/O is an area where nearly every operation can result in unexpected
-errors. It should allow errors to be handled efficiently.
-It needs to be convenient to use I/O when you don't care
-about dealing with specific errors.
+errors. Errors should be painfully visible when they happen, and handling them
+should be easy to work with. It should be convenient to handle specific I/O
+errors, and it should also be convenient to not deal with I/O errors.
Rust's I/O employs a combination of techniques to reduce boilerplate
while still providing feedback about errors. The basic strategy:
-* Errors are fatal by default, resulting in task failure
-* Errors raise the `io_error` condition which provides an opportunity to inspect
- an IoError object containing details.
-* Return values must have a sensible null or zero value which is returned
- if a condition is handled successfully. This may be an `Option`, an empty
- vector, or other designated error value.
-* Common traits are implemented for `Option`, e.g. `impl Reader for Option`,
- so that nullable values do not have to be 'unwrapped' before use.
+* All I/O operations return `IoResult` which is equivalent to
+ `Result`. The core `Result` type is defined in the `std::result`
+ module.
+* If the `Result` type goes unused, then the compiler will by default emit a
+ warning about the unused result.
+* Common traits are implemented for `IoResult`, e.g.
+ `impl Reader for IoResult`, so that error values do not have
+ to be 'unwrapped' before use.
These features combine in the API to allow for expressions like
`File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
without having to worry about whether "diary.txt" exists or whether
the write succeeds. As written, if either `new` or `write_line`
-encounters an error the task will fail.
+encounters an error then the result of the entire expression will
+be an error.
If you wanted to handle the error though you might write:
```rust
+# #[allow(unused_must_use)];
use std::io::File;
-use std::io::{IoError, io_error};
-let mut error = None;
-io_error::cond.trap(|e: IoError| {
- error = Some(e);
-}).inside(|| {
- File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"));
-});
-
-if error.is_some() {
- println!("failed to write my diary");
+match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
+ Ok(()) => { /* succeeded */ }
+ Err(e) => println!("failed to write to my diary: {}", e),
}
+
# ::std::io::fs::unlink(&Path::new("diary.txt"));
```
-FIXME: Need better condition handling syntax
-
-In this case the condition handler will have the opportunity to
-inspect the IoError raised by either the call to `new` or the call to
-`write_line`, but then execution will continue.
-
-So what actually happens if `new` encounters an error? To understand
-that it's important to know that what `new` returns is not a `File`
-but an `Option`. If the file does not open, and the condition
-is handled, then `new` will simply return `None`. Because there is an
-implementation of `Writer` (the trait required ultimately required for
-types to implement `write_line`) there is no need to inspect or unwrap
-the `Option` and we simply call `write_line` on it. If `new`
-returned a `None` then the followup call to `write_line` will also
-raise an error.
-
-## Concerns about this strategy
-
-This structure will encourage a programming style that is prone
-to errors similar to null pointer dereferences.
-In particular code written to ignore errors and expect conditions to be unhandled
-will start passing around null or zero objects when wrapped in a condition handler.
-
-* FIXME: How should we use condition handlers that return values?
-* FIXME: Should EOF raise default conditions when EOF is not an error?
+So what actually happens if `create` encounters an error?
+It's important to know that what `new` returns is not a `File`
+but an `IoResult`. If the file does not open, then `new` will simply
+return `Err(..)`. Because there is an implementation of `Writer` (the trait
+required ultimately required for types to implement `write_line`) there is no
+need to inspect or unwrap the `IoResult` and we simply call `write_line`
+on it. If `new` returned an `Err(..)` then the followup call to `write_line`
+will also return an error.
# Issues with i/o scheduler affinity, work stealing, task pinning
@@ -287,18 +262,19 @@ Out of scope
*/
#[allow(missing_doc)];
+#[deny(unused_must_use)];
use cast;
use char::Char;
-use condition::Guard;
use container::Container;
+use fmt;
use int;
use iter::Iterator;
use option::{Option, Some, None};
use path::Path;
use result::{Ok, Err, Result};
-use str;
use str::{StrSlice, OwnedStr};
+use str;
use to_str::ToStr;
use uint;
use unstable::finally::Finally;
@@ -347,8 +323,8 @@ mod mem;
/// Non-blocking access to stdin, stdout, stderr
pub mod stdio;
-/// Implementations for Option
-mod option;
+/// Implementations for Result
+mod result;
/// Extension traits
pub mod extensions;
@@ -373,17 +349,30 @@ mod comm_adapters;
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
static DEFAULT_BUF_SIZE: uint = 1024 * 64;
+pub type IoResult = Result;
+
/// The type passed to I/O condition handlers to indicate error
///
/// # FIXME
///
/// Is something like this sufficient? It's kind of archaic
+#[deriving(Eq, Clone)]
pub struct IoError {
kind: IoErrorKind,
desc: &'static str,
detail: Option<~str>
}
+impl fmt::Show for IoError {
+ fn fmt(err: &IoError, fmt: &mut fmt::Formatter) -> fmt::Result {
+ if_ok!(fmt.buf.write_str(err.desc));
+ match err.detail {
+ Some(ref s) => write!(fmt.buf, " ({})", *s),
+ None => Ok(())
+ }
+ }
+}
+
// FIXME: #8242 implementing manually because deriving doesn't work for some reason
impl ToStr for IoError {
fn to_str(&self) -> ~str {
@@ -398,9 +387,8 @@ impl ToStr for IoError {
}
}
-#[deriving(Eq)]
+#[deriving(Eq, Clone)]
pub enum IoErrorKind {
- PreviousIoError,
OtherIoError,
EndOfFile,
FileNotFound,
@@ -424,7 +412,6 @@ pub enum IoErrorKind {
impl ToStr for IoErrorKind {
fn to_str(&self) -> ~str {
match *self {
- PreviousIoError => ~"PreviousIoError",
OtherIoError => ~"OtherIoError",
EndOfFile => ~"EndOfFile",
FileNotFound => ~"FileNotFound",
@@ -446,184 +433,130 @@ impl ToStr for IoErrorKind {
}
}
-// FIXME: 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() -> Guard<'static,IoError,()> {
- io_error::cond.trap(|_| {
- // just swallow the error.. downstream users
- // who can make a decision based on a None result
- // won't care
- }).guard()
-}
-
-/// 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
+ // Only method which need to get implemented for this trait
/// Read bytes, up to the length of `buf` and place them in `buf`.
/// Returns the number of bytes read. The number of bytes read my
- /// be less than the number requested, even 0. Returns `None` on EOF.
- ///
- /// # Failure
+ /// be less than the number requested, even 0. Returns `Err` on EOF.
///
- /// Raises the `io_error` condition on error. If the condition
- /// is handled then no guarantee is made about the number of bytes
- /// read and the contents of `buf`. If the condition is handled
- /// returns `None` (FIXME see below).
+ /// # Error
///
- /// # FIXME
- ///
- /// * Should raise_default error on eof?
- /// * If the condition is handled it should still return the bytes read,
- /// in which case there's no need to return Option - but then you *have*
- /// to install a handler to detect eof.
- ///
- /// This doesn't take a `len` argument like the old `read`.
- /// 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;
+ /// If an error occurs during this I/O operation, then it is returned as
+ /// `Err(IoError)`. Note that end-of-file is considered an error, and can be
+ /// inspected for in the error's `kind` field. Also note that reading 0
+ /// bytes is not considered an error in all circumstances
+ fn read(&mut self, buf: &mut [u8]) -> IoResult;
// Convenient helper methods based on the above methods
- /// Reads a single byte. Returns `None` on EOF.
- ///
- /// # Failure
- ///
- /// Raises the same conditions as the `read` method. Returns
- /// `None` if the condition is handled.
- fn read_byte(&mut self) -> Option {
+ /// Reads a single byte. Returns `Err` on EOF.
+ 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(0) => {
+ debug!("read 0 bytes. trying again");
+ }
+ Ok(1) => return Ok(buf[0]),
+ Ok(_) => unreachable!(),
+ Err(e) => return Err(e)
}
- Some(1) => Some(buf[0]),
- Some(_) => unreachable!(),
- None => None
}
}
/// Reads `len` bytes and appends them to a vector.
///
/// May push fewer than the requested number of bytes on error
- /// or EOF. Returns true on success, false on EOF or error.
- ///
- /// # Failure
- ///
- /// 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) {
- unsafe {
- let start_len = buf.len();
- let mut total_read = 0;
-
- buf.reserve_additional(len);
- buf.set_len(start_len + len);
-
- (|| {
- while total_read < len {
- let len = buf.len();
- let slice = buf.mut_slice(start_len + total_read, len);
- match self.read(slice) {
- Some(nread) => {
- total_read += nread;
- }
- None => {
- io_error::cond.raise(standard_error(EndOfFile));
- break;
- }
+ /// or EOF. If `Ok(())` is returned, then all of the requested bytes were
+ /// pushed on to the vector, otherwise the amount `len` bytes couldn't be
+ /// read (an error was encountered), and the error is returned.
+ fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> {
+ let start_len = buf.len();
+ let mut total_read = 0;
+
+ buf.reserve_additional(len);
+ unsafe { buf.set_len(start_len + len); }
+
+ (|| {
+ while total_read < len {
+ let len = buf.len();
+ let slice = buf.mut_slice(start_len + total_read, len);
+ match self.read(slice) {
+ Ok(nread) => {
+ total_read += nread;
}
+ Err(e) => return Err(e)
}
- }).finally(|| buf.set_len(start_len + total_read))
- }
+ }
+ Ok(())
+ }).finally(|| unsafe { buf.set_len(start_len + total_read) })
}
/// Reads `len` bytes and gives you back a new vector of length `len`
///
- /// # Failure
+ /// # Error
///
- /// 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] {
+ /// Fails with the same conditions as `read`. Additionally returns error on
+ /// on EOF. Note that if an error is returned, then some number of bytes may
+ /// have already been consumed from the underlying reader, and they are lost
+ /// (not returned as part of the error). If this is unacceptable, then it is
+ /// recommended to use the `push_bytes` or `read` methods.
+ fn read_bytes(&mut self, len: uint) -> IoResult<~[u8]> {
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(e),
+ }
}
/// Reads all remaining bytes from the stream.
///
- /// # Failure
+ /// # Error
///
- /// Raises the same conditions as the `read` method except for
- /// `EndOfFile` which is swallowed.
- fn read_to_end(&mut self) -> ~[u8] {
+ /// Returns any non-EOF error immediately. Previously read bytes are
+ /// discarded when an error is returned.
+ ///
+ /// When EOF is encountered, all bytes read up to that point are returned.
+ 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 => break,
+ Err(e) => return Err(e)
}
- });
- return buf;
+ }
+ return Ok(buf);
}
/// Reads all of the remaining bytes of this stream, interpreting them as a
/// UTF-8 encoded stream. The corresponding string is returned.
///
- /// # Failure
+ /// # Error
///
- /// This function will raise all the same conditions as the `read` method,
- /// along with raising a condition if the input is not valid UTF-8.
- fn read_to_str(&mut self) -> ~str {
- match str::from_utf8_owned(self.read_to_end()) {
- Some(s) => s,
- None => {
- io_error::cond.raise(standard_error(InvalidInput));
- ~""
+ /// This function returns all of the same errors as `read_to_end` with an
+ /// additional error if the reader's contents are not a valid sequence of
+ /// UTF-8 bytes.
+ fn read_to_str(&mut self) -> IoResult<~str> {
+ self.read_to_end().and_then(|s| {
+ match str::from_utf8_owned(s) {
+ Some(s) => Ok(s),
+ None => Err(standard_error(InvalidInput)),
}
- }
+ })
}
/// Create an iterator that reads a single byte on
/// each iteration, until EOF.
///
- /// # Failure
+ /// # Error
///
- /// Raises the same conditions as the `read` method, for
- /// each call to its `.next()` method.
- /// Ends the iteration if the condition is handled.
+ /// The iterator protocol causes all specifics about errors encountered to
+ /// be swallowed. All errors will be signified by returning `None` from the
+ /// iterator. If this is undesirable, it is recommended to use the
+ /// `read_byte` method.
fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
extensions::Bytes::new(self)
}
@@ -633,225 +566,219 @@ 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 {
+ fn read_be_u64(&mut self) -> IoResult {
self.read_be_uint_n(8)
}
/// 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 {
+ fn read_be_i64(&mut self) -> IoResult {
self.read_be_int_n(8)
}
/// 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 {
+ fn read_le_u64(&mut self) -> IoResult {
self.read_le_uint_n(8)
}
/// 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 {
+ fn read_le_i64(&mut self) -> IoResult {
self.read_le_int_n(8)
}
/// 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,
- 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) }
}
impl<'a> Reader for &'a 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 extend_sign(val: u64, nbytes: uint) -> i64 {
@@ -860,19 +787,22 @@ fn extend_sign(val: u64, nbytes: uint) -> i64 {
}
pub trait Writer {
- /// Write the given buffer
+ /// Write the entirety of a given buffer
///
- /// # Failure
+ /// # Errors
///
- /// Raises the `io_error` condition on error
- fn write(&mut self, buf: &[u8]);
+ /// If an error happens during the I/O operation, the error is returned as
+ /// `Err`. Note that it is considered an error if the entire buffer could
+ /// not be written, and if an error is returned then it is unknown how much
+ /// data (if any) was actually written.
+ 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 implementers 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 a rust string into this sink.
///
@@ -880,8 +810,8 @@ pub trait Writer {
/// If other encodings are desired, it is recommended to compose this stream
/// with another performing the conversion, or to use `write` with a
/// converted byte-array instead.
- fn write_str(&mut self, s: &str) {
- self.write(s.as_bytes());
+ fn write_str(&mut self, s: &str) -> IoResult<()> {
+ self.write(s.as_bytes())
}
/// Writes a string into this sink, and then writes a literal newline (`\n`)
@@ -891,125 +821,124 @@ pub trait Writer {
///
/// If other encodings or line ending flavors are desired, it is recommended
/// that the `write` method is used specifically instead.
- fn write_line(&mut self, s: &str) {
- self.write_str(s);
- self.write(['\n' as u8]);
+ fn write_line(&mut self, s: &str) -> IoResult<()> {
+ self.write_str(s).and_then(|()| self.write(['\n' as u8]))
}
/// Write a single char, encoded as UTF-8.
- fn write_char(&mut self, c: char) {
+ fn write_char(&mut self, c: char) -> IoResult<()> {
let mut buf = [0u8, ..4];
let n = c.encode_utf8(buf.as_mut_slice());
- self.write(buf.slice_to(n));
+ self.write(buf.slice_to(n))
}
/// 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))
}
@@ -1017,31 +946,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<'a> Writer for &'a 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 { }
@@ -1057,18 +986,18 @@ impl Stream for T {}
/// an iteration, but continue to yield elements if iteration
/// is attempted again.
///
-/// # Failure
+/// # Error
///
-/// Raises the same conditions as the `read` method except for `EndOfFile`
-/// which is swallowed.
-/// Iteration yields `None` if the condition is handled.
+/// This iterator will swallow all I/O errors, transforming `Err` values to
+/// `None`. If errors need to be handled, it is recommended to use the
+/// `read_line` method directly.
pub struct Lines<'r, T> {
priv buffer: &'r mut T,
}
impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> {
fn next(&mut self) -> Option<~str> {
- self.buffer.read_line()
+ self.buffer.read_line().ok()
}
}
@@ -1085,11 +1014,12 @@ pub trait Buffer: Reader {
/// consumed from this buffer returned to ensure that the bytes are never
/// returned twice.
///
- /// # Failure
+ /// # Error
///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered.
- fn fill<'a>(&'a mut self) -> &'a [u8];
+ /// This function will return an I/O error if the underlying reader was
+ /// read, but returned an error. Note that it is not an error to return a
+ /// 0-length buffer.
+ 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`.
@@ -1103,108 +1033,117 @@ pub trait Buffer: Reader {
///
/// ```rust
/// use std::io::{BufferedReader, stdin};
- /// # let _g = ::std::io::ignore_io_error();
///
/// let mut reader = BufferedReader::new(stdin());
///
- /// let input = reader.read_line().unwrap_or(~"nothing");
+ /// let input = reader.read_line().ok().unwrap_or(~"nothing");
/// ```
///
- /// # Failure
+ /// # Error
+ ///
+ /// This function has the same error semantics as `read_until`:
+ ///
+ /// * All non-EOF errors will be returned immediately
+ /// * If an error is returned previously consumed bytes are lost
+ /// * EOF is only returned if no bytes have been read
+ /// * Reach EOF may mean that the delimiter is not present in the return
+ /// value
///
- /// This function will raise on the `io_error` condition (except for
- /// `EndOfFile` which is swallowed) 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> {
- self.read_until('\n' as u8).map(|line| str::from_utf8_owned(line).unwrap())
+ /// Additionally, this function can fail if the line of input read is not a
+ /// valid UTF-8 sequence of bytes.
+ fn read_line(&mut self) -> IoResult<~str> {
+ self.read_until('\n' as u8).and_then(|line|
+ match str::from_utf8_owned(line) {
+ Some(s) => Ok(s),
+ None => Err(standard_error(InvalidInput)),
+ }
+ )
}
/// Create an iterator that reads a line on each iteration until EOF.
///
- /// # Failure
+ /// # Error
///
- /// Iterator raises the same conditions as the `read` method
- /// except for `EndOfFile`.
+ /// This iterator will transform all error values to `None`, discarding the
+ /// cause of the error. If this is undesirable, it is recommended to call
+ /// `read_line` directly.
fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
- Lines {
- buffer: self,
- }
+ Lines { buffer: self }
}
/// Reads a sequence of bytes leading up to a specified delimiter. Once the
/// specified byte is encountered, reading ceases and the bytes up to and
/// including the delimiter are returned.
///
- /// # Failure
+ /// # Error
///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered, except that `EndOfFile` is swallowed.
- fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
+ /// If any I/O error is encountered other than EOF, the error is immediately
+ /// returned. Note that this may discard bytes which have already been read,
+ /// and those bytes will *not* be returned. It is recommended to use other
+ /// methods if this case is worrying.
+ ///
+ /// If EOF is encountered, then this function will return EOF if 0 bytes
+ /// have been read, otherwise the pending byte buffer is returned. This
+ /// is the reason that the byte buffer returned may not always contain the
+ /// delimiter.
+ fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> {
let mut res = ~[];
- io_error::cond.trap(|e| {
- if e.kind != EndOfFile {
- io_error::cond.raise(e);
- }
- }).inside(|| {
- let mut used;
- loop {
- {
- let available = self.fill();
- match available.iter().position(|&b| b == byte) {
- Some(i) => {
- res.push_all(available.slice_to(i + 1));
- used = i + 1;
- break
- }
- None => {
- res.push_all(available);
- used = available.len();
- }
+ let mut used;
+ loop {
+ {
+ let available = match self.fill() {
+ Ok(n) => n,
+ Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
+ used = 0;
+ break
+ }
+ Err(e) => return Err(e)
+ };
+ match available.iter().position(|&b| b == byte) {
+ Some(i) => {
+ res.push_all(available.slice_to(i + 1));
+ used = i + 1;
+ break
+ }
+ None => {
+ res.push_all(available);
+ used = available.len();
}
}
- if used == 0 {
- break
- }
- self.consume(used);
}
self.consume(used);
- });
- return if res.len() == 0 {None} else {Some(res)};
-
+ }
+ self.consume(used);
+ Ok(res)
}
/// Reads the next utf8-encoded character from the underlying stream.
///
- /// This will return `None` if the following sequence of bytes in the
- /// stream are not a valid utf8-sequence, or if an I/O error is encountered.
- ///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if a read error is
- /// encountered.
- fn read_char(&mut self) -> Option {
- let width = {
- let available = self.fill();
- if available.len() == 0 { return None } // read error
- str::utf8_char_width(available[0])
- };
- if width == 0 { return None } // not uf8
- let mut buf = [0, ..4];
+ /// # Error
+ ///
+ /// If an I/O error occurs, or EOF, then this function will return `Err`.
+ /// This function will also return error if the stream does not contain a
+ /// valid utf-8 encoded codepoint as the next few bytes in the stream.
+ fn read_char(&mut self) -> IoResult {
+ let first_byte = if_ok!(self.read_byte());
+ let width = str::utf8_char_width(first_byte);
+ if width == 1 { return Ok(first_byte as char) }
+ if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
+ let mut buf = [first_byte, 0, 0, 0];
{
- let mut start = 0;
- loop {
- match self.read(buf.mut_slice(start, width)) {
- Some(n) if n == width - start => break,
- Some(n) if n < width - start => { start += n; }
- Some(..) | None => return None // read error
+ let mut start = 1;
+ while start < width {
+ match if_ok!(self.read(buf.mut_slice(start, width))) {
+ n if n == width - start => break,
+ n if n < width - start => { start += n; }
+ _ => return Err(standard_error(InvalidInput)),
}
}
}
match str::from_utf8(buf.slice_to(width)) {
- Some(s) => Some(s.char_at(0)),
- None => None
+ Some(s) => Ok(s.char_at(0)),
+ None => Err(standard_error(InvalidInput))
}
}
}
@@ -1222,7 +1161,7 @@ pub enum SeekStyle {
/// * Are `u64` and `i64` the right choices?
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
///
@@ -1231,31 +1170,35 @@ pub trait Seek {
/// # FIXME
///
/// * What is the behavior when seeking past the end of a stream?
- fn seek(&mut self, pos: i64, style: SeekStyle);
+ fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
}
-/// A listener is a value that can consume itself to start listening for connections.
+/// A listener is a value that can consume itself to start listening for
+/// connections.
+///
/// Doing so produces some sort of Acceptor.
pub trait Listener> {
/// Spin up the listener and start queuing incoming connections
///
- /// # Failure
+ /// # Error
///
- /// Raises `io_error` condition. If the condition is handled,
- /// then `listen` returns `None`.
- fn listen(self) -> Option;
+ /// Returns `Err` if this listener could not be bound to listen for
+ /// connections. In all cases, this listener is consumed.
+ fn listen(self) -> IoResult ;
}
/// An acceptor is a value that presents incoming connections
pub trait Acceptor {
/// Wait for and accept an incoming connection
///
- /// # Failure
- /// Raise `io_error` condition. If the condition is handled,
- /// then `accept` returns `None`.
- fn accept(&mut self) -> Option;
+ /// # Error
+ ///
+ /// Returns `Err` if an I/O error is encountered.
+ fn accept(&mut self) -> IoResult;
- /// Create an iterator over incoming connection attempts
+ /// Create an iterator over incoming connection attempts.
+ ///
+ /// Note that I/O errors will be yielded by the iterator itself.
fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
IncomingConnections { inc: self }
}
@@ -1264,23 +1207,22 @@ pub trait Acceptor {
/// An infinite iterator over incoming connection attempts.
/// Calling `next` will block the task until a connection is attempted.
///
-/// Since connection attempts can continue forever, this iterator always returns Some.
-/// The Some contains another Option representing whether the connection attempt was succesful.
-/// A successful connection will be wrapped in Some.
-/// A failed connection is represented as a None and raises a condition.
+/// Since connection attempts can continue forever, this iterator always returns
+/// `Some`. The `Some` contains the `IoResult` representing whether the
+/// connection attempt was succesful. A successful connection will be wrapped
+/// in `Ok`. A failed connection is represented as an `Err`.
pub struct IncomingConnections<'a, A> {
priv inc: &'a mut A,
}
-impl<'a, T, A: Acceptor> Iterator> for IncomingConnections<'a, A> {
- fn next(&mut self) -> Option > {
+impl<'a, T, A: Acceptor> Iterator> for IncomingConnections<'a, A> {
+ fn next(&mut self) -> Option> {
Some(self.inc.accept())
}
}
pub fn standard_error(kind: IoErrorKind) -> IoError {
let desc = match kind {
- PreviousIoError => "failing due to previous I/O error",
EndOfFile => "end of file",
IoUnavailable => "I/O is unavailable",
InvalidInput => "invalid input",
@@ -1314,7 +1256,7 @@ pub enum FileMode {
}
/// Access permissions with which the file should be opened. `File`s
-/// opened with `Read` will raise an `io_error` condition if written to.
+/// opened with `Read` will return an error if written to.
pub enum FileAccess {
Read,
Write,
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index 29bf6261a0748..e9ffe97f1c356 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -17,8 +17,9 @@ getaddrinfo()
*/
-use option::{Option, Some, None};
+use io::IoResult;
use io::net::ip::{SocketAddr, IpAddr};
+use option::{Option, Some, None};
use rt::rtio::{IoFactory, LocalIo};
use vec::ImmutableVector;
@@ -69,11 +70,7 @@ pub struct Info {
/// Easy name resolution. Given a hostname, returns the list of IP addresses for
/// that hostname.
-///
-/// # 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))
}
@@ -87,14 +84,10 @@ pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
/// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this
/// controls lookup
///
-/// # Failure
-///
-/// On failure, this will raise on the `io_error` condition.
-///
/// FIXME: 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]> {
+ -> IoResult<~[Info]> {
LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
}
@@ -115,6 +108,6 @@ mod test {
iotest!(fn issue_10663() {
// Something should happen here, but this certainly shouldn't cause
// everything to die. The actual outcome we don't care too much about.
- get_host_addresses("example.com");
+ get_host_addresses("example.com").unwrap();
} #[ignore])
}
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 475e3b206f2ac..a0bdc193d980c 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -8,11 +8,8 @@
// 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::{Reader, Writer, Listener, Acceptor, IoResult};
use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
@@ -25,57 +22,27 @@ impl TcpStream {
TcpStream { obj: s }
}
- pub fn connect(addr: SocketAddr) -> Option {
+ pub fn connect(addr: SocketAddr) -> IoResult {
LocalIo::maybe_raise(|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) }
}
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) }
}
pub struct TcpListener {
@@ -83,33 +50,20 @@ pub struct TcpListener {
}
impl TcpListener {
- pub fn bind(addr: SocketAddr) -> Option {
+ pub fn bind(addr: SocketAddr) -> IoResult {
LocalIo::maybe_raise(|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(|acceptor| TcpAcceptor { obj: acceptor })
}
}
@@ -118,14 +72,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)
}
}
@@ -138,29 +86,19 @@ mod test {
// FIXME #11530 this fails on android because tests are run as root
iotest!(fn bind_error() {
- 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),
+ }
} #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
iotest!(fn connect_error() {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert_eq!(e.kind, ConnectionRefused);
- 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);
+ let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
+ match TcpStream::connect(addr) {
+ Ok(..) => fail!(),
+ Err(e) => assert_eq!(e.kind, ConnectionRefused),
+ }
})
iotest!(fn smoke_test_ip4() {
@@ -170,14 +108,14 @@ mod test {
spawn(proc() {
port.recv();
let mut stream = TcpStream::connect(addr);
- stream.write([99]);
+ stream.write([99]).unwrap();
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == 99);
})
@@ -188,14 +126,14 @@ mod test {
spawn(proc() {
port.recv();
let mut stream = TcpStream::connect(addr);
- stream.write([99]);
+ stream.write([99]).unwrap();
});
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
let mut stream = acceptor.accept();
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == 99);
})
@@ -214,7 +152,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());
})
iotest!(fn read_eof_ip6() {
@@ -232,7 +170,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());
})
iotest!(fn read_eof_twice_ip4() {
@@ -250,17 +188,15 @@ mod test {
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);
- } else {
- fail!();
+ assert!(nread.is_err());
+
+ match stream.read(buf) {
+ Ok(..) => fail!(),
+ Err(ref e) => {
+ assert!(e.kind == NotConnected || e.kind == EndOfFile,
+ "unknown kind: {:?}", e.kind);
}
- }).inside(|| {
- let nread = stream.read(buf);
- assert!(nread.is_none());
- })
+ }
})
iotest!(fn read_eof_twice_ip6() {
@@ -278,17 +214,15 @@ mod test {
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);
- } else {
- fail!();
+ assert!(nread.is_err());
+
+ match stream.read(buf) {
+ Ok(..) => fail!(),
+ Err(ref e) => {
+ assert!(e.kind == NotConnected || e.kind == EndOfFile,
+ "unknown kind: {:?}", e.kind);
}
- }).inside(|| {
- let nread = stream.read(buf);
- assert!(nread.is_none());
- })
+ }
})
iotest!(fn write_close_ip4() {
@@ -306,19 +240,16 @@ 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) => {
+ assert!(e.kind == ConnectionReset ||
+ e.kind == BrokenPipe ||
+ e.kind == ConnectionAborted,
+ "unknown error: {:?}", e);
+ break;
+ }
+ }
}
})
@@ -337,19 +268,16 @@ 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) => {
+ assert!(e.kind == ConnectionReset ||
+ e.kind == BrokenPipe ||
+ e.kind == ConnectionAborted,
+ "unknown error: {:?}", e);
+ break;
+ }
+ }
}
})
@@ -362,7 +290,7 @@ mod test {
port.recv();
for _ in range(0, max) {
let mut stream = TcpStream::connect(addr);
- stream.write([99]);
+ stream.write([99]).unwrap();
}
});
@@ -370,7 +298,7 @@ mod test {
chan.send(());
for ref mut stream in acceptor.incoming().take(max) {
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert_eq!(buf[0], 99);
}
})
@@ -384,7 +312,7 @@ mod test {
port.recv();
for _ in range(0, max) {
let mut stream = TcpStream::connect(addr);
- stream.write([99]);
+ stream.write([99]).unwrap();
}
});
@@ -392,7 +320,7 @@ mod test {
chan.send(());
for ref mut stream in acceptor.incoming().take(max) {
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert_eq!(buf[0], 99);
}
})
@@ -410,7 +338,7 @@ mod test {
spawn(proc() {
let mut stream = stream;
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == i as u8);
debug!("read");
});
@@ -429,7 +357,7 @@ mod test {
// Connect again before writing
connect(i + 1, addr);
debug!("writing");
- stream.write([i as u8]);
+ stream.write([i as u8]).unwrap();
});
}
})
@@ -447,7 +375,7 @@ mod test {
spawn(proc() {
let mut stream = stream;
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == i as u8);
debug!("read");
});
@@ -466,7 +394,7 @@ mod test {
// Connect again before writing
connect(i + 1, addr);
debug!("writing");
- stream.write([i as u8]);
+ stream.write([i as u8]).unwrap();
});
}
})
@@ -484,7 +412,7 @@ mod test {
spawn(proc() {
let mut stream = stream;
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == 99);
debug!("read");
});
@@ -503,7 +431,7 @@ mod test {
// Connect again before writing
connect(i + 1, addr);
debug!("writing");
- stream.write([99]);
+ stream.write([99]).unwrap();
});
}
})
@@ -521,7 +449,7 @@ mod test {
spawn(proc() {
let mut stream = stream;
let mut buf = [0];
- stream.read(buf);
+ stream.read(buf).unwrap();
assert!(buf[0] == 99);
debug!("read");
});
@@ -540,7 +468,7 @@ mod test {
// Connect again before writing
connect(i + 1, addr);
debug!("writing");
- stream.write([99]);
+ stream.write([99]).unwrap();
});
}
})
@@ -551,7 +479,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());
}
@@ -561,20 +489,20 @@ mod test {
spawn(proc() {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
- acceptor.accept();
+ acceptor.accept().unwrap();
});
port.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());
}
@@ -593,37 +521,33 @@ mod test {
let addr = next_test_ip4();
let (p, c) = Chan::new();
spawn(proc() {
- let mut srv = TcpListener::bind(addr).listen();
+ let mut srv = TcpListener::bind(addr).listen().unwrap();
c.send(());
let mut cl = srv.accept().unwrap();
- cl.write([10]);
+ cl.write([10]).unwrap();
let mut b = [0];
- cl.read(b);
+ cl.read(b).unwrap();
c.send(());
});
p.recv();
let mut c = TcpStream::connect(addr).unwrap();
let mut b = [0, ..10];
- assert_eq!(c.read(b), Some(1));
- c.write([1]);
+ assert_eq!(c.read(b), Ok(1));
+ c.write([1]).unwrap();
p.recv();
})
iotest!(fn double_bind() {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
- called = true;
- }).inside(|| {
- let addr = next_test_ip4();
- let listener = TcpListener::bind(addr).unwrap().listen();
- assert!(listener.is_some());
- let listener2 = TcpListener::bind(addr).and_then(|l|
- l.listen());
- assert!(listener2.is_none());
- });
- assert!(called);
+ let addr = next_test_ip4();
+ let listener = TcpListener::bind(addr).unwrap().listen();
+ assert!(listener.is_ok());
+ match TcpListener::bind(addr).listen() {
+ Ok(..) => fail!(),
+ Err(e) => {
+ assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
+ }
+ }
})
iotest!(fn fast_rebind() {
@@ -632,7 +556,7 @@ mod test {
spawn(proc() {
port.recv();
- let _stream = TcpStream::connect(addr);
+ let _stream = TcpStream::connect(addr).unwrap();
// Close
port.recv();
});
@@ -641,7 +565,7 @@ mod test {
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
{
- let _stream = acceptor.accept();
+ let _stream = acceptor.accept().unwrap();
// Close client
chan.send(());
}
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 1cf30d469f7aa..0ef62648afcb7 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.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};
-use io::{io_error, EndOfFile};
+use io::{Reader, Writer, IoResult};
use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
pub struct UdpSocket {
@@ -20,45 +18,26 @@ pub struct UdpSocket {
}
impl UdpSocket {
- pub fn bind(addr: SocketAddr) -> Option {
+ pub fn bind(addr: SocketAddr) -> IoResult {
LocalIo::maybe_raise(|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()
}
}
@@ -76,21 +55,21 @@ impl UdpStream {
}
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,
+ Ok((_nread, src)) if src != peer => Ok(0),
+ Ok((nread, _src)) => Ok(nread),
+ Err(e) => Err(e),
}
})
}
}
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(|sock| sock.sendto(buf, self.connectedTo))
}
}
@@ -101,16 +80,11 @@ mod test {
// FIXME #11530 this fails on android because tests are run as root
iotest!(fn bind_error() {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert_eq!(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),
+ }
} #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
iotest!(fn socket_smoke_test_ip4() {
@@ -121,29 +95,29 @@ mod test {
spawn(proc() {
match UdpSocket::bind(client_ip) {
- Some(ref mut client) => {
+ Ok(ref mut client) => {
port.recv();
- client.sendto([99], server_ip)
+ client.sendto([99], server_ip).unwrap()
}
- None => fail!()
+ Err(..) => fail!()
}
chan2.send(());
});
match UdpSocket::bind(server_ip) {
- Some(ref mut server) => {
+ Ok(ref mut server) => {
chan.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!()
}
port2.recv();
})
@@ -155,28 +129,28 @@ mod test {
spawn(proc() {
match UdpSocket::bind(client_ip) {
- Some(ref mut client) => {
+ Ok(ref mut client) => {
port.recv();
- client.sendto([99], server_ip)
+ client.sendto([99], server_ip).unwrap()
}
- None => fail!()
+ Err(..) => fail!()
}
});
match UdpSocket::bind(server_ip) {
- Some(ref mut server) => {
+ Ok(ref mut server) => {
chan.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!()
}
})
@@ -188,32 +162,32 @@ mod test {
spawn(proc() {
match UdpSocket::bind(client_ip) {
- Some(client) => {
+ Ok(client) => {
let client = ~client;
let mut stream = client.connect(server_ip);
port.recv();
- stream.write([99]);
+ stream.write([99]).unwrap();
}
- None => fail!()
+ Err(..) => fail!()
}
chan2.send(());
});
match UdpSocket::bind(server_ip) {
- Some(server) => {
+ Ok(server) => {
let server = ~server;
let mut stream = server.connect(client_ip);
chan.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!()
}
port2.recv();
})
@@ -226,32 +200,32 @@ mod test {
spawn(proc() {
match UdpSocket::bind(client_ip) {
- Some(client) => {
+ Ok(client) => {
let client = ~client;
let mut stream = client.connect(server_ip);
port.recv();
- stream.write([99]);
+ stream.write([99]).unwrap();
}
- None => fail!()
+ Err(..) => fail!()
}
chan2.send(());
});
match UdpSocket::bind(server_ip) {
- Some(server) => {
+ Ok(server) => {
let server = ~server;
let mut stream = server.connect(client_ip);
chan.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!()
}
port2.recv();
})
@@ -259,13 +233,13 @@ mod test {
pub fn socket_name(addr: SocketAddr) {
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 d470e9bfda108..ce95b987663f7 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, LocalIo, RtioUnixListener};
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
use io::pipe::PipeStream;
-use io::{io_error, Listener, Acceptor, Reader, Writer};
+use io::{Listener, Acceptor, Reader, Writer, IoResult};
/// A stream which communicates over a named pipe.
pub struct UnixStream {
@@ -45,20 +45,17 @@ impl UnixStream {
///
/// The returned stream will be closed when the object falls out of scope.
///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if the connection
- /// could not be made.
- ///
/// # Example
///
- /// use std::io::net::unix::UnixStream;
+ /// ```rust
+ /// # #[allow(unused_must_use)];
+ /// use std::io::net::unix::UnixStream;
///
- /// let server = Path("path/to/my/socket");
- /// let mut stream = UnixStream::connect(&server);
- /// stream.write([1, 2, 3]);
- ///
- pub fn connect(path: &P) -> Option {
+ /// let server = Path::new("path/to/my/socket");
+ /// let mut stream = UnixStream::connect(&server);
+ /// stream.write([1, 2, 3]);
+ /// ```
+ pub fn connect(path: &P) -> IoResult {
LocalIo::maybe_raise(|io| {
io.unix_connect(&path.to_c_str()).map(UnixStream::new)
})
@@ -66,11 +63,11 @@ impl UnixStream {
}
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) }
}
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 {
@@ -84,23 +81,20 @@ impl UnixListener {
///
/// This listener will be closed when it falls out of scope.
///
- /// # Failure
- ///
- /// This function will raise on the `io_error` condition if the specified
- /// path could not be bound.
- ///
/// # Example
///
- /// use std::io::net::unix::UnixListener;
- ///
- /// let server = Path("path/to/my/socket");
- /// let mut stream = UnixListener::bind(&server);
- /// for client in stream.incoming() {
- /// let mut client = client;
- /// client.write([1, 2, 3, 4]);
- /// }
+ /// ```
+ /// use std::io::net::unix::UnixListener;
+ /// use std::io::Listener;
///
- pub fn bind(path: &P) -> Option {
+ /// let server = Path::new("path/to/my/socket");
+ /// let mut stream = UnixListener::bind(&server);
+ /// for client in stream.incoming() {
+ /// let mut client = client;
+ /// client.write([1, 2, 3, 4]);
+ /// }
+ /// ```
+ pub fn bind(path: &P) -> IoResult {
LocalIo::maybe_raise(|io| {
io.unix_bind(&path.to_c_str()).map(|s| UnixListener { obj: s })
})
@@ -108,14 +102,8 @@ impl UnixListener {
}
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(|obj| UnixAcceptor { obj: obj })
}
}
@@ -124,14 +112,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)
}
}
@@ -159,39 +141,29 @@ mod tests {
#[test]
fn bind_error() {
- 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() {
- let mut called = false;
- io_error::cond.trap(|e| {
- assert_eq!(e.kind,
- if cfg!(windows) {OtherIoError} else {FileNotFound});
- 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,
+ if cfg!(windows) {OtherIoError} else {FileNotFound})
+ }
}
#[test]
fn smoke() {
smalltest(proc(mut server) {
let mut buf = [0];
- server.read(buf);
+ server.read(buf).unwrap();
assert!(buf[0] == 99);
}, proc(mut client) {
- client.write([99]);
+ client.write([99]).unwrap();
})
}
@@ -199,8 +171,8 @@ 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());
+ assert!(server.read(buf).is_err());
+ assert!(server.read(buf).is_err());
}, proc(_client) {
// drop the client
})
@@ -210,15 +182,15 @@ mod tests {
fn write_begone() {
smalltest(proc(mut server) {
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);
- })
+ loop {
+ match server.write(buf) {
+ Ok(..) => {}
+ Err(e) => {
+ assert!(e.kind == BrokenPipe || e.kind == NotConnected,
+ "unknown error {:?}", e);
+ break;
+ }
+ }
}
}, proc(_client) {
// drop the client
@@ -236,7 +208,7 @@ mod tests {
port.recv();
for _ in range(0, times) {
let mut stream = UnixStream::connect(&path2);
- stream.write([100]);
+ stream.write([100]).unwrap();
}
});
@@ -245,7 +217,7 @@ mod tests {
for _ in range(0, times) {
let mut client = acceptor.accept();
let mut buf = [0];
- client.read(buf);
+ client.read(buf).unwrap();
assert_eq!(buf[0], 100);
}
}
diff --git a/src/libstd/io/option.rs b/src/libstd/io/option.rs
deleted file mode 100644
index e2eec652d9ded..0000000000000
--- a/src/libstd/io/option.rs
+++ /dev/null
@@ -1,154 +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
- }
- }
- }
-}
-
-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 prelude::*;
- use super::super::mem::*;
- use super::super::{PreviousIoError, io_error};
-
- #[test]
- fn test_option_writer() {
- let mut writer: Option = Some(MemWriter::new());
- writer.write([0, 1, 2]);
- writer.flush();
- assert_eq!(writer.unwrap().unwrap(), ~[0, 1, 2]);
- }
-
- #[test]
- fn test_option_writer_error() {
- 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() {
- let mut reader: Option = Some(MemReader::new(~[0, 1, 2, 3]));
- let mut buf = [0, 0];
- reader.read(buf);
- assert_eq!(buf, [0, 1]);
- }
-
- #[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);
- }
-}
diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs
index 9919d333f41b4..ca85707149b92 100644
--- a/src/libstd/io/pipe.rs
+++ b/src/libstd/io/pipe.rs
@@ -14,7 +14,7 @@
//! enough so that pipes can be created to child processes.
use prelude::*;
-use io::{io_error, EndOfFile};
+use io::IoResult;
use libc;
use rt::rtio::{RtioPipe, LocalIo};
@@ -32,17 +32,15 @@ impl PipeStream {
///
/// # Example
///
- /// use std::libc;
- /// use std::io::pipe;
+ /// ```rust
+ /// # #[allow(unused_must_use)];
+ /// use std::libc;
+ /// use std::io::pipe::PipeStream;
///
- /// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
- /// pipe.write(bytes!("Hello, stderr!"));
- ///
- /// # Failure
- ///
- /// If the pipe cannot be created, an error will be raised on the
- /// `io_error` condition.
- pub fn open(fd: libc::c_int) -> Option {
+ /// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
+ /// pipe.write(bytes!("Hello, stderr!"));
+ /// ```
+ pub fn open(fd: libc::c_int) -> IoResult {
LocalIo::maybe_raise(|io| {
io.pipe_open(fd).map(|obj| PipeStream { obj: obj })
})
@@ -54,29 +52,11 @@ 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) }
}
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) }
}
#[cfg(test)]
@@ -91,12 +71,12 @@ mod test {
let (p, c) = Chan::new();
spawn(proc() {
let mut out = out;
- out.write([10]);
+ out.write([10]).unwrap();
p.recv(); // don't close the pipe until the other read has finished
});
let mut buf = [0, ..10];
- input.read(buf);
+ input.read(buf).unwrap();
c.send(());
})
}
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 6a10f24916f2f..ccf3d4582def4 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -14,7 +14,7 @@ use prelude::*;
use libc;
use io;
-use io::io_error;
+use io::IoResult;
use rt::rtio::{RtioProcess, IoFactory, LocalIo};
use fmt;
@@ -93,7 +93,7 @@ pub enum ProcessExit {
impl fmt::Show 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),
@@ -118,7 +118,7 @@ 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 mut config = Some(config);
LocalIo::maybe_raise(|io| {
io.spawn(config.take_unwrap()).map(|(p, io)| {
@@ -141,14 +141,9 @@ impl Process {
/// Note that this is purely a wrapper around libuv's `uv_process_kill`
/// 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)
- }
- }
+ /// If the signal delivery fails, the corresponding error is returned.
+ pub fn signal(&mut self, signal: int) -> IoResult<()> {
+ self.handle.kill(signal)
}
/// Wait for the child to exit completely, returning the status that it
@@ -176,7 +171,6 @@ impl Drop for Process {
mod tests {
use io::process::{ProcessConfig, Process};
use prelude::*;
- use str;
// FIXME(#10380)
#[cfg(unix, not(target_os="android"))]
@@ -190,7 +184,7 @@ mod tests {
io: io,
};
let p = Process::new(args);
- assert!(p.is_some());
+ assert!(p.is_ok());
let mut p = p.unwrap();
assert!(p.wait().success());
})
@@ -206,7 +200,7 @@ mod tests {
cwd: None,
io: io,
};
- match io::result(|| Process::new(args)) {
+ match Process::new(args) {
Ok(..) => fail!(),
Err(..) => {}
}
@@ -224,7 +218,7 @@ mod tests {
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));
})
@@ -240,7 +234,7 @@ mod tests {
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) => {},
@@ -249,20 +243,12 @@ mod tests {
})
pub 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.push_str(str::from_utf8(buf.slice_to(n)).unwrap()); }
- }
- }
- return ret;
+ input.read_to_str().unwrap()
}
pub 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());
@@ -312,8 +298,8 @@ mod tests {
cwd: None,
io: io,
};
- let mut p = Process::new(args).expect("didn't create a proces?!");
- p.io[0].get_mut_ref().write("foobar".as_bytes());
+ let mut p = Process::new(args).unwrap();
+ p.io[0].get_mut_ref().write("foobar".as_bytes()).unwrap();
p.io[0] = None; // close stdin;
let out = read_all(p.io[1].get_mut_ref() as &mut Reader);
assert!(p.wait().success());
diff --git a/src/libstd/io/result.rs b/src/libstd/io/result.rs
new file mode 100644
index 0000000000000..8e03cffd0fb24
--- /dev/null
+++ b/src/libstd/io/result.rs
@@ -0,0 +1,128 @@
+// 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