use serde::Serialize;
#[derive(Serialize, Debug, PartialEq)]
pub struct Zone {
pub name: String,
pub lower: u32,
pub upper: u32,
}
pub fn calc_power_zones(ftp: u32) -> Vec<Zone> {
let mut zones: Vec<Zone> = Vec::new();
let mut lower = 0;
for (name, upper_percent) in vec![
("Recovery", 0.55), ("Endurance", 0.75), ("Tempo", 0.9),
("Threshold", 1.05), ("VO2Max", 1.2), ("Anaerobic Capacity", 1.5)] {
let upper = watts(ftp, upper_percent);
zones.push(Zone{name: name.to_string(), lower, upper});
lower = upper+1;
}
zones
}
fn watts(ftp: u32, target: f32) -> u32 {
((ftp as f32) * target).round() as u32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zone1() {
let zones = calc_power_zones(189);
assert_eq!(zones[0], Zone{name: "Recovery".to_owned(), lower: 0, upper: 104});
assert_eq!(zones[1], Zone{name: "Endurance".to_owned(), lower: 105, upper: 142});
assert_eq!(zones[2], Zone{name: "Tempo".to_owned(), lower: 143, upper: 170});
assert_eq!(zones[3], Zone{name: "Threshold".to_owned(), lower: 171, upper: 198});
assert_eq!(zones[4], Zone{name: "VO2Max".to_owned(), lower: 199, upper: 227});
assert_eq!(zones[5], Zone{name: "Anaerobic Capacity".to_owned(), lower: 228, upper: 284});
}
}