use nom::{IResult, alpha, digit, space, rest};
use regex::{Regex, RegexBuilder};
use chrono::{Date, UTC, Datelike};
use term;
use toml;
use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::io;
use std::iter;
use std::str;
use config::Config;
#[derive(Debug)]
pub enum Error {
CommitMessageLength,
FooterParsing(String),
Io(io::Error),
ParagraphParsing(String),
SummaryParsing(String),
Terminal,
Toml(toml::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::CommitMessageLength => write!(f, "Commit message length too small."),
Error::FooterParsing(ref line) => write!(f, "Footer parsing: '{}'", line),
Error::Io(ref e) => write!(f, "Io: {}", e),
Error::ParagraphParsing(ref line) => write!(f, "Paragraph parsing: '{}'", line),
Error::SummaryParsing(ref line) => write!(f, "Summary parsing: '{}'", line),
Error::Terminal => write!(f, "Could not print to terminal."),
Error::Toml(ref e) => write!(f, "Toml: {}", e),
}
}
}
impl From<term::Error> for Error {
#[allow(unused_variables)]
fn from(err: term::Error) -> Error {
Error::Terminal
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}
impl From<toml::Error> for Error {
fn from(err: toml::Error) -> Error {
Error::Toml(err)
}
}
#[derive(PartialEq)]
pub enum Printed {
Nothing,
Something,
}
pub trait Print {
fn print<T: Write, F, G, H>(&self,
t: &mut T,
config: &Config,
tag: Option<&str>,
c1: &F,
c2: &G,
c3: &H)
-> Result<Printed, Error>
where F: Fn(&mut T) -> Result<(), Error>,
G: Fn(&mut T) -> Result<(), Error>,
H: Fn(&mut T) -> Result<(), Error>;
fn print_default<T: Write>(&self, t: &mut T, config: &Config, tag: Option<&str>) -> Result<(), Error> {
try!(self.print(t, config, tag, &|_| Ok(()), &|_| Ok(()), &|_| Ok(())));
Ok(())
}
fn print_default_term(&self,
mut t: &mut Box<term::StdoutTerminal>,
config: &Config,
tag: Option<&str>)
-> Result<(), Error> {
try!(self.print(&mut t,
config,
tag,
&|t| {
try!(t.fg(term::color::BRIGHT_BLUE));
Ok(())
},
&|t| {
try!(t.fg(term::color::WHITE));
Ok(())
},
&|t| {
try!(t.reset());
Ok(())
}));
Ok(())
}
fn contains_tag(&self, tag: Option<&str>) -> bool;
fn contains_untagged_elements(&self) -> bool;
fn matches_default_tag(&self, tag: Option<&str>) -> bool {
match tag {
Some(tag) => tag == "default" && self.contains_untagged_elements(),
None => false,
}
}
fn should_be_printed(&self, tag: Option<&str>) -> bool {
self.contains_tag(tag) || self.matches_default_tag(tag)
}
fn print_to_term_and_write_to_vector(&self,
mut term: &mut Box<term::StdoutTerminal>,
mut vec: &mut Vec<u8>,
config: &Config,
tag: Option<&str>)
-> Result<(), Error> {
try!(self.print_default_term(&mut term, config