#![allow(clippy::result_large_err)]
use std::borrow::Cow;
use git_features::threading::OwnShared;
use crate::{
bstr::BStr,
config::{CommitAutoRollback, Snapshot, SnapshotMut},
};
impl<'repo> Snapshot<'repo> {
pub fn boolean<'a>(&self, key: impl Into<&'a BStr>) -> Option<bool> {
self.try_boolean(key).and_then(Result::ok)
}
pub fn try_boolean<'a>(&self, key: impl Into<&'a BStr>) -> Option<Result<bool, git_config::value::Error>> {
self.repo.config.resolved.boolean_by_key(key)
}
pub fn integer<'a>(&self, key: impl Into<&'a BStr>) -> Option<i64> {
self.try_integer(key).and_then(Result::ok)
}
pub fn try_integer<'a>(&self, key: impl Into<&'a BStr>) -> Option<Result<i64, git_config::value::Error>> {
self.repo.config.resolved.integer_by_key(key)
}
pub fn string<'a>(&self, key: impl Into<&'a BStr>) -> Option<Cow<'_, BStr>> {
self.repo.config.resolved.string_by_key(key)
}
pub fn trusted_path<'a>(
&self,
key: impl Into<&'a BStr>,
) -> Option<Result<Cow<'_, std::path::Path>, git_config::path::interpolate::Error>> {
let key = git_config::parse::key(key)?;
self.repo
.config
.trusted_file_path(key.section_name, key.subsection_name, key.value_name)
}
}
impl<'repo> Snapshot<'repo> {
pub fn plumbing(&self) -> &git_config::File<'static> {
&self.repo.config.resolved
}
}
impl<'repo> SnapshotMut<'repo> {
pub fn append_config(
&mut self,
values: impl IntoIterator<Item = impl AsRef<BStr>>,
source: git_config::Source,
) -> Result<&mut Self, crate::config::overrides::Error> {
crate::config::overrides::append(&mut self.config, values, source, |v| Some(format!("-c {v}").into()))?;
Ok(self)
}
pub fn commit(mut self) -> Result<&'repo mut crate::Repository, crate::config::Error> {
let repo = self.repo.take().expect("always present here");
self.commit_inner(repo)
}
pub(crate) fn commit_inner(
&mut self,
repo: &'repo mut crate::Repository,
) -> Result<&'repo mut crate::Repository, crate::config::Error> {
repo.reread_values_and_clear_caches_replacing_config(std::mem::take(&mut self.config).into())?;
Ok(repo)
}
pub fn commit_auto_rollback(mut self) -> Result<CommitAutoRollback<'repo>, crate::config::Error> {
let repo = self.repo.take().expect("this only runs once on consumption");
let prev_config = OwnShared::clone(&repo.config.resolved);
Ok(CommitAutoRollback {
repo: self.commit_inner(repo)?.into(),
prev_config,
})
}
pub fn forget(mut self) -> git_config::File<'static> {
self.repo.take();
std::mem::take(&mut self.config)
}
}
impl<'repo> CommitAutoRollback<'repo> {
pub fn rollback(mut self) -> Result<&'repo mut crate::Repository, crate::config::Error> {
let repo = self.repo.take().expect("still present, consumed only once");
self.rollback_inner(repo)
}
pub(crate) fn rollback_inner(
&mut self,
repo: &'repo mut crate::Repository,
) -> Result<&'repo mut crate::Repository, crate::config::Error> {
repo.reread_values_and_clear_caches_replacing_config(OwnShared::clone(&self.prev_config))?;
Ok(repo)
}
}