From 4ce03bf5f95c9b5099c890ac9de68596c5a3b1ff Mon Sep 17 00:00:00 2001 From: Till Hoeppner Date: Fri, 24 Jul 2015 00:02:16 +0200 Subject: Half-decent error reporting --- src/lib.rs | 27 +++++++++++++++++++++++++++ src/main.rs | 25 ++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7e4de8b..55ebdf8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,8 @@ pub mod context; use std::convert::From; use std::{ io, result }; +use std::error::Error; +use std::fmt::{ self, Display, Formatter }; use chrono::format::ParseError; @@ -41,6 +43,31 @@ pub enum IlcError { Io(io::Error) } +impl Display for IlcError { + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + fmt.write_str(self.description()) + } +} + +impl Error for IlcError { + fn description(&self) -> &str { + use IlcError::*; + match self { + &Parse(_) => "error while parsing", + &Chrono(_) => "error while parsing time strings", + &BincodeDecode => "error while decoding from binary", + &BincodeEncode => "error while encoding to binary", + &Io(_) => "error during input/output" + } + } + + fn cause(&self) -> Option<&Error> { + match self { + _ => None + } + } +} + impl From for IlcError { fn from(err: ParseError) -> IlcError { IlcError::Chrono(err) } } diff --git a/src/main.rs b/src/main.rs index 980650f..1f22995 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ extern crate env_logger; use std::process; use std::io::{ self, BufReader }; use std::fs::File; +use std::error::Error; use std::str::FromStr; use docopt::Docopt; @@ -35,7 +36,6 @@ use docopt::Docopt; use chrono::offset::fixed::FixedOffset; use chrono::naive::date::NaiveDate; -use ilc::event::Event; use ilc::context::Context; use ilc::format::{ self, Encode, Decode, DecodeBox }; @@ -78,6 +78,16 @@ struct Args { flag_channel: Option } +fn error(e: Box) -> ! { + println!("{}", e.description()); + let mut e = e.cause(); + while let Some(err) = e { + println!("\t{}", err.description()); + e = err.cause(); + } + process::exit(1) +} + fn main() { env_logger::init().unwrap(); let args: Args = Docopt::new(USAGE) @@ -112,12 +122,17 @@ fn main() { let informat = args.arg_informat.expect("Must provide informat"); let outformat = args.arg_outformat.expect("Must provide outformat"); - let mut parser = format::decoder(&informat).expect("Decoder not available"); - let formatter = format::encoder(&outformat).expect("Encoder not available"); + let mut decoder = format::decoder(&informat).expect("Decoder not available"); + let encoder = format::encoder(&outformat).expect("Encoder not available"); let mut lock = stdin.lock(); - for e in parser.decode_box(&context, &mut lock) { - drop(formatter.encode(&context, &mut io::stdout(), &e.unwrap())) + for e in decoder.decode_box(&context, &mut lock) { + match e { + Ok(e) => { + let _ = encoder.encode(&context, &mut io::stdout(), &e); + }, + Err(e) => error(Box::new(e)) + } } } } -- cgit v1.2.3