119 lines
2.7 KiB
Rust
119 lines
2.7 KiB
Rust
use std::{env, fmt, result};
|
|
use std::error::Error;
|
|
use std::path::PathBuf;
|
|
use std::fs::File;
|
|
use std::io::{self, Write, BufRead, BufReader};
|
|
|
|
use colored::*;
|
|
use walkdir::WalkDir;
|
|
|
|
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 {}
|
|
|
|
pub type Result<T> = result::Result<T, MError>;
|
|
|
|
pub fn git_dir() -> Result<String> {
|
|
Ok(env::var("GCLONE_PATH")?)
|
|
}
|
|
|
|
pub struct Cache(Vec<String>);
|
|
|
|
impl Cache {
|
|
|
|
pub fn new() -> Result<Cache> {
|
|
Ok(Cache(WalkDir::new(git_dir()?)
|
|
.max_depth(3)
|
|
.into_iter()
|
|
.filter_map(|x| x.ok())
|
|
.map(|x| x.path().display().to_string())
|
|
.collect()))
|
|
}
|
|
|
|
pub fn read() -> Result<Cache> {
|
|
|
|
let mut path = PathBuf::from(git_dir()?);
|
|
path.push(".cdgcache");
|
|
|
|
let file = match File::open(&path) {
|
|
Ok(f) => f,
|
|
Err(_) => return Ok(Cache(vec![])),
|
|
};
|
|
|
|
let file = BufReader::new(file);
|
|
|
|
let mut values = vec![];
|
|
|
|
for line in file.lines() {
|
|
if let Ok(l) = line {
|
|
values.push(l);
|
|
}
|
|
}
|
|
|
|
Ok(Cache(values))
|
|
}
|
|
|
|
pub fn write(&self) -> Result<()> {
|
|
let mut path = PathBuf::from(git_dir()?);
|
|
path.push(".cdgcache");
|
|
let mut file = File::create(path)?;
|
|
|
|
for line in &self.0 {
|
|
writeln!(file, "{}", line)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn find(&self, dirname: &str) -> Vec<String> {
|
|
let dirname = &format!("/{}", dirname);
|
|
let mut matches = vec![];
|
|
for line in &self.0 {
|
|
if line.ends_with(dirname) {
|
|
matches.push(line.clone());
|
|
}
|
|
}
|
|
|
|
matches
|
|
}
|
|
|
|
pub fn append(&mut self, value: String) {
|
|
self.0.push(value);
|
|
}
|
|
}
|
|
|