use serde::{Deserialize, Serialize};
use super::standard_id::StandardId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CrossReferenceType {
Converged,
Related,
Complementary,
DerivedFrom,
IncorporatedInto,
Parallel,
AuditMapping,
ControlFrameworkMapping,
}
impl std::fmt::Display for CrossReferenceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Converged => write!(f, "Converged"),
Self::Related => write!(f, "Related"),
Self::Complementary => write!(f, "Complementary"),
Self::DerivedFrom => write!(f, "Derived From"),
Self::IncorporatedInto => write!(f, "Incorporated Into"),
Self::Parallel => write!(f, "Parallel"),
Self::AuditMapping => write!(f, "Audit Mapping"),
Self::ControlFrameworkMapping => write!(f, "Control Framework Mapping"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrossReference {
pub from_standard: StandardId,
pub to_standard: StandardId,
pub relationship: CrossReferenceType,
pub convergence_level: f64,
pub description: Option<String>,
}
impl CrossReference {
pub fn new(from: StandardId, to: StandardId, relationship: CrossReferenceType) -> Self {
let convergence = match relationship {
CrossReferenceType::Converged => 0.9,
CrossReferenceType::IncorporatedInto => 0.85,
CrossReferenceType::Related => 0.6,
CrossReferenceType::Complementary => 0.5,
CrossReferenceType::DerivedFrom => 0.7,
CrossReferenceType::Parallel => 0.4,
CrossReferenceType::AuditMapping => 0.7,
CrossReferenceType::ControlFrameworkMapping => 0.6,
};
Self {
from_standard: from,
to_standard: to,
relationship,
convergence_level: convergence,
description: None,
}
}
pub fn with_convergence(mut self, level: f64) -> Self {
self.convergence_level = level.clamp(0.0, 1.0);
self
}
pub fn with_description(mut self, desc: impl Into<String>) -> Self {
self.description = Some(desc.into());
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cross_reference() {
let xref = CrossReference::new(
StandardId::new("IFRS", "15"),
StandardId::new("ASC", "606"),
CrossReferenceType::Converged,
)
.with_description("Joint standard — substantially converged");
assert_eq!(xref.from_standard.as_str(), "IFRS-15");
assert_eq!(xref.to_standard.as_str(), "ASC-606");
assert!(xref.convergence_level > 0.8);
}
}