use std::io::{Read, Result, copy, stdout}; use std::env::args_os; use std::process::exit; use std::ffi::OsString; use std::fs::File; use std::path::Path; extern crate concat; use concat::concat; fn main() { let mut args = args_os(); let progname = args.next().unwrap_or_else(|| OsString::from("cat")); let mut c = concat(args.map(InputSource::from)); let res = copy(&mut c, &mut stdout()); if let Err(e) = res { match c.current() { None => { println!("{}: {}\n", AsRef::::as_ref(&progname).display(), e); }, Some(ref f) => { println!("{}: {}: {}\n", AsRef::::as_ref(&progname).display(), f.path().display(), e); }, }; exit(1); } } struct InputSource { path: OsString, file: Option, } impl InputSource { pub fn path(&self) -> &Path { self.path.as_ref() } } impl From for InputSource { fn from(path: OsString) -> InputSource { InputSource { path: path, file: None, } } } impl Read for InputSource { fn read(&mut self, buf: &mut [u8]) -> Result { if self.file.is_none() { self.file = Some(try!(File::open(&self.path))); } self.file.as_mut().unwrap().read(buf) } }