#![recursion_limit = "256"]
pub mod calculator;
pub mod calculators;
pub mod license;
pub mod proprietary;
pub mod response;
pub mod tags;
pub mod template;
#[cfg(feature = "cli")]
pub mod cli;
#[cfg(feature = "mcp")]
pub mod mcp;
pub use calculator::{CalcError, Calculator};
pub use license::CalculatorLicense;
pub use proprietary::ProprietaryCalculator;
pub use response::CalculationResponse;
pub use tags::{all_tags, for_name as tags_for_name};
pub use template::template_from_schema;
pub fn all() -> Vec<Box<dyn Calculator>> {
let mut list: Vec<Box<dyn Calculator>> = vec![
Box::new(calculators::feverpain::FeverPain),
Box::new(calculators::asrs::Asrs),
Box::new(calculators::phq9::Phq9),
Box::new(calculators::gad7::Gad7),
Box::new(calculators::egfr::Egfr),
Box::new(calculators::fib4::Fib4),
Box::new(calculators::cha2ds2vasc::Cha2ds2Vasc),
Box::new(calculators::auditc::AuditC),
Box::new(calculators::audit::Audit),
Box::new(calculators::epds::Epds),
Box::new(calculators::ipss::Ipss),
Box::new(calculators::amts::Amts),
Box::new(calculators::mrc_dyspnoea::MrcDyspnoea),
Box::new(calculators::news2::News2),
Box::new(calculators::curb65::Curb65),
Box::new(calculators::wells_dvt::WellsDvt),
Box::new(calculators::wells_pe::WellsPe),
Box::new(calculators::hasbled::HasBled),
Box::new(calculators::abcd2::Abcd2),
Box::new(calculators::qsofa::Qsofa),
Box::new(calculators::fourat::FourAt),
Box::new(calculators::das28::Das28),
Box::new(calculators::uacr::Uacr),
Box::new(calculators::sofa::Sofa),
Box::new(calculators::heart::Heart),
Box::new(calculators::timi::Timi),
Box::new(calculators::child_pugh::ChildPugh),
Box::new(calculators::meld::Meld),
Box::new(calculators::padua::Padua),
Box::new(calculators::ukeld::Ukeld),
Box::new(calculators::nhfs::Nhfs),
Box::new(calculators::bode::Bode),
Box::new(calculators::abpi::Abpi),
Box::new(calculators::waterlow::Waterlow),
Box::new(calculators::gleason::Gleason),
Box::new(calculators::npi::Npi),
Box::new(calculators::chalice::Chalice),
Box::new(calculators::ckd_risk::CkdRisk),
Box::new(calculators::grace::Grace),
Box::new(calculators::euroscore2::EuroScore2),
Box::new(calculators::qrisk3::Qrisk3),
Box::new(calculators::qfracture::Qfracture),
];
for p in proprietary::PROPRIETARY {
list.push(Box::new(*p));
}
list
}
pub fn get(name: &str) -> Option<Box<dyn Calculator>> {
all().into_iter().find(|c| c.name() == name)
}
#[cfg(test)]
mod registry_tests {
use super::*;
#[test]
fn every_calculator_records_its_license() {
for calc in all() {
let lic = calc.license();
assert!(
!lic.license.trim().is_empty(),
"{}: license must not be empty",
calc.name()
);
assert!(
lic.source_url.starts_with("http"),
"{}: license source_url must be a URL, got {:?}",
calc.name(),
lic.source_url
);
}
}
#[test]
fn every_calculator_has_at_least_one_tag() {
for calc in all() {
assert!(
!calc.tags().is_empty(),
"{}: tags() must return at least one tag - add an entry to clincalc::tags::TAGS",
calc.name()
);
}
}
}