#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AdolSex {
Male,
Female,
}
#[derive(Debug, Clone)]
pub struct AdolescentMorphConfig {
pub sex: AdolSex,
pub growth_spurt_peak_years: f32,
}
impl Default for AdolescentMorphConfig {
fn default() -> Self {
AdolescentMorphConfig {
sex: AdolSex::Female,
growth_spurt_peak_years: 14.0,
}
}
}
#[derive(Debug, Clone)]
pub struct AdolescentMorph {
pub age_years: f32,
pub config: AdolescentMorphConfig,
pub enabled: bool,
}
pub fn new_adolescent_morph() -> AdolescentMorph {
AdolescentMorph {
age_years: 12.0,
config: AdolescentMorphConfig::default(),
enabled: true,
}
}
pub fn adol_set_age(m: &mut AdolescentMorph, years: f32) {
m.age_years = years.clamp(12.0, 18.0);
}
pub fn adol_progress(m: &AdolescentMorph) -> f32 {
(m.age_years - 12.0) / 6.0
}
pub fn adol_hip_delta(m: &AdolescentMorph) -> f32 {
let t = adol_progress(m);
match m.config.sex {
AdolSex::Female => 0.2 * t,
AdolSex::Male => 0.05 * t,
}
}
pub fn adol_shoulder_delta(m: &AdolescentMorph) -> f32 {
let t = adol_progress(m);
match m.config.sex {
AdolSex::Male => 0.2 * t,
AdolSex::Female => 0.08 * t,
}
}
pub fn adol_to_json(m: &AdolescentMorph) -> String {
format!(
r#"{{"age_years":{:.1},"enabled":{},"hip_delta":{:.3}}}"#,
m.age_years,
m.enabled,
adol_hip_delta(m)
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_age_is_twelve() {
let m = new_adolescent_morph();
assert!((m.age_years - 12.0).abs() < 1e-6 );
}
#[test]
fn clamp_upper() {
let mut m = new_adolescent_morph();
adol_set_age(&mut m, 99.0);
assert!((m.age_years - 18.0).abs() < 1e-6 );
}
#[test]
fn progress_at_18() {
let mut m = new_adolescent_morph();
adol_set_age(&mut m, 18.0);
assert!((adol_progress(&m) - 1.0).abs() < 1e-6 );
}
#[test]
fn female_hip_delta_larger_than_male() {
let mut mf = new_adolescent_morph();
adol_set_age(&mut mf, 18.0);
let mut mm = new_adolescent_morph();
mm.config.sex = AdolSex::Male;
adol_set_age(&mut mm, 18.0);
assert!(adol_hip_delta(&mf) > adol_hip_delta(&mm) );
}
#[test]
fn male_shoulder_delta_larger() {
let mut mm = new_adolescent_morph();
mm.config.sex = AdolSex::Male;
adol_set_age(&mut mm, 18.0);
let mut mf = new_adolescent_morph();
adol_set_age(&mut mf, 18.0);
assert!(adol_shoulder_delta(&mm) > adol_shoulder_delta(&mf) );
}
#[test]
fn json_contains_age() {
let mut m = new_adolescent_morph();
adol_set_age(&mut m, 15.0);
assert!(adol_to_json(&m).contains("15.0") );
}
#[test]
fn enabled_default_true() {
let m = new_adolescent_morph();
assert!(m.enabled );
}
#[test]
fn hip_delta_zero_at_start() {
let mut m = new_adolescent_morph();
adol_set_age(&mut m, 12.0);
assert!((adol_hip_delta(&m) - 0.0).abs() < 1e-6 );
}
}