#[derive(Debug, Clone, Default)]
pub struct ReputationService;
impl ReputationService {
pub fn new() -> Self {
Self
}
pub fn apply_reputation_change(current_value: f32, delta: f32, min: f32, max: f32) -> f32 {
(current_value + delta).clamp(min, max)
}
pub fn calculate_decay(current: f32, decay_rate: f32, elapsed_time: u64) -> f32 {
current * decay_rate.powi(elapsed_time as i32)
}
pub fn get_rank(value: f32, thresholds: &[f32]) -> usize {
thresholds.iter().filter(|&&t| value >= t).count()
}
pub fn check_threshold_crossed(old_value: f32, new_value: f32, threshold: f32) -> Option<bool> {
let old_below = old_value < threshold;
let new_below = new_value < threshold;
match (old_below, new_below) {
(true, false) => Some(true), (false, true) => Some(false), _ => None, }
}
pub fn apply_change_multiplier(
base_change: f32,
positive_multiplier: f32,
negative_multiplier: f32,
) -> f32 {
if base_change > 0.0 {
base_change * positive_multiplier
} else if base_change < 0.0 {
base_change * negative_multiplier
} else {
0.0
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_apply_reputation_change() {
let value = ReputationService::apply_reputation_change(50.0, 20.0, 0.0, 100.0);
assert_eq!(value, 70.0);
let value = ReputationService::apply_reputation_change(90.0, 20.0, 0.0, 100.0);
assert_eq!(value, 100.0);
let value = ReputationService::apply_reputation_change(50.0, -30.0, 0.0, 100.0);
assert_eq!(value, 20.0);
let value = ReputationService::apply_reputation_change(10.0, -20.0, 0.0, 100.0);
assert_eq!(value, 0.0);
let value = ReputationService::apply_reputation_change(50.0, 0.0, 0.0, 100.0);
assert_eq!(value, 50.0);
let value = ReputationService::apply_reputation_change(0.0, -30.0, -100.0, 100.0);
assert_eq!(value, -30.0);
let value = ReputationService::apply_reputation_change(-90.0, -20.0, -100.0, 100.0);
assert_eq!(value, -100.0);
}
#[test]
fn test_calculate_decay() {
let value = ReputationService::calculate_decay(100.0, 0.95, 1);
assert!((value - 95.0).abs() < 0.001);
let value = ReputationService::calculate_decay(100.0, 0.95, 3);
assert!((value - 85.7375).abs() < 0.001);
let value = ReputationService::calculate_decay(100.0, 1.0, 10);
assert_eq!(value, 100.0);
let value = ReputationService::calculate_decay(100.0, 0.95, 0);
assert_eq!(value, 100.0);
let value = ReputationService::calculate_decay(100.0, 0.9, 2);
assert!((value - 81.0).abs() < 0.001);
let value = ReputationService::calculate_decay(0.0, 0.95, 5);
assert_eq!(value, 0.0);
}
#[test]
fn test_get_rank() {
let thresholds = vec![10.0, 50.0, 100.0];
let rank = ReputationService::get_rank(5.0, &thresholds);
assert_eq!(rank, 0);
let rank = ReputationService::get_rank(10.0, &thresholds);
assert_eq!(rank, 1);
let rank = ReputationService::get_rank(30.0, &thresholds);
assert_eq!(rank, 1);
let rank = ReputationService::get_rank(50.0, &thresholds);
assert_eq!(rank, 2);
let rank = ReputationService::get_rank(75.0, &thresholds);
assert_eq!(rank, 2);
let rank = ReputationService::get_rank(100.0, &thresholds);
assert_eq!(rank, 3);
let rank = ReputationService::get_rank(150.0, &thresholds);
assert_eq!(rank, 3);
let rank = ReputationService::get_rank(50.0, &[]);
assert_eq!(rank, 0);
}
#[test]
fn test_check_threshold_crossed() {
let crossed = ReputationService::check_threshold_crossed(40.0, 60.0, 50.0);
assert_eq!(crossed, Some(true));
let crossed = ReputationService::check_threshold_crossed(60.0, 40.0, 50.0);
assert_eq!(crossed, Some(false));
let crossed = ReputationService::check_threshold_crossed(30.0, 40.0, 50.0);
assert_eq!(crossed, None);
let crossed = ReputationService::check_threshold_crossed(60.0, 70.0, 50.0);
assert_eq!(crossed, None);
let crossed = ReputationService::check_threshold_crossed(40.0, 50.0, 50.0);
assert_eq!(crossed, Some(true));
let crossed = ReputationService::check_threshold_crossed(50.0, 40.0, 50.0);
assert_eq!(crossed, Some(false));
let crossed = ReputationService::check_threshold_crossed(50.0, 50.0, 50.0);
assert_eq!(crossed, None);
}
#[test]
fn test_apply_change_multiplier() {
let change = ReputationService::apply_change_multiplier(10.0, 1.5, 1.0);
assert!((change - 15.0).abs() < 0.001);
let change = ReputationService::apply_change_multiplier(-10.0, 1.0, 2.0);
assert!((change - (-20.0)).abs() < 0.001);
let change = ReputationService::apply_change_multiplier(0.0, 1.5, 2.0);
assert_eq!(change, 0.0);
let change = ReputationService::apply_change_multiplier(5.0, 2.0, 3.0);
assert!((change - 10.0).abs() < 0.001);
let change = ReputationService::apply_change_multiplier(-5.0, 2.0, 3.0);
assert!((change - (-15.0)).abs() < 0.001);
}
}