use crate::models::{ChangeDetection, ScriptType};
pub fn detect_change(
output_values: &[i64],
output_scripts: &[ScriptType],
dominant_input_script: ScriptType,
) -> ChangeDetection {
if output_values.len() <= 1 {
return ChangeDetection::None;
}
let mut has_round = false;
let mut has_continuity = false;
for &val in output_values {
if val > 0 && (val % 10_000 == 0 || val % 100_000 == 0 || val % 1_000_000 == 0) {
has_round = true;
break;
}
}
for &script in output_scripts {
if script == dominant_input_script
&& script != ScriptType::Unknown
&& script != ScriptType::Mixed
{
has_continuity = true;
break;
}
}
match (has_round, has_continuity) {
(true, true) => ChangeDetection::HighMultiMethod,
(true, false) => ChangeDetection::HighRoundNumber,
(false, true) => ChangeDetection::HighScoreContinuity,
(false, false) => ChangeDetection::None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_single_output_returns_none() {
let result = detect_change(&[100_000], &[ScriptType::P2WPKH], ScriptType::P2WPKH);
assert_eq!(result, ChangeDetection::None);
}
#[test]
fn test_round_and_continuity_returns_high_multi() {
let result = detect_change(
&[1_000_000, 234_567],
&[ScriptType::P2WPKH, ScriptType::P2WPKH],
ScriptType::P2WPKH,
);
assert_eq!(result, ChangeDetection::HighMultiMethod);
}
#[test]
fn test_round_no_continuity() {
let result = detect_change(
&[1_000_000, 234_567],
&[ScriptType::P2TR, ScriptType::P2PKH],
ScriptType::P2WPKH,
);
assert_eq!(result, ChangeDetection::HighRoundNumber);
}
#[test]
fn test_continuity_no_round() {
let result = detect_change(
&[1_234_567, 987_654],
&[ScriptType::P2WPKH, ScriptType::P2WPKH],
ScriptType::P2WPKH,
);
assert_eq!(result, ChangeDetection::HighScoreContinuity);
}
#[test]
fn test_empty_outputs_returns_none() {
let result = detect_change(&[], &[], ScriptType::P2WPKH);
assert_eq!(result, ChangeDetection::None);
}
}