use prikk_object::NodeId;
use crate::node_lifecycle::NodeLifecycleState;
use crate::patch_replay::decode::DecodedPatchOperation;
use crate::path::RepoPath;
use super::types::{
Action, ConflictWitness, ConflictWitnessKind, OperationFacts, PairClass, RequiredOrder,
UnknownReason,
};
pub(super) fn ordered(
required_order: RequiredOrder,
kind: ConflictWitnessKind,
left: &OperationFacts,
right: &OperationFacts,
node_id: Option<NodeId>,
path: Option<RepoPath>,
) -> PairClass {
PairClass::OrderedDependency {
required_order,
witness: witness(kind, left.op_seq, right.op_seq, node_id, path, None),
}
}
pub(super) fn conflict(
kind: ConflictWitnessKind,
left: &OperationFacts,
right: &OperationFacts,
node_id: Option<NodeId>,
path: Option<RepoPath>,
) -> PairClass {
PairClass::Conflict {
witness: witness(kind, left.op_seq, right.op_seq, node_id, path, None),
}
}
pub(super) fn conflict_with_span(
kind: ConflictWitnessKind,
left: &OperationFacts,
right: &OperationFacts,
node_id: NodeId,
path: Option<RepoPath>,
span_id: [u8; 32],
) -> PairClass {
PairClass::Conflict {
witness: witness(
kind,
left.op_seq,
right.op_seq,
Some(node_id),
path,
Some(span_id),
),
}
}
pub(super) fn unknown(
reason: UnknownReason,
left: &DecodedPatchOperation,
right: &DecodedPatchOperation,
node_id: Option<NodeId>,
path: Option<RepoPath>,
) -> PairClass {
PairClass::Unknown {
reason,
witness: witness(
match reason {
UnknownReason::MalformedOperation => ConflictWitnessKind::MalformedOperation,
UnknownReason::RenameDeferred | UnknownReason::SymlinkDeferred => {
ConflictWitnessKind::UnsupportedOperation
}
_ => ConflictWitnessKind::UnknownRelation,
},
left.op_seq,
right.op_seq,
node_id,
path,
None,
),
}
}
pub(super) fn unknown_from_facts(
reason: UnknownReason,
left: &OperationFacts,
right: &OperationFacts,
node_id: Option<NodeId>,
path: Option<RepoPath>,
) -> PairClass {
PairClass::Unknown {
reason,
witness: witness(
ConflictWitnessKind::UnknownRelation,
left.op_seq,
right.op_seq,
node_id,
path,
None,
),
}
}
pub(super) fn derive_path(
baseline: &NodeLifecycleState,
left: &OperationFacts,
right: &OperationFacts,
) -> Option<RepoPath> {
match (operand_path(baseline, left), operand_path(baseline, right)) {
(Some(left_path), Some(right_path)) if left_path == right_path => Some(left_path),
(Some(left_path), None) => Some(left_path),
(None, Some(right_path)) => Some(right_path),
_ => None,
}
}
pub(super) fn operand_path(
baseline: &NodeLifecycleState,
facts: &OperationFacts,
) -> Option<RepoPath> {
match &facts.action {
Action::CreateFile { path, .. }
| Action::DeleteFile { path, .. }
| Action::DeleteSymlink { path, .. }
| Action::CreateSymlink { path, .. } => Some(path.clone()),
Action::RenamePath { .. } => None,
Action::EditText { node_id, .. }
| Action::ReplaceBinary { node_id, .. }
| Action::ChangePerm { node_id, .. } => {
baseline.live_node(node_id).map(|live| live.path.clone())
}
}
}
fn witness(
kind: ConflictWitnessKind,
left_op_seq: u32,
right_op_seq: u32,
node_id: Option<NodeId>,
path: Option<RepoPath>,
text_span: Option<[u8; 32]>,
) -> ConflictWitness {
ConflictWitness {
kind,
left_op_seq,
right_op_seq,
node_id,
path,
text_span,
}
}
pub(super) fn common_node(left: &OperationFacts, right: &OperationFacts) -> Option<NodeId> {
match (left.node_id, right.node_id) {
(Some(left_id), Some(right_id)) if left_id == right_id => Some(left_id),
_ => None,
}
}