#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BmiCategory {
Underweight,
Normal,
Overweight,
Obese,
}
#[derive(Debug, Clone)]
pub struct BodyMassIndexMorph {
pub bmi: f32,
pub category: BmiCategory,
pub influence: f32,
pub morph_count: usize,
pub enabled: bool,
}
impl BodyMassIndexMorph {
pub fn new(morph_count: usize) -> Self {
BodyMassIndexMorph {
bmi: 22.0,
category: BmiCategory::Normal,
influence: 1.0,
morph_count,
enabled: true,
}
}
}
pub fn new_bmi_morph(morph_count: usize) -> BodyMassIndexMorph {
BodyMassIndexMorph::new(morph_count)
}
pub fn bmi_set_value(morph: &mut BodyMassIndexMorph, bmi: f32) {
morph.bmi = bmi.clamp(10.0, 60.0);
morph.category = if bmi < 18.5 {
BmiCategory::Underweight
} else if bmi < 25.0 {
BmiCategory::Normal
} else if bmi < 30.0 {
BmiCategory::Overweight
} else {
BmiCategory::Obese
};
}
pub fn bmi_set_influence(morph: &mut BodyMassIndexMorph, influence: f32) {
morph.influence = influence.clamp(0.0, 1.0);
}
pub fn bmi_evaluate(morph: &BodyMassIndexMorph) -> Vec<f32> {
if morph.morph_count == 0 || !morph.enabled {
return vec![];
}
let w = morph.influence * ((morph.bmi - 10.0) / 50.0).clamp(0.0, 1.0);
vec![w; morph.morph_count]
}
pub fn bmi_set_enabled(morph: &mut BodyMassIndexMorph, enabled: bool) {
morph.enabled = enabled;
}
pub fn bmi_to_json(morph: &BodyMassIndexMorph) -> String {
let cat = match morph.category {
BmiCategory::Underweight => "underweight",
BmiCategory::Normal => "normal",
BmiCategory::Overweight => "overweight",
BmiCategory::Obese => "obese",
};
format!(
r#"{{"bmi":{},"category":"{}","influence":{},"morph_count":{},"enabled":{}}}"#,
morph.bmi, cat, morph.influence, morph.morph_count, morph.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_default_bmi() {
let m = new_bmi_morph(8);
assert!((m.bmi - 22.0).abs() < 1e-6 );
}
#[test]
fn test_category_normal() {
let m = new_bmi_morph(4);
assert_eq!(
m.category,
BmiCategory::Normal
);
}
#[test]
fn test_set_underweight() {
let mut m = new_bmi_morph(4);
bmi_set_value(&mut m, 17.0);
assert_eq!(
m.category,
BmiCategory::Underweight
);
}
#[test]
fn test_set_overweight() {
let mut m = new_bmi_morph(4);
bmi_set_value(&mut m, 27.0);
assert_eq!(
m.category,
BmiCategory::Overweight
);
}
#[test]
fn test_set_obese() {
let mut m = new_bmi_morph(4);
bmi_set_value(&mut m, 35.0);
assert_eq!(m.category, BmiCategory::Obese );
}
#[test]
fn test_influence_clamped() {
let mut m = new_bmi_morph(4);
bmi_set_influence(&mut m, 2.0);
assert!((m.influence - 1.0).abs() < 1e-6 );
}
#[test]
fn test_evaluate_length() {
let m = new_bmi_morph(6);
let out = bmi_evaluate(&m);
assert_eq!(out.len(), 6 );
}
#[test]
fn test_evaluate_disabled_empty() {
let mut m = new_bmi_morph(4);
bmi_set_enabled(&mut m, false);
let out = bmi_evaluate(&m);
assert!(out.is_empty() );
}
#[test]
fn test_to_json_contains_bmi() {
let m = new_bmi_morph(4);
let j = bmi_to_json(&m);
assert!(j.contains("\"bmi\"") );
}
#[test]
fn test_enabled_default() {
let m = new_bmi_morph(4);
assert!(m.enabled );
}
}