From 6c5916af57d44abbd0e238ea3d8984e193521723 Mon Sep 17 00:00:00 2001 From: Konstantin Stepanov Date: Sun, 29 Mar 2015 08:39:31 +0300 Subject: [PATCH] errors --- src/lib.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++-------- src/main.rs | 2 +- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 33b2714..7bf2cc4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,9 +6,10 @@ use std::ops::Add; use std::fs::File; use std::io::{self, Lines, BufReader, BufRead}; use std::iter::{Iterator, Enumerate}; -use std::error::FromError; +use std::error::{FromError, Error}; use std::convert::AsRef; use std::path::Path; +use std::fmt::{self, Display, Formatter}; pub trait Limited: Add + PartialOrd + Copy { fn min_value() -> Self; @@ -38,40 +39,83 @@ impl CrontabFile { } #[derive(Debug)] -pub enum CrontabFileError { +pub enum CrontabFileErrorKind { Io(io::Error), Parse(crontab::CrontabEntryParseError) } +#[derive(Debug)] +pub struct CrontabFileError { + pub lineno: usize, + pub line: String, + pub kind: CrontabFileErrorKind +} + impl FromError for CrontabFileError { fn from_error(err: io::Error) -> CrontabFileError { - CrontabFileError::Io(err) + CrontabFileError { + lineno: 0, + line: "".to_string(), + kind: CrontabFileErrorKind::Io(err) + } } } impl FromError for CrontabFileError { fn from_error(err: crontab::CrontabEntryParseError) -> CrontabFileError { - CrontabFileError::Parse(err) + CrontabFileError { + lineno: 0, + line: "".to_string(), + kind: CrontabFileErrorKind::Parse(err) + } } } +impl Error for CrontabFileError { + fn description(&self) -> &str { + &"error parsing crontab"[..] + } + + fn cause(&self) -> Option<&Error> { + // match self.kind { + // CrontabFileErrorKind::Parse(ref e) => Some(e as &Error), + // CrontabFileErrorKind::Io(ref e) => Some(e as &Error) + // } + None + } +} + +impl Display for CrontabFileError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "error parsing crontab at line {} ({:?}): {:?}", self.lineno, self.line, self.kind) + } +} impl Iterator for CrontabFile { - type Item = Result; - fn next(&mut self) -> Option> { + type Item = Result; + fn next(&mut self) -> Option> { loop { match self.lines.next() { - Some((l, Ok(line))) => { + Some((lineno, Ok(line))) => { if line.len() == 0 || line.starts_with("#") || line.chars().all(|c| c == ' ' || c == '\t') { continue; } return Some(match line.parse::() { Ok(envvar) => Ok(crontab::CrontabEntry::EnvVar(envvar)), - _ => line.parse::().map_err(|e| (l, FromError::from_error(e))).map(crontab::ToCrontabEntry::to_crontab_entry) + _ => line.parse::().map_err(|e| { + let mut err: CrontabFileError = FromError::from_error(e); + err.lineno = lineno + 1; + err.line = line.to_string(); + err + }).map(crontab::ToCrontabEntry::to_crontab_entry) }); }, - Some((l, Err(e))) => return Some(Err((l, FromError::from_error(e)))), + Some((lineno, Err(e))) => { + let mut err: CrontabFileError = FromError::from_error(e); + err.lineno = lineno + 1; + return Some(Err(err)); + }, None => return None } } diff --git a/src/main.rs b/src/main.rs index 7420c5d..a60156b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ fn main() { for line in file { match line { Ok(entry) => generate_systemd_units(entry), - Err((lineno, error)) => panic!("error in {}:{}: {:?}", filename, lineno, error) + Err(error) => panic!("At file {}: {}", filename, error) } } }