use crate::game::eu4::content::{DivergentBlockPolicy, MergePolicies};
use crate::merge::semantic_fingerprint::{statement_fingerprint, value_fingerprint};
use super::super::patch::{AstPath, ClausewitzPatch};
use super::PatchAddress;
pub(super) fn patch_address(patch: &ClausewitzPatch, policies: &MergePolicies) -> PatchAddress {
match patch {
ClausewitzPatch::SetValue { path, key, .. } => PatchAddress {
path: path.clone(),
key: key.clone(),
},
ClausewitzPatch::RemoveNode {
path, key, removed, ..
} => {
let fingerprint_nodes = matches!(
policies.divergent_block_policy_for_key(key),
DivergentBlockPolicy::Union
);
let key = if fingerprint_nodes {
format!("__node__::{}::{}", key, statement_fingerprint(removed))
} else {
key.clone()
};
PatchAddress {
path: path.clone(),
key,
}
}
ClausewitzPatch::InsertNode {
path,
key,
statement,
} => {
let fingerprint_nodes = matches!(
policies.divergent_block_policy_for_key(key),
DivergentBlockPolicy::Union
);
let key = if fingerprint_nodes {
format!("__node__::{}::{}", key, statement_fingerprint(statement))
} else {
key.clone()
};
PatchAddress {
path: path.clone(),
key,
}
}
ClausewitzPatch::AppendListItem {
path,
key,
value,
target_occurrence,
} => PatchAddress {
path: path.clone(),
key: format!(
"__list_item__::{}::{}::occurrence::{}",
key,
value_fingerprint(value),
target_occurrence.identity_ordinal()
),
},
ClausewitzPatch::RemoveListItem {
path,
key,
value,
source_occurrence,
} => PatchAddress {
path: path.clone(),
key: format!(
"__list_item__::{}::{}::occurrence::{}",
key,
value_fingerprint(value),
source_occurrence.identity_ordinal()
),
},
ClausewitzPatch::ReplaceBlock { path, key, .. } => PatchAddress {
path: path.clone(),
key: key.clone(),
},
ClausewitzPatch::AppendBlockItem { path, value } => PatchAddress {
path: path.clone(),
key: format!("__append_block_item__::{}", value_fingerprint(value)),
},
ClausewitzPatch::RemoveBlockItem { path, value } => PatchAddress {
path: path.clone(),
key: format!("__remove_block_item__::{}", value_fingerprint(value)),
},
ClausewitzPatch::Rename { path, old_key, .. } => PatchAddress {
path: path.clone(),
key: format!("__rename__::{old_key}"),
},
}
}
pub(super) fn patch_raw_address(patch: &ClausewitzPatch) -> Option<(AstPath, String)> {
match patch {
ClausewitzPatch::SetValue { path, key, .. }
| ClausewitzPatch::RemoveNode { path, key, .. }
| ClausewitzPatch::InsertNode { path, key, .. }
| ClausewitzPatch::ReplaceBlock { path, key, .. } => Some((path.clone(), key.clone())),
_ => None,
}
}
pub(super) fn patch_kind(patch: &ClausewitzPatch) -> &'static str {
match patch {
ClausewitzPatch::SetValue { .. } => "SetValue",
ClausewitzPatch::RemoveNode { .. } => "RemoveNode",
ClausewitzPatch::InsertNode { .. } => "InsertNode",
ClausewitzPatch::AppendListItem { .. } => "AppendListItem",
ClausewitzPatch::RemoveListItem { .. } => "RemoveListItem",
ClausewitzPatch::ReplaceBlock { .. } => "ReplaceBlock",
ClausewitzPatch::AppendBlockItem { .. } => "AppendBlockItem",
ClausewitzPatch::RemoveBlockItem { .. } => "RemoveBlockItem",
ClausewitzPatch::Rename { .. } => "Rename",
}
}