From c7319caf38ff22e67f6fb625411ed554cf3b1f92 Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Sun, 27 Nov 2022 19:23:11 -0600 Subject: feat: improve Project trait --- src/project/error.rs | 11 +++++++++++ src/project/git.rs | 34 ++++++++++++++++++++++------------ src/project/path.rs | 41 +++++++---------------------------------- 3 files changed, 40 insertions(+), 46 deletions(-) create mode 100644 src/project/error.rs (limited to 'src/project') diff --git a/src/project/error.rs b/src/project/error.rs new file mode 100644 index 0000000..7047533 --- /dev/null +++ b/src/project/error.rs @@ -0,0 +1,11 @@ +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + IO(#[from] std::io::Error), + + #[error(transparent)] + Git(#[from] git2::Error), + + #[error(transparent)] + SystemTime(#[from] std::time::SystemTimeError), +} diff --git a/src/project/git.rs b/src/project/git.rs index f1c4d5a..00cd000 100644 --- a/src/project/git.rs +++ b/src/project/git.rs @@ -1,8 +1,11 @@ -use crate::{Error, Project}; use git2::{BranchType, Repository}; use ignore::DirEntry; use std::{cmp::Ordering, path::PathBuf, time::Duration}; +use crate::project::Error; +use crate::project::Timestamp; +use crate::Project; + #[derive(Debug, Clone)] pub struct GitProject { path_buf: PathBuf, @@ -11,19 +14,19 @@ pub struct GitProject { impl GitProject { fn new(path_buf: PathBuf) -> Result { - let repository = Repository::open(&path_buf)?; - let latest_commit = Self::latest_commit(&repository); + let latest_commit = Self::latest_commit(&path_buf).ok(); Ok(Self { path_buf, latest_commit, }) } - fn latest_commit(repository: &Repository) -> Option { - let mut branches = repository.branches(Some(BranchType::Local)).ok()?; + fn latest_commit(path_buf: &PathBuf) -> Result { + let repository = Repository::open(path_buf)?; + let mut branches = repository.branches(Some(BranchType::Local))?; branches .try_fold(0, |latest, branch| { - let branch = branch?.0; + let (branch, _) = branch?; let name = branch .name()? @@ -35,17 +38,24 @@ impl GitProject { .map(|c| (c.time().seconds() as u64).max(latest)) }) .map(Duration::from_secs) - .ok() + .map_err(Into::into) } } -impl Project for GitProject { - fn timestamp(&self) -> Option { - self.latest_commit +impl Timestamp for GitProject { + type Error = Error; + + fn timestamp(&self) -> Result { + match self.latest_commit { + Some(t) => Ok(t), + None => Self::latest_commit(&self.path_buf), + } } +} - fn to_path_buf(&self) -> PathBuf { - self.path_buf.to_owned() +impl Project for GitProject { + fn to_path_buf(&self) -> &PathBuf { + &self.path_buf } } diff --git a/src/project/path.rs b/src/project/path.rs index 24dad9d..14ce308 100644 --- a/src/project/path.rs +++ b/src/project/path.rs @@ -1,39 +1,18 @@ use ignore::DirEntry; -use std::{ - path::PathBuf, - time::{Duration, SystemTime}, -}; - -use crate::Project; +use std::path::PathBuf; #[derive(Debug, PartialEq, Eq, Clone, Default)] -pub struct PathProject { - path_buf: PathBuf, - timestamp: Option, -} +pub struct PathProject(PathBuf); impl PathProject { fn new(path_buf: PathBuf) -> Self { - let timestamp = path_buf - .metadata() - .ok() - .and_then(|m| m.modified().ok()) - .and_then(|t| t.duration_since(SystemTime::UNIX_EPOCH).ok()); - - Self { - timestamp, - path_buf, - } + Self(path_buf) } } -impl Project for PathProject { - fn timestamp(&self) -> Option { - self.timestamp - } - - fn to_path_buf(&self) -> PathBuf { - self.path_buf.to_owned() +impl AsRef for PathProject { + fn as_ref(&self) -> &PathBuf { + &self.0 } } @@ -55,12 +34,6 @@ impl TryFrom<(&String, DirEntry)> for PathProject { } } -impl From for PathProject { - fn from(value: PathBuf) -> Self { - Self::new(value) - } -} - impl From for PathProject { fn from(value: DirEntry) -> Self { Self::new(value.into_path()) @@ -69,6 +42,6 @@ impl From for PathProject { impl From for PathBuf { fn from(value: PathProject) -> Self { - value.path_buf + value.0 } } -- cgit v1.2.3-70-g09d2