use crate::time::date::Date;
use crate::types::Real;
pub trait Claim {
fn amount(&self, default_date: &Date, notional: Real, recovery_rate: Real) -> Real;
}
#[derive(Debug, Clone, Copy)]
pub struct FaceValueClaim;
impl Claim for FaceValueClaim {
fn amount(&self, _default_date: &Date, notional: Real, recovery_rate: Real) -> Real {
notional * (1.0 - recovery_rate)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::shared::{Shared, shared};
use crate::time::date::Month;
fn a_date() -> Date {
Date::new(15, Month::June, 2026)
}
#[test]
fn face_value_claim_pays_the_non_recovered_notional() {
let claim = FaceValueClaim;
assert_eq!(claim.amount(&a_date(), 100.0, 0.5), 50.0);
assert_eq!(claim.amount(&a_date(), 1_000_000.0, 0.25), 750_000.0);
}
#[test]
fn face_value_claim_at_the_recovery_extremes() {
let claim = FaceValueClaim;
assert_eq!(claim.amount(&a_date(), 100.0, 0.0), 100.0);
assert_eq!(claim.amount(&a_date(), 100.0, 1.0), 0.0);
}
#[test]
fn face_value_claim_ignores_the_default_date() {
let claim = FaceValueClaim;
let early = Date::new(1, Month::January, 2026);
let late = Date::new(31, Month::December, 2030);
assert_eq!(
claim.amount(&early, 100.0, 0.5),
claim.amount(&late, 100.0, 0.5)
);
}
#[test]
fn claim_is_dyn_compatible() {
let claim: Shared<dyn Claim> = shared(FaceValueClaim);
assert_eq!(claim.amount(&a_date(), 100.0, 0.5), 50.0);
}
}