diff --git a/src/lib.rs b/src/lib.rs index e5ac623..a551146 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,37 +1,69 @@ -use std::env; +use std::{env, fmt, result}; use std::process::exit; use std::error::Error; use std::path::PathBuf; use std::fs::File; -use std::io::{Write, BufRead, BufReader}; +use std::io::{self, Write, BufRead, BufReader}; use colored::*; -pub fn git_dir() -> String { - match env::var("GCLONE_PATH") { - Ok(path) => path, - Err(e) => { - eprintln!("{} {} {}", - "error:".bold().red(), - "environment variable GCLONE_PATH must be set:".bold(), - e.description()); - - exit(1); - }, +macro_rules! impl_from_error { + ($type: ty, $variant: path, $from: ty) => { + impl From<$from> for $type { + fn from(e: $from) -> $type { + $variant(e) + } + } } } +#[derive(Debug)] +pub enum MError { + NoGclonePath(env::VarError), + IoError(io::Error), +} + +impl_from_error!(MError, MError::NoGclonePath, env::VarError); +impl_from_error!(MError, MError::IoError, io::Error); + +impl fmt::Display for MError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match self { + MError::NoGclonePath(e) => + write!(fmt, "{} {} {}", + "error:".bold().red(), + "couldn't read environment variable GCLONE_PATH".bold(), + e), + MError::IoError(e) => + write!(fmt, "{} {} {}", + "error:".bold().red(), + "couldn't read or write cache:".bold(), + e), + } + } +} + +impl Error for MError { + +} + +type Result = result::Result; + +pub fn git_dir() -> Result { + Ok(env::var("GCLONE_PATH")?) +} + pub struct Cache(Vec); impl Cache { - pub fn read() -> Cache { + pub fn read() -> Result { - let mut path = PathBuf::from(git_dir()); + let mut path = PathBuf::from(git_dir()?); path.push(".cdgcache"); let file = match File::open(&path) { Ok(f) => f, - Err(_) => return Cache(vec![]), + Err(_) => return Ok(Cache(vec![])), }; let file = BufReader::new(file); @@ -44,11 +76,11 @@ impl Cache { } } - Cache(values) + Ok(Cache(values)) } - pub fn write(&self) -> Result<(), Box> { - let mut path = PathBuf::from(git_dir()); + pub fn write(&self) -> Result<()> { + let mut path = PathBuf::from(git_dir()?); path.push(".cdgcache"); let mut file = File::create(path)?;