Architecture - hnlearndev/rslife GitHub Wiki

Core Design Principles

Builder Pattern First

  • All actuarial functions use the builder pattern for parameter specification
  • Only required parameters need to be specified
  • Automatic parameter validation and cross-field validation
  • Type-safe construction prevents runtime errors

Zero-Cost Abstractions

  • Built on Rust's zero-cost abstractions
  • Compile-time optimizations eliminate runtime overhead
  • Memory-efficient operations with smart data reuse

Universal Data Input

  • Supports multiple data sources: DataFrames, XLSX/ODS, SOA XML, IFOA XLS
  • Automatic format detection (qx rates vs lx survivor functions)
  • Smart table recognition (ultimate vs select mortality tables)

Module Structure

rslife/
├── src/
│   ├── lib.rs                  # Main library entry point
│   ├── prelude.rs              # Common re-exports for user convenience
│   ├── params.rs               # Parameter validation structs
│   ├── helpers.rs              # Utility and helper functions
│   ├── int_rate_convert.rs     # Interest rate conversions
│   ├── annuities_certain.rs    # Certain annuities (no mortality)
│   ├── mt_config.rs            # Mortality table configuration and logic entry point
│   ├── mt_config/              # Submodules for mortality table configuration
│   │   ├── ifoa_xls.rs         # IFOA XLS data loader and logic
│   │   ├── mt_data.rs          # Mortality data loading and processing (submodule)
│   │   ├── soa_xml.rs          # SOA XML data loader and logic
│   │   └── ...                 # Other mt_config submodules
│   ├── single_life.rs          # Single life actuarial calculation entry point
│   ├── single_life/            # Submodules for single life actuarial logic
│   │   ├── annuities.rs        # Life annuity functions
│   │   ├── benefits.rs         # Life insurance benefit functions
│   │   ├── commutations.rs     # Commutation functions (Cx, Dx, Mx, Nx, Sx, Rx)
│   │   ├── survivals.rs        # Survival probability and related functions
│   │   └── ...                 # Additional actuarial logic
│   └── ...                     # Other modules as needed
├── data/                       # Example mortality tables and input data
├── diagrams/                   # Actuarial function diagrams and visualizations
├── wiki/                       # Wiki/Documentation for this crate
├── tests/                      # Integration and unit tests
└── examples/                   # Usage examples and demos

Data Flow Architecture

Data Loading Layer

MortData::from_soa_url_id(1704)     // SOA XML
MortData::from_ifo_url_id("AM92")   // IFOA XLS
MortData::from_xlsx("file.xlsx")    // Excel files
MortData::from_ods("file.ods")      // ODS files
MortData::from_df(dataframe)        // Polars DataFrame

MortData is constructed as a seperate layer to maximize its flexibility and capacity to handle multiple data sources.

There are also various other methods to help users to:

  • directly access data from SOA XML files (locally or via internet)
  • directly access data from IFOA xls files (locally or via internet)
  • other methods to handle their own custom data

More details on discussion to different ways to access data can be found at.

Configuration Layer

MortTableConfig::builder()
    .data(mort_data)
    .radix(100_000)                      // Using 100k instead of default 10k
    .pct(1.2)                           // Using 120% mortality instead of default 100%
    .assumption(AssumptionEnum::CFM)   // Using CFM instead of default UDD
    .build()
  • Central configuration object for all calculations
  • Holds mortality data, assumptions, and adjustments
  • Supports both ultimate and select mortality tables
  • Automatic validation of configuration parameters
  • Include methods to retrieve information from mortality table

Calculation Layer

Ax().mt(&config).i(0.04).x(35).call()?   // Life insurance

aax().mt(&config).i(0.04).x(65).call()?  // Annuities

tpx().mt(&config).x(35.0).t(5.0).call()? // Survival

Rx().mt(&config).i(0.06).x(27).call()? // Commutation

Each function call will perform parameter validation:

  • SingleLifeParams: Validates parameters for life insurance and annuity calculations
  • SurvivalFunctionParams: Validates parameters for survival probability calculations
  • Cross-field validation ensures parameter combinations are valid
  • Early error detection prevents invalid calculations

Dependencies

Core Dependencies

  • Polars: DataFrame operations and data processing
  • bon: Builder pattern implementation
  • garde: Parameter validation
  • calamine: Excel file reading
  • spreadsheet-ods: ODS file reading
  • roxmltree: XML parsing for SOA data
  • reqwest: HTTP requests for SOA and IFOA data

Development Dependencies

  • approx: Floating-point comparisons in tests
  • Standard Rust testing framework

Future Architecture Considerations

Multi-Life Extensions

  • Joint life calculations
  • Survivor annuities
  • Last survivor benefits

Advanced Features

  • Stochastic mortality models
  • Economic scenario generation
  • Cash flow projections

Performance Enhancements

  • SIMD optimizations for bulk calculations
  • Parallel computation for independent calculations
  • GPU acceleration for large-scale computations