#![allow(clippy::module_name_repetitions)]
use std::sync::mpsc::{Receiver, Sender, TryRecvError};
use crate::commit::{Commit, Oid};
use std::fmt::{Debug, Formatter};
use std::sync::mpsc;
use std::thread;
use git_wrapper::Repository;
use super::ActorThread;
#[derive(Debug)]
pub enum ForkPointCalculation {
Done(bool),
InProgress,
}
pub struct ForkPointThread(ActorThread<ForkPointRequest, ForkPointResponse>);
pub struct ForkPointRequest {
pub first: Oid,
pub second: Oid,
}
#[cfg(not(tarpaulin_include))]
impl Debug for ForkPointRequest {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut first = self.first.0.clone();
let mut second = self.second.0.clone();
first.truncate(8);
second.truncate(8);
f.debug_struct("ForkPointRequest")
.field("oid", &first)
.field("oid", &second)
.finish()
}
}
pub struct ForkPointResponse {
pub first: Oid,
pub second: Oid,
pub value: bool,
}
#[cfg(not(tarpaulin_include))]
impl Debug for ForkPointResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut oid = self.first.0.clone();
oid.truncate(8);
f.debug_tuple("ForkPointResponse")
.field(&oid)
.field(&self.value.to_string())
.finish()
}
}
impl ForkPointThread {
#[allow(clippy::missing_errors_doc)]
pub fn try_recv(&self) -> Result<ForkPointResponse, TryRecvError> {
self.0.try_recv()
}
pub fn request_calculation(
&self,
t: &Commit,
above_commit: Option<&Commit>,
) -> ForkPointCalculation {
let mut fork_point_calc = ForkPointCalculation::Done(false);
if let Some(c) = above_commit {
fork_point_calc = if c.is_merge() && c.parents()[1] != *t.id() {
self.0
.send(ForkPointRequest {
first: t.id().clone(),
second: c.parents()[1].clone(),
})
.unwrap();
ForkPointCalculation::InProgress
} else {
ForkPointCalculation::Done(false)
}
}
fork_point_calc
}
pub fn new(repo: Repository) -> Self {
let (tx_1, receiver): (Sender<ForkPointResponse>, Receiver<ForkPointResponse>) =
mpsc::channel();
let (sender, rx_2): (Sender<ForkPointRequest>, Receiver<ForkPointRequest>) =
mpsc::channel();
let thread = thread::spawn(move || {
while let Ok(v) = rx_2.recv() {
let value = repo.is_ancestor(&v.first.0, &v.second.0);
tx_1.send(ForkPointResponse {
first: v.first.clone(),
second: v.second.clone(),
value,
})
.expect("Send ForkPointResponse");
}
});
Self(ActorThread::new(thread, receiver, sender))
}
}