use crate::candidate_error::CandidateError;
use crate::candidate_prediction::{CandidateRequest, PreparedCandidates, prepare_candidates};
use crate::repository_facts::RepositoryFacts;
use crate::repository_location::RepositoryLocation;
use crate::rule_commit_index::IndexVsHead;
use crate::rule_commit_sequencer::SequencerState;
use crate::rule_worktree_dirty::DirtyScope;
use crate::transaction_git::GitContext;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
const INDEX_FILE_VARIABLE: &str = "GIT_INDEX_FILE";
const OBJECT_DIRECTORY_VARIABLE: &str = "GIT_OBJECT_DIRECTORY";
pub struct PrivateIndexFacts<F: RepositoryFacts> {
inner: F,
private: Vec<(OsString, OsString)>,
}
impl<F: RepositoryFacts> PrivateIndexFacts<F> {
pub fn new(inner: F, index: &Path, object_directory: &Path) -> Self {
return PrivateIndexFacts {
inner,
private: private_entries(index, object_directory),
};
}
pub fn use_index(&mut self, index: &Path, object_directory: &Path) {
self.private = private_entries(index, object_directory);
}
}
fn private_entries(index: &Path, object_directory: &Path) -> Vec<(OsString, OsString)> {
return vec![
(OsString::from(INDEX_FILE_VARIABLE), index.as_os_str().to_os_string()),
(
OsString::from(OBJECT_DIRECTORY_VARIABLE),
object_directory.as_os_str().to_os_string(),
),
];
}
impl<F: RepositoryFacts> RepositoryFacts for PrivateIndexFacts<F> {
fn location(&mut self) -> Result<RepositoryLocation, String> {
return self.inner.location();
}
fn index_vs_head(&mut self) -> Result<IndexVsHead, String> {
return self.inner.index_vs_head();
}
fn worktree_dirty(&mut self, scope: DirtyScope) -> Result<bool, String> {
return self.inner.worktree_dirty(scope);
}
fn sequencer_state(&mut self) -> Result<SequencerState, String> {
return self.inner.sequencer_state();
}
fn remote_guess_creates_branch(&mut self, target: &OsStr) -> Result<bool, String> {
return self.inner.remote_guess_creates_branch(target);
}
fn candidates(&mut self, request: &CandidateRequest) -> Result<PreparedCandidates, CandidateError> {
let context: GitContext = self.inner.transaction_context();
let mut overlay: Vec<(OsString, OsString)> = context.overlay.clone();
overlay.extend(self.private.iter().cloned());
return prepare_candidates(
context.real_git.as_path(),
context.global_prefix.as_slice(),
overlay.as_slice(),
request,
);
}
fn asked_location(&self) -> Option<Result<RepositoryLocation, String>> {
return self.inner.asked_location();
}
fn transaction_context(&self) -> GitContext {
return self.inner.transaction_context();
}
}
impl<F: RepositoryFacts> RepositoryFacts for &mut F {
fn location(&mut self) -> Result<RepositoryLocation, String> {
return (**self).location();
}
fn index_vs_head(&mut self) -> Result<IndexVsHead, String> {
return (**self).index_vs_head();
}
fn worktree_dirty(&mut self, scope: DirtyScope) -> Result<bool, String> {
return (**self).worktree_dirty(scope);
}
fn sequencer_state(&mut self) -> Result<SequencerState, String> {
return (**self).sequencer_state();
}
fn remote_guess_creates_branch(&mut self, target: &OsStr) -> Result<bool, String> {
return (**self).remote_guess_creates_branch(target);
}
fn candidates(&mut self, request: &CandidateRequest) -> Result<PreparedCandidates, CandidateError> {
return (**self).candidates(request);
}
fn asked_location(&self) -> Option<Result<RepositoryLocation, String>> {
return (**self).asked_location();
}
fn known_common_dir(&mut self) -> Option<PathBuf> {
return (**self).known_common_dir();
}
fn known_git_dir(&mut self) -> Option<PathBuf> {
return (**self).known_git_dir();
}
fn transaction_context(&self) -> GitContext {
return (**self).transaction_context();
}
}
#[cfg(test)]
#[path = "commit_facts_tests.rs"]
mod tests;