use crate::{
bstr::BStr,
status::{index_worktree, tree_index},
worktree::IndexPersistedOrInMemory,
};
pub struct Iter {
#[cfg(feature = "parallel")]
#[allow(clippy::type_complexity)]
pub(super) rx_and_join: Option<(
std::sync::mpsc::Receiver<Item>,
std::thread::JoinHandle<Result<Outcome, index_worktree::Error>>,
Option<std::thread::JoinHandle<Result<tree_index::Outcome, tree_index::Error>>>,
)>,
#[cfg(feature = "parallel")]
pub(super) should_interrupt: crate::status::OwnedOrStaticAtomicBool,
#[cfg(not(feature = "parallel"))]
pub(super) items: std::vec::IntoIter<Item>,
pub(in crate::status) out: Option<Outcome>,
pub(super) index_changes: Vec<(usize, ApplyChange)>,
}
#[derive(Clone, PartialEq, Debug)]
pub enum Item {
IndexWorktree(index_worktree::Item),
TreeIndex(gix_diff::index::Change),
}
pub struct Outcome {
pub index_worktree: gix_status::index_as_worktree_with_renames::Outcome,
pub tree_index: Option<tree_index::Outcome>,
pub worktree_index: IndexPersistedOrInMemory,
pub(super) skip_hash: bool,
pub(super) changes: Option<Vec<(usize, ApplyChange)>>,
}
impl Outcome {
pub fn has_changes(&self) -> bool {
self.changes.as_ref().is_some_and(|changes| !changes.is_empty())
}
pub fn write_changes(&mut self) -> Option<Result<(), gix_index::file::write::Error>> {
let _span = gix_features::trace::coarse!("gix::status::index_worktree::Outcome::write_changes()");
let changes = self.changes.take()?;
let mut index = match &self.worktree_index {
IndexPersistedOrInMemory::Persisted(persisted) => (***persisted).clone(),
IndexPersistedOrInMemory::InMemory(index) => index.clone(),
};
let entries = index.entries_mut();
for (entry_index, change) in changes {
let entry = &mut entries[entry_index];
match change {
ApplyChange::SetSizeToZero => {
entry.stat.size = 0;
}
ApplyChange::NewStat(new_stat) => {
entry.stat = new_stat;
}
}
}
Some(index.write(crate::index::write::Options {
extensions: Default::default(),
skip_hash: self.skip_hash,
}))
}
}
pub(super) enum ApplyChange {
SetSizeToZero,
NewStat(crate::index::entry::Stat),
}
impl From<index_worktree::Item> for Item {
fn from(value: index_worktree::Item) -> Self {
Item::IndexWorktree(value)
}
}
impl From<gix_diff::index::Change> for Item {
fn from(value: gix_diff::index::Change) -> Self {
Item::TreeIndex(value)
}
}
impl Item {
pub fn location(&self) -> &BStr {
match self {
Item::IndexWorktree(change) => change.rela_path(),
Item::TreeIndex(change) => change.location(),
}
}
}