grass/dev/
repository.rs

1use std::{
2    fmt::Display,
3    path::{Path, PathBuf},
4};
5
6use git2::{Repository, Status};
7
8pub enum RepositoryChangeStatus {
9    UpToDate,
10    NoRepository,
11    UncommittedChanges(usize),
12}
13
14pub enum GetRepositoryChangersError {
15    CannotOpenRepository { path: PathBuf, reason: String },
16    CannotReadStatus { path: PathBuf, reason: String },
17}
18
19pub fn get_repository_changes<T>(
20    path: T,
21) -> Result<RepositoryChangeStatus, GetRepositoryChangersError>
22where
23    T: AsRef<Path>,
24{
25    let repository = Repository::open(path.as_ref());
26    let repository = match repository {
27        Ok(repository) => repository,
28        Err(error) => match error.code() {
29            git2::ErrorCode::NotFound => todo!(),
30            _ => {
31                return Err(GetRepositoryChangersError::CannotOpenRepository {
32                    path: path.as_ref().into(),
33                    reason: error.message().to_string(),
34                })
35            }
36        },
37    };
38
39    let statuses = repository.statuses(None);
40    let statuses = match statuses {
41        Ok(statuses) => statuses,
42        Err(error) => {
43            return Err(GetRepositoryChangersError::CannotReadStatus {
44                path: path.as_ref().into(),
45                reason: error.message().to_string(),
46            })
47        }
48    };
49    match statuses
50        .iter()
51        .filter(|status| !matches!(status.status(), Status::IGNORED))
52        .count()
53    {
54        0 => Ok(RepositoryChangeStatus::UpToDate),
55        num_changes => Ok(RepositoryChangeStatus::UncommittedChanges(num_changes)),
56    }
57}
58
59impl Display for RepositoryChangeStatus {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        match self {
62            RepositoryChangeStatus::UpToDate => write!(f, "No changes"),
63            RepositoryChangeStatus::NoRepository => write!(f, "No repository"),
64            RepositoryChangeStatus::UncommittedChanges(n) => write!(f, "{} uncommitted changes", n),
65        }
66    }
67}