use crate::{
config::{cache::util::ApplyLeniency, tree::Diff},
diff::rename::Tracking,
object::tree::diff::Rewrites,
};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum CopySource {
FromSetOfModifiedFiles,
FromSetOfModifiedFilesAndSourceTree,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Copies {
pub source: CopySource,
pub percentage: Option<f32>,
}
impl Default for Copies {
fn default() -> Self {
Copies {
source: CopySource::FromSetOfModifiedFiles,
percentage: Some(0.5),
}
}
}
#[derive(Default, Clone, Copy, Debug, PartialEq)]
pub struct Outcome {
pub options: Rewrites,
pub num_similarity_checks: usize,
pub num_similarity_checks_skipped_for_rename_tracking_due_to_limit: usize,
pub num_similarity_checks_skipped_for_copy_tracking_due_to_limit: usize,
}
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
ConfigDiffRenames(#[from] crate::config::key::GenericError),
#[error(transparent)]
ConfigDiffRenameLimit(#[from] crate::config::unsigned_integer::Error),
}
impl Default for Rewrites {
fn default() -> Self {
Rewrites {
copies: None,
percentage: Some(0.5),
limit: 1000,
}
}
}
impl Rewrites {
#[allow(clippy::result_large_err)]
pub fn try_from_config(config: &gix_config::File<'static>, lenient: bool) -> Result<Option<Self>, Error> {
let key = "diff.renames";
let copies = match config
.boolean_by_key(key)
.map(|value| Diff::RENAMES.try_into_renames(value, || config.string_by_key(key)))
.transpose()
.with_leniency(lenient)?
{
Some(renames) => match renames {
Tracking::Disabled => return Ok(None),
Tracking::Renames => None,
Tracking::RenamesAndCopies => Some(Copies::default()),
},
None => return Ok(None),
};
let default = Self::default();
Ok(Rewrites {
copies,
limit: config
.integer_by_key("diff.renameLimit")
.map(|value| Diff::RENAME_LIMIT.try_into_usize(value))
.transpose()
.with_leniency(lenient)?
.unwrap_or(default.limit),
..default
}
.into())
}
}