std: Remove io::io_error

* All I/O now returns IoResult<T> = Result<T, IoError>
* All formatting traits now return fmt::Result = IoResult<()>
* The if_ok!() macro was added to libstd
This commit is contained in:
Alex Crichton
2014-01-29 16:33:57 -08:00
parent be4fc63809
commit ece8a8f520
35 changed files with 918 additions and 1059 deletions

View File

@@ -28,7 +28,7 @@ out.write(bytes!("Hello, world!"));
use container::Container;
use fmt;
use io::{Reader, Writer, io_error, IoError, OtherIoError,
use io::{Reader, Writer, IoResult, IoError, OtherIoError,
standard_error, EndOfFile, LineBufferedWriter};
use libc;
use option::{Option, Some, None};
@@ -114,7 +114,8 @@ fn reset_helper(w: ~Writer,
match f(t.get(), w) {
Some(mut w) => {
drop(t);
w.flush();
// FIXME: is failing right here?
w.flush().unwrap();
Some(w)
}
None => None
@@ -155,9 +156,9 @@ pub fn set_stderr(stderr: ~Writer) -> Option<~Writer> {
// // io1 aliases io2
// })
// })
fn with_task_stdout(f: |&mut Writer|) {
fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
let task: Option<~Task> = Local::try_take();
match task {
let result = match task {
Some(mut task) => {
// Printing may run arbitrary code, so ensure that the task is in
// TLS to allow all std services. Note that this means a print while
@@ -169,7 +170,7 @@ fn with_task_stdout(f: |&mut Writer|) {
if my_stdout.is_none() {
my_stdout = Some(~LineBufferedWriter::new(stdout()) as ~Writer);
}
f(*my_stdout.get_mut_ref());
let ret = f(*my_stdout.get_mut_ref());
// Note that we need to be careful when putting the stdout handle
// back into the task. If the handle was set to `Some` while
@@ -184,22 +185,29 @@ fn with_task_stdout(f: |&mut Writer|) {
let prev = util::replace(&mut t.get().stdout, my_stdout);
drop(t);
drop(prev);
ret
}
None => {
struct Stdout;
impl Writer for Stdout {
fn write(&mut self, data: &[u8]) {
fn write(&mut self, data: &[u8]) -> IoResult<()> {
unsafe {
libc::write(libc::STDOUT_FILENO,
data.as_ptr() as *libc::c_void,
data.len() as libc::size_t);
}
Ok(()) // just ignore the results
}
}
let mut io = Stdout;
f(&mut io as &mut Writer);
f(&mut io as &mut Writer)
}
};
match result {
Ok(()) => {}
Err(e) => fail!("failed printing to stdout: {}", e),
}
}
@@ -226,8 +234,7 @@ pub fn print(s: &str) {
/// `\n` character is printed to the console after the string.
pub fn println(s: &str) {
with_task_stdout(|io| {
io.write(s.as_bytes());
io.write(['\n' as u8]);
io.write(s.as_bytes()).and_then(|()| io.write(['\n' as u8]))
})
}
@@ -249,7 +256,7 @@ pub struct StdReader {
}
impl Reader for StdReader {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
let ret = match self.inner {
TTY(ref mut tty) => tty.read(buf),
File(ref mut file) => file.read(buf).map(|i| i as uint),
@@ -260,15 +267,8 @@ impl Reader for StdReader {
// return an actual EOF error, but apparently for stdin it's a
// little different. Hence, here we convert a 0 length read to an
// end-of-file indicator so the caller knows to stop reading.
Ok(0) => {
io_error::cond.raise(standard_error(EndOfFile));
None
}
Ok(amt) => Some(amt),
Err(e) => {
io_error::cond.raise(e);
None
}
Ok(0) => { Err(standard_error(EndOfFile)) }
ret @ Ok(..) | ret @ Err(..) => ret,
}
}
}
@@ -289,24 +289,15 @@ impl StdWriter {
///
/// This function will raise on the `io_error` condition if an error
/// happens.
pub fn winsize(&mut self) -> Option<(int, int)> {
pub fn winsize(&mut self) -> IoResult<(int, int)> {
match self.inner {
TTY(ref mut tty) => {
match tty.get_winsize() {
Ok(p) => Some(p),
Err(e) => {
io_error::cond.raise(e);
None
}
}
}
TTY(ref mut tty) => tty.get_winsize(),
File(..) => {
io_error::cond.raise(IoError {
Err(IoError {
kind: OtherIoError,
desc: "stream is not a tty",
detail: None,
});
None
})
}
}
}
@@ -318,20 +309,15 @@ impl StdWriter {
///
/// This function will raise on the `io_error` condition if an error
/// happens.
pub fn set_raw(&mut self, raw: bool) {
pub fn set_raw(&mut self, raw: bool) -> IoResult<()> {
match self.inner {
TTY(ref mut tty) => {
match tty.set_raw(raw) {
Ok(()) => {},
Err(e) => io_error::cond.raise(e),
}
}
TTY(ref mut tty) => tty.set_raw(raw),
File(..) => {
io_error::cond.raise(IoError {
Err(IoError {
kind: OtherIoError,
desc: "stream is not a tty",
detail: None,
});
})
}
}
}
@@ -346,14 +332,10 @@ impl StdWriter {
}
impl Writer for StdWriter {
fn write(&mut self, buf: &[u8]) {
let ret = match self.inner {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
match self.inner {
TTY(ref mut tty) => tty.write(buf),
File(ref mut file) => file.write(buf),
};
match ret {
Ok(()) => {}
Err(e) => io_error::cond.raise(e)
}
}
}