feat(ffi): add bloodstream and bladder metrics API
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
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
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -29,3 +29,24 @@ fn ffi_errors() {
|
||||
let s = medicallib_rust::ffi::ml_patient_summary(std::ptr::null());
|
||||
assert!(s.is_null());
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
#[test]
|
||||
fn ffi_bloodstream_metrics() {
|
||||
use medicallib_rust::ffi::*;
|
||||
use std::ffi::CString;
|
||||
|
||||
let id = CString::new("ffi-blood").unwrap();
|
||||
let p = ml_patient_new(id.as_ptr());
|
||||
assert!(!p.is_null());
|
||||
|
||||
let mut metrics = std::mem::MaybeUninit::<MLBloodstreamMetrics>::uninit();
|
||||
assert_eq!(ml_patient_update(p, 0.5), ML_OK);
|
||||
let rc = ml_patient_bloodstream_metrics(p, metrics.as_mut_ptr());
|
||||
assert_eq!(rc, ML_OK);
|
||||
let metrics = unsafe { metrics.assume_init() };
|
||||
assert!(metrics.oncotic_pressure_mm_hg > 15.0);
|
||||
assert!(metrics.rbc_mature_fraction > 0.4);
|
||||
ml_patient_free(p);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user