use errors::Error;
use std::env::current_dir;
use std::fmt::{self, Display, Formatter};
use std::fs::File;
use std::io::{BufRead, BufReader};
#[derive(Debug,Clone,Copy,PartialEq)]
pub struct Source {
pub filename: &'static str,
pub line: u32,
pub column: u32,
}
pub struct ErrRenderer<'a> {
pub err: &'a Error,
pub src: Option<Source>,
pub msg: Option<String>,
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let renderer = ErrRenderer {
err: self,
src: None,
msg: None,
};
Display::fmt(&renderer, f)
}
}
impl<'a> Display for ErrRenderer<'a> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let &Error { ref got, ref kind } = self.err;
writeln!(f, "")?;
writeln!(f, "error[]: assertion failed")?;
if let Some(Source { filename, line, column }) = self.src {
writeln!(f, " --> {}:{}:{}", filename, line, column)?;
let file_path = current_dir().unwrap().join(filename);
if let Ok(buf) = BufReader::new(File::open(&file_path).unwrap())
.lines()
.skip(line as usize - 1)
.next()
.unwrap() {
writeln!(f, " |")?;
writeln!(f, "{line:<width$}| {}", buf, line = line, width = 3)?;
writeln!(f, " | {:<column$} ^^^^", ' ', column = column as usize)?;
}
}
if let Some(ref msg) = self.msg {
writeln!(f, "{}", msg)?;
}
writeln!(f, "")?;
writeln!(f, "Got: {:?}", got)?;
write!(f, "\n{:?} {}\n\n", got, kind)
}
}