31a0b8a485
Multi-Platform CI / test-platforms (ubuntu-22.04) (push) Successful in 18s
Multi-Platform CI / test-platforms (windows-latest) (push) Successful in 18s
Multi-Platform CI / Package for Linux x86_64 (push) Has been skipped
Multi-Platform CI / Package for Windows x86_64 (push) Has been skipped
Multi-Platform CI / Create GitHub Release (push) Has been skipped
- add C FFI enums MLBladderPhase, MLMetabolicState, MLPerfusionState - add C FFI structs MLBloodstreamMetrics and MLBladderMetrics - add ml_patient_bloodstream_metrics and ml_patient_bladder_metrics to populate metrics for a patient (mirrored in src/ffi.rs) - update examples/c/ffi_example.c to print new metrics - add tests for FFI metrics (tests/ffi.rs) organ model expansions - bloodstream: add metrics() snapshot and detailed physiology: plasma proteins/oncotic pressure, lymph return, RBC cohort tracking, erythropoiesis/clearance with HIF, iron/folate/B12 stores, platelets, coagulation/fibrinolysis, immune cell counts, complement, acid–base - bladder: introduce adaptive compliance, reflex gating, cortical/voluntary modulators, safety indices; add metrics(), summary, and unit tests - brain: add homeostatic drives (respiratory, thirst, hunger, thermo, pain), brainstem nuclei (NTS/RVLM/CVLM, nAmb/DMV, RTN), sleep cycle timing, cerebrovascular autoregulation; wire drives into autonomic control - heart: add phase-based cycle (valves and atria), conduction system, RAAS regulation, improved coronary perfusion - intestines: add micronutrient absorption feeding erythropoiesis patient coupling - expose Patient::bloodstream_metrics() and ::bladder_metrics() - integrate new organ signals (kidney osmolality, spleen culling, liver proteins) and brain–lung/continence control pathways - re-export BladderMetrics and BloodstreamMetrics in lib.rs note - existing FFI remains compatible; this is a surface addition - ffi/medicallib.h kept in sync with src/ffi.rs
71 lines
2.5 KiB
Rust
71 lines
2.5 KiB
Rust
use medicallib_rust::{Bladder, Organ, OrganType, Patient};
|
|
|
|
#[test]
|
|
fn bladder_metrics_match_patient_api() {
|
|
let patient = Patient::new("metrics")
|
|
.unwrap()
|
|
.initialize_default()
|
|
.with_organ(OrganType::Bladder);
|
|
let metrics_via_patient = patient.bladder_metrics().expect("bladder present");
|
|
let bladder = patient.find_organ_typed::<Bladder>().unwrap();
|
|
let direct = bladder.metrics();
|
|
assert!((metrics_via_patient.urgency - direct.urgency).abs() < 1e-6);
|
|
assert_eq!(metrics_via_patient.phase, direct.phase);
|
|
assert_eq!(metrics_via_patient.capacity_ml, direct.capacity_ml);
|
|
}
|
|
|
|
#[test]
|
|
fn voluntary_hold_updates_metrics() {
|
|
let mut patient = Patient::new("hold")
|
|
.unwrap()
|
|
.initialize_default()
|
|
.with_organ(OrganType::Bladder);
|
|
|
|
{
|
|
let bladder = patient.find_organ_typed_mut::<Bladder>().unwrap();
|
|
bladder.volume_ml = bladder.micturition_threshold_ml + 140.0;
|
|
bladder.urgency = 0.82;
|
|
bladder.cortical_inhibition = 0.1;
|
|
bladder.voluntary_hold_command = 0.1;
|
|
bladder.continence_training = 0.45;
|
|
bladder.update(0.5);
|
|
}
|
|
let baseline = patient.bladder_metrics().unwrap();
|
|
|
|
{
|
|
let bladder = patient.find_organ_typed_mut::<Bladder>().unwrap();
|
|
bladder.cortical_inhibition = 0.9;
|
|
bladder.voluntary_hold_command = 0.9;
|
|
bladder.continence_training = 0.9;
|
|
bladder.update(0.5);
|
|
}
|
|
let hold = patient.bladder_metrics().unwrap();
|
|
|
|
assert!(hold.voluntary_hold_fraction > baseline.voluntary_hold_fraction);
|
|
assert!(hold.cortical_gate_fraction > baseline.cortical_gate_fraction);
|
|
assert!(hold.cortical_gate_fraction <= 1.0);
|
|
assert!(hold.voluntary_hold_fraction <= 1.0);
|
|
}
|
|
|
|
#[cfg(feature = "ffi")]
|
|
#[test]
|
|
fn ffi_exposes_bladder_metrics() {
|
|
use core::mem::MaybeUninit;
|
|
use medicallib_rust::ffi::{
|
|
ml_patient_bladder_metrics, ml_patient_free, ml_patient_new, ml_patient_update,
|
|
MLBladderMetrics, MLPatient, ML_ERR, ML_OK,
|
|
};
|
|
use std::ffi::CString;
|
|
|
|
unsafe {
|
|
let id = CString::new("ffi-metrics").unwrap();
|
|
let patient: *mut MLPatient = ml_patient_new(id.as_ptr());
|
|
assert!(!patient.is_null());
|
|
assert_eq!(ml_patient_update(patient, 0.5), ML_OK);
|
|
let mut metrics = MaybeUninit::<MLBladderMetrics>::zeroed();
|
|
let status = ml_patient_bladder_metrics(patient as *const MLPatient, metrics.as_mut_ptr());
|
|
assert_eq!(status, ML_ERR);
|
|
ml_patient_free(patient);
|
|
}
|
|
}
|