#![allow(clippy::manual_range_patterns)]
use crate::profile::typedef::{self, FitBaseType};
use crate::proto::*;
use crate::semconv;
use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize, Serializer, ser::SerializeStruct};
fn is_expanded(state: &[u8], num: u8) -> bool {
match num {
5 | 6 | 19 | 29 | 73 | 78 | 108 => (state[num as usize >> 3] >> (num & 7)) & 1 == 1,
_ => false,
}
}
#[cfg_attr(feature = "serde", derive(Deserialize), serde(from = "De"))]
#[derive(Debug, Clone)]
pub struct Record {
pub timestamp: typedef::DateTime,
pub position_lat: i32,
pub position_long: i32,
pub altitude: u16,
pub heart_rate: u8,
pub cadence: u8,
pub distance: u32,
pub speed: u16,
pub power: u16,
pub compressed_speed_distance: [u8; 3],
pub grade: i16,
pub resistance: u8,
pub time_from_course: i32,
pub cycle_length: u8,
pub temperature: i8,
pub speed_1s: Vec<u8>,
pub cycles: u8,
pub total_cycles: u32,
pub compressed_accumulated_power: u16,
pub accumulated_power: u32,
pub left_right_balance: typedef::LeftRightBalance,
pub gps_accuracy: u8,
pub vertical_speed: i16,
pub calories: u16,
pub vertical_oscillation: u16,
pub stance_time_percent: u16,
pub stance_time: u16,
pub activity_type: typedef::ActivityType,
pub left_torque_effectiveness: u8,
pub right_torque_effectiveness: u8,
pub left_pedal_smoothness: u8,
pub right_pedal_smoothness: u8,
pub combined_pedal_smoothness: u8,
pub time128: u8,
pub stroke_type: typedef::StrokeType,
pub zone: u8,
pub ball_speed: u16,
pub cadence256: u16,
pub fractional_cadence: u8,
pub total_hemoglobin_conc: u16,
pub total_hemoglobin_conc_min: u16,
pub total_hemoglobin_conc_max: u16,
pub saturated_hemoglobin_percent: u16,
pub saturated_hemoglobin_percent_min: u16,
pub saturated_hemoglobin_percent_max: u16,
pub device_index: typedef::DeviceIndex,
pub left_pco: i8,
pub right_pco: i8,
pub left_power_phase: Vec<u8>,
pub left_power_phase_peak: Vec<u8>,
pub right_power_phase: Vec<u8>,
pub right_power_phase_peak: Vec<u8>,
pub enhanced_speed: u32,
pub enhanced_altitude: u32,
pub battery_soc: u8,
pub motor_power: u16,
pub vertical_ratio: u16,
pub stance_time_balance: u16,
pub step_length: u16,
pub cycle_length16: u16,
pub absolute_pressure: u32,
pub depth: u32,
pub next_stop_depth: u32,
pub next_stop_time: u32,
pub time_to_surface: u32,
pub ndl_time: u32,
pub cns_load: u8,
pub n2_load: u16,
pub respiration_rate: u8,
pub enhanced_respiration_rate: u16,
pub grit: f32,
pub flow: f32,
pub current_stress: u16,
pub ebike_travel_range: u16,
pub ebike_battery_level: u8,
pub ebike_assist_mode: u8,
pub ebike_assist_level_percent: u8,
pub air_time_remaining: u32,
pub pressure_sac: u16,
pub volume_sac: u16,
pub rmv: u16,
pub ascent_rate: i32,
pub po2: u8,
pub core_temperature: u16,
state: [u8; 14], pub unknown_fields: Vec<Field>,
pub developer_fields: Vec<DeveloperField>,
}
impl Record {
pub const TIMESTAMP: u8 = 253;
pub const POSITION_LAT: u8 = 0;
pub const POSITION_LONG: u8 = 1;
pub const ALTITUDE: u8 = 2;
pub const HEART_RATE: u8 = 3;
pub const CADENCE: u8 = 4;
pub const DISTANCE: u8 = 5;
pub const SPEED: u8 = 6;
pub const POWER: u8 = 7;
pub const COMPRESSED_SPEED_DISTANCE: u8 = 8;
pub const GRADE: u8 = 9;
pub const RESISTANCE: u8 = 10;
pub const TIME_FROM_COURSE: u8 = 11;
pub const CYCLE_LENGTH: u8 = 12;
pub const TEMPERATURE: u8 = 13;
pub const SPEED_1S: u8 = 17;
pub const CYCLES: u8 = 18;
pub const TOTAL_CYCLES: u8 = 19;
pub const COMPRESSED_ACCUMULATED_POWER: u8 = 28;
pub const ACCUMULATED_POWER: u8 = 29;
pub const LEFT_RIGHT_BALANCE: u8 = 30;
pub const GPS_ACCURACY: u8 = 31;
pub const VERTICAL_SPEED: u8 = 32;
pub const CALORIES: u8 = 33;
pub const VERTICAL_OSCILLATION: u8 = 39;
pub const STANCE_TIME_PERCENT: u8 = 40;
pub const STANCE_TIME: u8 = 41;
pub const ACTIVITY_TYPE: u8 = 42;
pub const LEFT_TORQUE_EFFECTIVENESS: u8 = 43;
pub const RIGHT_TORQUE_EFFECTIVENESS: u8 = 44;
pub const LEFT_PEDAL_SMOOTHNESS: u8 = 45;
pub const RIGHT_PEDAL_SMOOTHNESS: u8 = 46;
pub const COMBINED_PEDAL_SMOOTHNESS: u8 = 47;
pub const TIME128: u8 = 48;
pub const STROKE_TYPE: u8 = 49;
pub const ZONE: u8 = 50;
pub const BALL_SPEED: u8 = 51;
pub const CADENCE256: u8 = 52;
pub const FRACTIONAL_CADENCE: u8 = 53;
pub const TOTAL_HEMOGLOBIN_CONC: u8 = 54;
pub const TOTAL_HEMOGLOBIN_CONC_MIN: u8 = 55;
pub const TOTAL_HEMOGLOBIN_CONC_MAX: u8 = 56;
pub const SATURATED_HEMOGLOBIN_PERCENT: u8 = 57;
pub const SATURATED_HEMOGLOBIN_PERCENT_MIN: u8 = 58;
pub const SATURATED_HEMOGLOBIN_PERCENT_MAX: u8 = 59;
pub const DEVICE_INDEX: u8 = 62;
pub const LEFT_PCO: u8 = 67;
pub const RIGHT_PCO: u8 = 68;
pub const LEFT_POWER_PHASE: u8 = 69;
pub const LEFT_POWER_PHASE_PEAK: u8 = 70;
pub const RIGHT_POWER_PHASE: u8 = 71;
pub const RIGHT_POWER_PHASE_PEAK: u8 = 72;
pub const ENHANCED_SPEED: u8 = 73;
pub const ENHANCED_ALTITUDE: u8 = 78;
pub const BATTERY_SOC: u8 = 81;
pub const MOTOR_POWER: u8 = 82;
pub const VERTICAL_RATIO: u8 = 83;
pub const STANCE_TIME_BALANCE: u8 = 84;
pub const STEP_LENGTH: u8 = 85;
pub const CYCLE_LENGTH16: u8 = 87;
pub const ABSOLUTE_PRESSURE: u8 = 91;
pub const DEPTH: u8 = 92;
pub const NEXT_STOP_DEPTH: u8 = 93;
pub const NEXT_STOP_TIME: u8 = 94;
pub const TIME_TO_SURFACE: u8 = 95;
pub const NDL_TIME: u8 = 96;
pub const CNS_LOAD: u8 = 97;
pub const N2_LOAD: u8 = 98;
pub const RESPIRATION_RATE: u8 = 99;
pub const ENHANCED_RESPIRATION_RATE: u8 = 108;
pub const GRIT: u8 = 114;
pub const FLOW: u8 = 115;
pub const CURRENT_STRESS: u8 = 116;
pub const EBIKE_TRAVEL_RANGE: u8 = 117;
pub const EBIKE_BATTERY_LEVEL: u8 = 118;
pub const EBIKE_ASSIST_MODE: u8 = 119;
pub const EBIKE_ASSIST_LEVEL_PERCENT: u8 = 120;
pub const AIR_TIME_REMAINING: u8 = 123;
pub const PRESSURE_SAC: u8 = 124;
pub const VOLUME_SAC: u8 = 125;
pub const RMV: u8 = 126;
pub const ASCENT_RATE: u8 = 127;
pub const PO2: u8 = 129;
pub const CORE_TEMPERATURE: u8 = 139;
pub const fn new() -> Self {
Self {
timestamp: typedef::DateTime(u32::MAX),
position_lat: i32::MAX,
position_long: i32::MAX,
altitude: u16::MAX,
heart_rate: u8::MAX,
cadence: u8::MAX,
distance: u32::MAX,
speed: u16::MAX,
power: u16::MAX,
compressed_speed_distance: [u8::MAX; 3],
grade: i16::MAX,
resistance: u8::MAX,
time_from_course: i32::MAX,
cycle_length: u8::MAX,
temperature: i8::MAX,
speed_1s: Vec::new(),
cycles: u8::MAX,
total_cycles: u32::MAX,
compressed_accumulated_power: u16::MAX,
accumulated_power: u32::MAX,
left_right_balance: typedef::LeftRightBalance(u8::MAX),
gps_accuracy: u8::MAX,
vertical_speed: i16::MAX,
calories: u16::MAX,
vertical_oscillation: u16::MAX,
stance_time_percent: u16::MAX,
stance_time: u16::MAX,
activity_type: typedef::ActivityType(u8::MAX),
left_torque_effectiveness: u8::MAX,
right_torque_effectiveness: u8::MAX,
left_pedal_smoothness: u8::MAX,
right_pedal_smoothness: u8::MAX,
combined_pedal_smoothness: u8::MAX,
time128: u8::MAX,
stroke_type: typedef::StrokeType(u8::MAX),
zone: u8::MAX,
ball_speed: u16::MAX,
cadence256: u16::MAX,
fractional_cadence: u8::MAX,
total_hemoglobin_conc: u16::MAX,
total_hemoglobin_conc_min: u16::MAX,
total_hemoglobin_conc_max: u16::MAX,
saturated_hemoglobin_percent: u16::MAX,
saturated_hemoglobin_percent_min: u16::MAX,
saturated_hemoglobin_percent_max: u16::MAX,
device_index: typedef::DeviceIndex(u8::MAX),
left_pco: i8::MAX,
right_pco: i8::MAX,
left_power_phase: Vec::new(),
left_power_phase_peak: Vec::new(),
right_power_phase: Vec::new(),
right_power_phase_peak: Vec::new(),
enhanced_speed: u32::MAX,
enhanced_altitude: u32::MAX,
battery_soc: u8::MAX,
motor_power: u16::MAX,
vertical_ratio: u16::MAX,
stance_time_balance: u16::MAX,
step_length: u16::MAX,
cycle_length16: u16::MAX,
absolute_pressure: u32::MAX,
depth: u32::MAX,
next_stop_depth: u32::MAX,
next_stop_time: u32::MAX,
time_to_surface: u32::MAX,
ndl_time: u32::MAX,
cns_load: u8::MAX,
n2_load: u16::MAX,
respiration_rate: u8::MAX,
enhanced_respiration_rate: u16::MAX,
grit: f32::from_bits(u32::MAX),
flow: f32::from_bits(u32::MAX),
current_stress: u16::MAX,
ebike_travel_range: u16::MAX,
ebike_battery_level: u8::MAX,
ebike_assist_mode: u8::MAX,
ebike_assist_level_percent: u8::MAX,
air_time_remaining: u32::MAX,
pressure_sac: u16::MAX,
volume_sac: u16::MAX,
rmv: u16::MAX,
ascent_rate: i32::MAX,
po2: u8::MAX,
core_temperature: u16::MAX,
state: [0u8; 14],
unknown_fields: Vec::new(),
developer_fields: Vec::new(),
}
}
pub fn position_lat_degrees(&self) -> Option<f64> {
semconv::to_degrees(self.position_lat)
}
pub fn set_position_lat_degrees(&mut self, v: f64) -> &mut Self {
self.position_lat = semconv::to_semicircles(v).unwrap_or(i32::MAX);
self
}
pub fn position_long_degrees(&self) -> Option<f64> {
semconv::to_degrees(self.position_long)
}
pub fn set_position_long_degrees(&mut self, v: f64) -> &mut Self {
self.position_long = semconv::to_semicircles(v).unwrap_or(i32::MAX);
self
}
pub fn altitude_scaled(&self) -> Option<f64> {
if self.altitude == u16::MAX {
return None;
}
Some(self.altitude as f64 / 5.0 - 500.0)
}
pub fn set_altitude_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 500.0) * 5.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.altitude = u16::MAX;
return self;
}
self.altitude = unscaled as u16;
self
}
pub fn distance_scaled(&self) -> Option<f64> {
if self.distance == u32::MAX {
return None;
}
Some(self.distance as f64 / 100.0 - 0.0)
}
pub fn set_distance_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
self.distance = u32::MAX;
return self;
}
self.distance = unscaled as u32;
self
}
pub fn speed_scaled(&self) -> Option<f64> {
if self.speed == u16::MAX {
return None;
}
Some(self.speed as f64 / 1000.0 - 0.0)
}
pub fn set_speed_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.speed = u16::MAX;
return self;
}
self.speed = unscaled as u16;
self
}
pub fn grade_scaled(&self) -> Option<f64> {
if self.grade == i16::MAX {
return None;
}
Some(self.grade as f64 / 100.0 - 0.0)
}
pub fn set_grade_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i16::MAX as f64 {
self.grade = i16::MAX;
return self;
}
self.grade = unscaled as i16;
self
}
pub fn time_from_course_scaled(&self) -> Option<f64> {
if self.time_from_course == i32::MAX {
return None;
}
Some(self.time_from_course as f64 / 1000.0 - 0.0)
}
pub fn set_time_from_course_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i32::MAX as f64 {
self.time_from_course = i32::MAX;
return self;
}
self.time_from_course = unscaled as i32;
self
}
pub fn cycle_length_scaled(&self) -> Option<f64> {
if self.cycle_length == u8::MAX {
return None;
}
Some(self.cycle_length as f64 / 100.0 - 0.0)
}
pub fn set_cycle_length_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.cycle_length = u8::MAX;
return self;
}
self.cycle_length = unscaled as u8;
self
}
pub fn speed_1s_scaled(&self) -> Option<Vec<f64>> {
if self.speed_1s.is_empty() {
return None;
}
let mut v = Vec::with_capacity(self.speed_1s.len());
for &x in &self.speed_1s {
v.push(x as f64 / 16.0 - 0.0)
}
Some(v)
}
pub fn set_speed_1s_scaled(&mut self, v: &[f64]) -> &mut Self {
self.speed_1s = Vec::with_capacity(v.len());
if v.is_empty() {
return self;
}
for &x in v {
let unscaled = (x + 0.0) * 16.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.speed_1s.push(u8::MAX);
continue;
}
self.speed_1s.push(unscaled as u8);
}
self
}
pub fn vertical_speed_scaled(&self) -> Option<f64> {
if self.vertical_speed == i16::MAX {
return None;
}
Some(self.vertical_speed as f64 / 1000.0 - 0.0)
}
pub fn set_vertical_speed_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i16::MAX as f64 {
self.vertical_speed = i16::MAX;
return self;
}
self.vertical_speed = unscaled as i16;
self
}
pub fn vertical_oscillation_scaled(&self) -> Option<f64> {
if self.vertical_oscillation == u16::MAX {
return None;
}
Some(self.vertical_oscillation as f64 / 10.0 - 0.0)
}
pub fn set_vertical_oscillation_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.vertical_oscillation = u16::MAX;
return self;
}
self.vertical_oscillation = unscaled as u16;
self
}
pub fn stance_time_percent_scaled(&self) -> Option<f64> {
if self.stance_time_percent == u16::MAX {
return None;
}
Some(self.stance_time_percent as f64 / 100.0 - 0.0)
}
pub fn set_stance_time_percent_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.stance_time_percent = u16::MAX;
return self;
}
self.stance_time_percent = unscaled as u16;
self
}
pub fn stance_time_scaled(&self) -> Option<f64> {
if self.stance_time == u16::MAX {
return None;
}
Some(self.stance_time as f64 / 10.0 - 0.0)
}
pub fn set_stance_time_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.stance_time = u16::MAX;
return self;
}
self.stance_time = unscaled as u16;
self
}
pub fn left_torque_effectiveness_scaled(&self) -> Option<f64> {
if self.left_torque_effectiveness == u8::MAX {
return None;
}
Some(self.left_torque_effectiveness as f64 / 2.0 - 0.0)
}
pub fn set_left_torque_effectiveness_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.left_torque_effectiveness = u8::MAX;
return self;
}
self.left_torque_effectiveness = unscaled as u8;
self
}
pub fn right_torque_effectiveness_scaled(&self) -> Option<f64> {
if self.right_torque_effectiveness == u8::MAX {
return None;
}
Some(self.right_torque_effectiveness as f64 / 2.0 - 0.0)
}
pub fn set_right_torque_effectiveness_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.right_torque_effectiveness = u8::MAX;
return self;
}
self.right_torque_effectiveness = unscaled as u8;
self
}
pub fn left_pedal_smoothness_scaled(&self) -> Option<f64> {
if self.left_pedal_smoothness == u8::MAX {
return None;
}
Some(self.left_pedal_smoothness as f64 / 2.0 - 0.0)
}
pub fn set_left_pedal_smoothness_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.left_pedal_smoothness = u8::MAX;
return self;
}
self.left_pedal_smoothness = unscaled as u8;
self
}
pub fn right_pedal_smoothness_scaled(&self) -> Option<f64> {
if self.right_pedal_smoothness == u8::MAX {
return None;
}
Some(self.right_pedal_smoothness as f64 / 2.0 - 0.0)
}
pub fn set_right_pedal_smoothness_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.right_pedal_smoothness = u8::MAX;
return self;
}
self.right_pedal_smoothness = unscaled as u8;
self
}
pub fn combined_pedal_smoothness_scaled(&self) -> Option<f64> {
if self.combined_pedal_smoothness == u8::MAX {
return None;
}
Some(self.combined_pedal_smoothness as f64 / 2.0 - 0.0)
}
pub fn set_combined_pedal_smoothness_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.combined_pedal_smoothness = u8::MAX;
return self;
}
self.combined_pedal_smoothness = unscaled as u8;
self
}
pub fn time128_scaled(&self) -> Option<f64> {
if self.time128 == u8::MAX {
return None;
}
Some(self.time128 as f64 / 128.0 - 0.0)
}
pub fn set_time128_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 128.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.time128 = u8::MAX;
return self;
}
self.time128 = unscaled as u8;
self
}
pub fn ball_speed_scaled(&self) -> Option<f64> {
if self.ball_speed == u16::MAX {
return None;
}
Some(self.ball_speed as f64 / 100.0 - 0.0)
}
pub fn set_ball_speed_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.ball_speed = u16::MAX;
return self;
}
self.ball_speed = unscaled as u16;
self
}
pub fn cadence256_scaled(&self) -> Option<f64> {
if self.cadence256 == u16::MAX {
return None;
}
Some(self.cadence256 as f64 / 256.0 - 0.0)
}
pub fn set_cadence256_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 256.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.cadence256 = u16::MAX;
return self;
}
self.cadence256 = unscaled as u16;
self
}
pub fn fractional_cadence_scaled(&self) -> Option<f64> {
if self.fractional_cadence == u8::MAX {
return None;
}
Some(self.fractional_cadence as f64 / 128.0 - 0.0)
}
pub fn set_fractional_cadence_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 128.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.fractional_cadence = u8::MAX;
return self;
}
self.fractional_cadence = unscaled as u8;
self
}
pub fn total_hemoglobin_conc_scaled(&self) -> Option<f64> {
if self.total_hemoglobin_conc == u16::MAX {
return None;
}
Some(self.total_hemoglobin_conc as f64 / 100.0 - 0.0)
}
pub fn set_total_hemoglobin_conc_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.total_hemoglobin_conc = u16::MAX;
return self;
}
self.total_hemoglobin_conc = unscaled as u16;
self
}
pub fn total_hemoglobin_conc_min_scaled(&self) -> Option<f64> {
if self.total_hemoglobin_conc_min == u16::MAX {
return None;
}
Some(self.total_hemoglobin_conc_min as f64 / 100.0 - 0.0)
}
pub fn set_total_hemoglobin_conc_min_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.total_hemoglobin_conc_min = u16::MAX;
return self;
}
self.total_hemoglobin_conc_min = unscaled as u16;
self
}
pub fn total_hemoglobin_conc_max_scaled(&self) -> Option<f64> {
if self.total_hemoglobin_conc_max == u16::MAX {
return None;
}
Some(self.total_hemoglobin_conc_max as f64 / 100.0 - 0.0)
}
pub fn set_total_hemoglobin_conc_max_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.total_hemoglobin_conc_max = u16::MAX;
return self;
}
self.total_hemoglobin_conc_max = unscaled as u16;
self
}
pub fn saturated_hemoglobin_percent_scaled(&self) -> Option<f64> {
if self.saturated_hemoglobin_percent == u16::MAX {
return None;
}
Some(self.saturated_hemoglobin_percent as f64 / 10.0 - 0.0)
}
pub fn set_saturated_hemoglobin_percent_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.saturated_hemoglobin_percent = u16::MAX;
return self;
}
self.saturated_hemoglobin_percent = unscaled as u16;
self
}
pub fn saturated_hemoglobin_percent_min_scaled(&self) -> Option<f64> {
if self.saturated_hemoglobin_percent_min == u16::MAX {
return None;
}
Some(self.saturated_hemoglobin_percent_min as f64 / 10.0 - 0.0)
}
pub fn set_saturated_hemoglobin_percent_min_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.saturated_hemoglobin_percent_min = u16::MAX;
return self;
}
self.saturated_hemoglobin_percent_min = unscaled as u16;
self
}
pub fn saturated_hemoglobin_percent_max_scaled(&self) -> Option<f64> {
if self.saturated_hemoglobin_percent_max == u16::MAX {
return None;
}
Some(self.saturated_hemoglobin_percent_max as f64 / 10.0 - 0.0)
}
pub fn set_saturated_hemoglobin_percent_max_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.saturated_hemoglobin_percent_max = u16::MAX;
return self;
}
self.saturated_hemoglobin_percent_max = unscaled as u16;
self
}
pub fn left_power_phase_scaled(&self) -> Option<Vec<f64>> {
if self.left_power_phase.is_empty() {
return None;
}
let mut v = Vec::with_capacity(self.left_power_phase.len());
for &x in &self.left_power_phase {
v.push(x as f64 / 0.7111111 - 0.0)
}
Some(v)
}
pub fn set_left_power_phase_scaled(&mut self, v: &[f64]) -> &mut Self {
self.left_power_phase = Vec::with_capacity(v.len());
if v.is_empty() {
return self;
}
for &x in v {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.left_power_phase.push(u8::MAX);
continue;
}
self.left_power_phase.push(unscaled as u8);
}
self
}
pub fn left_power_phase_peak_scaled(&self) -> Option<Vec<f64>> {
if self.left_power_phase_peak.is_empty() {
return None;
}
let mut v = Vec::with_capacity(self.left_power_phase_peak.len());
for &x in &self.left_power_phase_peak {
v.push(x as f64 / 0.7111111 - 0.0)
}
Some(v)
}
pub fn set_left_power_phase_peak_scaled(&mut self, v: &[f64]) -> &mut Self {
self.left_power_phase_peak = Vec::with_capacity(v.len());
if v.is_empty() {
return self;
}
for &x in v {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.left_power_phase_peak.push(u8::MAX);
continue;
}
self.left_power_phase_peak.push(unscaled as u8);
}
self
}
pub fn right_power_phase_scaled(&self) -> Option<Vec<f64>> {
if self.right_power_phase.is_empty() {
return None;
}
let mut v = Vec::with_capacity(self.right_power_phase.len());
for &x in &self.right_power_phase {
v.push(x as f64 / 0.7111111 - 0.0)
}
Some(v)
}
pub fn set_right_power_phase_scaled(&mut self, v: &[f64]) -> &mut Self {
self.right_power_phase = Vec::with_capacity(v.len());
if v.is_empty() {
return self;
}
for &x in v {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.right_power_phase.push(u8::MAX);
continue;
}
self.right_power_phase.push(unscaled as u8);
}
self
}
pub fn right_power_phase_peak_scaled(&self) -> Option<Vec<f64>> {
if self.right_power_phase_peak.is_empty() {
return None;
}
let mut v = Vec::with_capacity(self.right_power_phase_peak.len());
for &x in &self.right_power_phase_peak {
v.push(x as f64 / 0.7111111 - 0.0)
}
Some(v)
}
pub fn set_right_power_phase_peak_scaled(&mut self, v: &[f64]) -> &mut Self {
self.right_power_phase_peak = Vec::with_capacity(v.len());
if v.is_empty() {
return self;
}
for &x in v {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.right_power_phase_peak.push(u8::MAX);
continue;
}
self.right_power_phase_peak.push(unscaled as u8);
}
self
}
pub fn enhanced_speed_scaled(&self) -> Option<f64> {
if self.enhanced_speed == u32::MAX {
return None;
}
Some(self.enhanced_speed as f64 / 1000.0 - 0.0)
}
pub fn set_enhanced_speed_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
self.enhanced_speed = u32::MAX;
return self;
}
self.enhanced_speed = unscaled as u32;
self
}
pub fn enhanced_altitude_scaled(&self) -> Option<f64> {
if self.enhanced_altitude == u32::MAX {
return None;
}
Some(self.enhanced_altitude as f64 / 5.0 - 500.0)
}
pub fn set_enhanced_altitude_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 500.0) * 5.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
self.enhanced_altitude = u32::MAX;
return self;
}
self.enhanced_altitude = unscaled as u32;
self
}
pub fn battery_soc_scaled(&self) -> Option<f64> {
if self.battery_soc == u8::MAX {
return None;
}
Some(self.battery_soc as f64 / 2.0 - 0.0)
}
pub fn set_battery_soc_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.battery_soc = u8::MAX;
return self;
}
self.battery_soc = unscaled as u8;
self
}
pub fn vertical_ratio_scaled(&self) -> Option<f64> {
if self.vertical_ratio == u16::MAX {
return None;
}
Some(self.vertical_ratio as f64 / 100.0 - 0.0)
}
pub fn set_vertical_ratio_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.vertical_ratio = u16::MAX;
return self;
}
self.vertical_ratio = unscaled as u16;
self
}
pub fn stance_time_balance_scaled(&self) -> Option<f64> {
if self.stance_time_balance == u16::MAX {
return None;
}
Some(self.stance_time_balance as f64 / 100.0 - 0.0)
}
pub fn set_stance_time_balance_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.stance_time_balance = u16::MAX;
return self;
}
self.stance_time_balance = unscaled as u16;
self
}
pub fn step_length_scaled(&self) -> Option<f64> {
if self.step_length == u16::MAX {
return None;
}
Some(self.step_length as f64 / 10.0 - 0.0)
}
pub fn set_step_length_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.step_length = u16::MAX;
return self;
}
self.step_length = unscaled as u16;
self
}
pub fn cycle_length16_scaled(&self) -> Option<f64> {
if self.cycle_length16 == u16::MAX {
return None;
}
Some(self.cycle_length16 as f64 / 100.0 - 0.0)
}
pub fn set_cycle_length16_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.cycle_length16 = u16::MAX;
return self;
}
self.cycle_length16 = unscaled as u16;
self
}
pub fn depth_scaled(&self) -> Option<f64> {
if self.depth == u32::MAX {
return None;
}
Some(self.depth as f64 / 1000.0 - 0.0)
}
pub fn set_depth_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
self.depth = u32::MAX;
return self;
}
self.depth = unscaled as u32;
self
}
pub fn next_stop_depth_scaled(&self) -> Option<f64> {
if self.next_stop_depth == u32::MAX {
return None;
}
Some(self.next_stop_depth as f64 / 1000.0 - 0.0)
}
pub fn set_next_stop_depth_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
self.next_stop_depth = u32::MAX;
return self;
}
self.next_stop_depth = unscaled as u32;
self
}
pub fn enhanced_respiration_rate_scaled(&self) -> Option<f64> {
if self.enhanced_respiration_rate == u16::MAX {
return None;
}
Some(self.enhanced_respiration_rate as f64 / 100.0 - 0.0)
}
pub fn set_enhanced_respiration_rate_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.enhanced_respiration_rate = u16::MAX;
return self;
}
self.enhanced_respiration_rate = unscaled as u16;
self
}
pub fn current_stress_scaled(&self) -> Option<f64> {
if self.current_stress == u16::MAX {
return None;
}
Some(self.current_stress as f64 / 100.0 - 0.0)
}
pub fn set_current_stress_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.current_stress = u16::MAX;
return self;
}
self.current_stress = unscaled as u16;
self
}
pub fn pressure_sac_scaled(&self) -> Option<f64> {
if self.pressure_sac == u16::MAX {
return None;
}
Some(self.pressure_sac as f64 / 100.0 - 0.0)
}
pub fn set_pressure_sac_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.pressure_sac = u16::MAX;
return self;
}
self.pressure_sac = unscaled as u16;
self
}
pub fn volume_sac_scaled(&self) -> Option<f64> {
if self.volume_sac == u16::MAX {
return None;
}
Some(self.volume_sac as f64 / 100.0 - 0.0)
}
pub fn set_volume_sac_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.volume_sac = u16::MAX;
return self;
}
self.volume_sac = unscaled as u16;
self
}
pub fn rmv_scaled(&self) -> Option<f64> {
if self.rmv == u16::MAX {
return None;
}
Some(self.rmv as f64 / 100.0 - 0.0)
}
pub fn set_rmv_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.rmv = u16::MAX;
return self;
}
self.rmv = unscaled as u16;
self
}
pub fn ascent_rate_scaled(&self) -> Option<f64> {
if self.ascent_rate == i32::MAX {
return None;
}
Some(self.ascent_rate as f64 / 1000.0 - 0.0)
}
pub fn set_ascent_rate_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i32::MAX as f64 {
self.ascent_rate = i32::MAX;
return self;
}
self.ascent_rate = unscaled as i32;
self
}
pub fn po2_scaled(&self) -> Option<f64> {
if self.po2 == u8::MAX {
return None;
}
Some(self.po2 as f64 / 100.0 - 0.0)
}
pub fn set_po2_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.po2 = u8::MAX;
return self;
}
self.po2 = unscaled as u8;
self
}
pub fn core_temperature_scaled(&self) -> Option<f64> {
if self.core_temperature == u16::MAX {
return None;
}
Some(self.core_temperature as f64 / 100.0 - 0.0)
}
pub fn set_core_temperature_scaled(&mut self, v: f64) -> &mut Self {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.core_temperature = u16::MAX;
return self;
}
self.core_temperature = unscaled as u16;
self
}
pub fn mark_as_expanded(&mut self, num: u8, flag: bool) -> bool {
match num {
5 | 6 | 19 | 29 | 73 | 78 | 108 => {
if flag {
self.state[num as usize >> 3] |= 1 << (num & 7)
} else {
self.state[num as usize >> 3] &= !(1 << (num & 7))
}
true
}
_ => false,
}
}
pub fn is_expanded(&self, num: u8) -> bool {
is_expanded(&self.state, num)
}
fn count_valid_fields(&self) -> usize {
(self.timestamp.0 != u32::MAX) as usize
+ (self.position_lat != i32::MAX) as usize
+ (self.position_long != i32::MAX) as usize
+ (self.altitude != u16::MAX) as usize
+ (self.heart_rate != u8::MAX) as usize
+ (self.cadence != u8::MAX) as usize
+ (self.distance != u32::MAX) as usize
+ (self.speed != u16::MAX) as usize
+ (self.power != u16::MAX) as usize
+ (self.compressed_speed_distance != [u8::MAX; 3]) as usize
+ (self.grade != i16::MAX) as usize
+ (self.resistance != u8::MAX) as usize
+ (self.time_from_course != i32::MAX) as usize
+ (self.cycle_length != u8::MAX) as usize
+ (self.temperature != i8::MAX) as usize
+ (!self.speed_1s.is_empty()) as usize
+ (self.cycles != u8::MAX) as usize
+ (self.total_cycles != u32::MAX) as usize
+ (self.compressed_accumulated_power != u16::MAX) as usize
+ (self.accumulated_power != u32::MAX) as usize
+ (self.left_right_balance.0 != u8::MAX) as usize
+ (self.gps_accuracy != u8::MAX) as usize
+ (self.vertical_speed != i16::MAX) as usize
+ (self.calories != u16::MAX) as usize
+ (self.vertical_oscillation != u16::MAX) as usize
+ (self.stance_time_percent != u16::MAX) as usize
+ (self.stance_time != u16::MAX) as usize
+ (self.activity_type.0 != u8::MAX) as usize
+ (self.left_torque_effectiveness != u8::MAX) as usize
+ (self.right_torque_effectiveness != u8::MAX) as usize
+ (self.left_pedal_smoothness != u8::MAX) as usize
+ (self.right_pedal_smoothness != u8::MAX) as usize
+ (self.combined_pedal_smoothness != u8::MAX) as usize
+ (self.time128 != u8::MAX) as usize
+ (self.stroke_type.0 != u8::MAX) as usize
+ (self.zone != u8::MAX) as usize
+ (self.ball_speed != u16::MAX) as usize
+ (self.cadence256 != u16::MAX) as usize
+ (self.fractional_cadence != u8::MAX) as usize
+ (self.total_hemoglobin_conc != u16::MAX) as usize
+ (self.total_hemoglobin_conc_min != u16::MAX) as usize
+ (self.total_hemoglobin_conc_max != u16::MAX) as usize
+ (self.saturated_hemoglobin_percent != u16::MAX) as usize
+ (self.saturated_hemoglobin_percent_min != u16::MAX) as usize
+ (self.saturated_hemoglobin_percent_max != u16::MAX) as usize
+ (self.device_index.0 != u8::MAX) as usize
+ (self.left_pco != i8::MAX) as usize
+ (self.right_pco != i8::MAX) as usize
+ (!self.left_power_phase.is_empty()) as usize
+ (!self.left_power_phase_peak.is_empty()) as usize
+ (!self.right_power_phase.is_empty()) as usize
+ (!self.right_power_phase_peak.is_empty()) as usize
+ (self.enhanced_speed != u32::MAX) as usize
+ (self.enhanced_altitude != u32::MAX) as usize
+ (self.battery_soc != u8::MAX) as usize
+ (self.motor_power != u16::MAX) as usize
+ (self.vertical_ratio != u16::MAX) as usize
+ (self.stance_time_balance != u16::MAX) as usize
+ (self.step_length != u16::MAX) as usize
+ (self.cycle_length16 != u16::MAX) as usize
+ (self.absolute_pressure != u32::MAX) as usize
+ (self.depth != u32::MAX) as usize
+ (self.next_stop_depth != u32::MAX) as usize
+ (self.next_stop_time != u32::MAX) as usize
+ (self.time_to_surface != u32::MAX) as usize
+ (self.ndl_time != u32::MAX) as usize
+ (self.cns_load != u8::MAX) as usize
+ (self.n2_load != u16::MAX) as usize
+ (self.respiration_rate != u8::MAX) as usize
+ (self.enhanced_respiration_rate != u16::MAX) as usize
+ (self.grit.to_bits() != u32::MAX) as usize
+ (self.flow.to_bits() != u32::MAX) as usize
+ (self.current_stress != u16::MAX) as usize
+ (self.ebike_travel_range != u16::MAX) as usize
+ (self.ebike_battery_level != u8::MAX) as usize
+ (self.ebike_assist_mode != u8::MAX) as usize
+ (self.ebike_assist_level_percent != u8::MAX) as usize
+ (self.air_time_remaining != u32::MAX) as usize
+ (self.pressure_sac != u16::MAX) as usize
+ (self.volume_sac != u16::MAX) as usize
+ (self.rmv != u16::MAX) as usize
+ (self.ascent_rate != i32::MAX) as usize
+ (self.po2 != u8::MAX) as usize
+ (self.core_temperature != u16::MAX) as usize
}
}
impl Default for Record {
fn default() -> Self {
Self::new()
}
}
impl From<&Message> for Record {
fn from(mesg: &Message) -> Self {
const KNOWN_NUMS: [u64; 4] = [
5764606990190788607,
18013290270358914040,
2050,
2305843009213693952,
];
let mut n = 0u64;
for field in &mesg.fields {
n += (KNOWN_NUMS[field.num as usize >> 6] >> (field.num & 63)) & 1 ^ 1
}
let mut v = Self::new();
v.unknown_fields = Vec::<Field>::with_capacity(n as usize);
v.developer_fields = mesg.developer_fields.clone();
for field in &mesg.fields {
match field.num {
253 => v.timestamp = typedef::DateTime(field.value.as_u32()),
0 => v.position_lat = field.value.as_i32(),
1 => v.position_long = field.value.as_i32(),
2 => v.altitude = field.value.as_u16(),
3 => v.heart_rate = field.value.as_u8(),
4 => v.cadence = field.value.as_u8(),
5 => v.distance = field.value.as_u32(),
6 => v.speed = field.value.as_u16(),
7 => v.power = field.value.as_u16(),
8 => {
v.compressed_speed_distance = match &field.value {
Value::VecUint8(v) => {
let mut arr = [u8::MAX; 3];
for (i, x) in v.iter().take(3).enumerate() {
arr[i] = *x;
}
arr
}
_ => [u8::MAX; 3],
}
}
9 => v.grade = field.value.as_i16(),
10 => v.resistance = field.value.as_u8(),
11 => v.time_from_course = field.value.as_i32(),
12 => v.cycle_length = field.value.as_u8(),
13 => v.temperature = field.value.as_i8(),
17 => v.speed_1s = field.value.to_vec_u8(),
18 => v.cycles = field.value.as_u8(),
19 => v.total_cycles = field.value.as_u32(),
28 => v.compressed_accumulated_power = field.value.as_u16(),
29 => v.accumulated_power = field.value.as_u32(),
30 => v.left_right_balance = typedef::LeftRightBalance(field.value.as_u8()),
31 => v.gps_accuracy = field.value.as_u8(),
32 => v.vertical_speed = field.value.as_i16(),
33 => v.calories = field.value.as_u16(),
39 => v.vertical_oscillation = field.value.as_u16(),
40 => v.stance_time_percent = field.value.as_u16(),
41 => v.stance_time = field.value.as_u16(),
42 => v.activity_type = typedef::ActivityType(field.value.as_u8()),
43 => v.left_torque_effectiveness = field.value.as_u8(),
44 => v.right_torque_effectiveness = field.value.as_u8(),
45 => v.left_pedal_smoothness = field.value.as_u8(),
46 => v.right_pedal_smoothness = field.value.as_u8(),
47 => v.combined_pedal_smoothness = field.value.as_u8(),
48 => v.time128 = field.value.as_u8(),
49 => v.stroke_type = typedef::StrokeType(field.value.as_u8()),
50 => v.zone = field.value.as_u8(),
51 => v.ball_speed = field.value.as_u16(),
52 => v.cadence256 = field.value.as_u16(),
53 => v.fractional_cadence = field.value.as_u8(),
54 => v.total_hemoglobin_conc = field.value.as_u16(),
55 => v.total_hemoglobin_conc_min = field.value.as_u16(),
56 => v.total_hemoglobin_conc_max = field.value.as_u16(),
57 => v.saturated_hemoglobin_percent = field.value.as_u16(),
58 => v.saturated_hemoglobin_percent_min = field.value.as_u16(),
59 => v.saturated_hemoglobin_percent_max = field.value.as_u16(),
62 => v.device_index = typedef::DeviceIndex(field.value.as_u8()),
67 => v.left_pco = field.value.as_i8(),
68 => v.right_pco = field.value.as_i8(),
69 => v.left_power_phase = field.value.to_vec_u8(),
70 => v.left_power_phase_peak = field.value.to_vec_u8(),
71 => v.right_power_phase = field.value.to_vec_u8(),
72 => v.right_power_phase_peak = field.value.to_vec_u8(),
73 => v.enhanced_speed = field.value.as_u32(),
78 => v.enhanced_altitude = field.value.as_u32(),
81 => v.battery_soc = field.value.as_u8(),
82 => v.motor_power = field.value.as_u16(),
83 => v.vertical_ratio = field.value.as_u16(),
84 => v.stance_time_balance = field.value.as_u16(),
85 => v.step_length = field.value.as_u16(),
87 => v.cycle_length16 = field.value.as_u16(),
91 => v.absolute_pressure = field.value.as_u32(),
92 => v.depth = field.value.as_u32(),
93 => v.next_stop_depth = field.value.as_u32(),
94 => v.next_stop_time = field.value.as_u32(),
95 => v.time_to_surface = field.value.as_u32(),
96 => v.ndl_time = field.value.as_u32(),
97 => v.cns_load = field.value.as_u8(),
98 => v.n2_load = field.value.as_u16(),
99 => v.respiration_rate = field.value.as_u8(),
108 => v.enhanced_respiration_rate = field.value.as_u16(),
114 => v.grit = field.value.as_f32(),
115 => v.flow = field.value.as_f32(),
116 => v.current_stress = field.value.as_u16(),
117 => v.ebike_travel_range = field.value.as_u16(),
118 => v.ebike_battery_level = field.value.as_u8(),
119 => v.ebike_assist_mode = field.value.as_u8(),
120 => v.ebike_assist_level_percent = field.value.as_u8(),
123 => v.air_time_remaining = field.value.as_u32(),
124 => v.pressure_sac = field.value.as_u16(),
125 => v.volume_sac = field.value.as_u16(),
126 => v.rmv = field.value.as_u16(),
127 => v.ascent_rate = field.value.as_i32(),
129 => v.po2 = field.value.as_u8(),
139 => v.core_temperature = field.value.as_u16(),
_ => {
v.unknown_fields.push(field.clone());
continue;
}
};
if field.is_expanded && field.num < 109 {
v.state[field.num as usize >> 3] |= 1 << (field.num & 7)
}
}
v
}
}
impl From<Record> for Message {
fn from(m: Record) -> Self {
let mut fields =
Vec::<Field>::with_capacity(m.count_valid_fields() + m.unknown_fields.len());
if m.timestamp.0 != u32::MAX {
fields.push(Field {
num: 253,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.timestamp.0),
is_expanded: false,
});
};
if m.position_lat != i32::MAX {
fields.push(Field {
num: 0,
base_type: FitBaseType::SINT32,
value: Value::Int32(m.position_lat),
is_expanded: false,
});
};
if m.position_long != i32::MAX {
fields.push(Field {
num: 1,
base_type: FitBaseType::SINT32,
value: Value::Int32(m.position_long),
is_expanded: false,
});
};
if m.altitude != u16::MAX {
fields.push(Field {
num: 2,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.altitude),
is_expanded: false,
});
};
if m.heart_rate != u8::MAX {
fields.push(Field {
num: 3,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.heart_rate),
is_expanded: false,
});
};
if m.cadence != u8::MAX {
fields.push(Field {
num: 4,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.cadence),
is_expanded: false,
});
};
if m.distance != u32::MAX {
fields.push(Field {
num: 5,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.distance),
is_expanded: is_expanded(&m.state, 5),
});
};
if m.speed != u16::MAX {
fields.push(Field {
num: 6,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.speed),
is_expanded: is_expanded(&m.state, 6),
});
};
if m.power != u16::MAX {
fields.push(Field {
num: 7,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.power),
is_expanded: false,
});
};
if m.compressed_speed_distance != [u8::MAX; 3] {
fields.push(Field {
num: 8,
base_type: FitBaseType::BYTE,
value: Value::VecUint8(Vec::from(&m.compressed_speed_distance)),
is_expanded: false,
});
};
if m.grade != i16::MAX {
fields.push(Field {
num: 9,
base_type: FitBaseType::SINT16,
value: Value::Int16(m.grade),
is_expanded: false,
});
};
if m.resistance != u8::MAX {
fields.push(Field {
num: 10,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.resistance),
is_expanded: false,
});
};
if m.time_from_course != i32::MAX {
fields.push(Field {
num: 11,
base_type: FitBaseType::SINT32,
value: Value::Int32(m.time_from_course),
is_expanded: false,
});
};
if m.cycle_length != u8::MAX {
fields.push(Field {
num: 12,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.cycle_length),
is_expanded: false,
});
};
if m.temperature != i8::MAX {
fields.push(Field {
num: 13,
base_type: FitBaseType::SINT8,
value: Value::Int8(m.temperature),
is_expanded: false,
});
};
if !m.speed_1s.is_empty() {
fields.push(Field {
num: 17,
base_type: FitBaseType::UINT8,
value: Value::VecUint8(m.speed_1s),
is_expanded: false,
});
};
if m.cycles != u8::MAX {
fields.push(Field {
num: 18,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.cycles),
is_expanded: false,
});
};
if m.total_cycles != u32::MAX {
fields.push(Field {
num: 19,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.total_cycles),
is_expanded: is_expanded(&m.state, 19),
});
};
if m.compressed_accumulated_power != u16::MAX {
fields.push(Field {
num: 28,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.compressed_accumulated_power),
is_expanded: false,
});
};
if m.accumulated_power != u32::MAX {
fields.push(Field {
num: 29,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.accumulated_power),
is_expanded: is_expanded(&m.state, 29),
});
};
if m.left_right_balance.0 != u8::MAX {
fields.push(Field {
num: 30,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.left_right_balance.0),
is_expanded: false,
});
};
if m.gps_accuracy != u8::MAX {
fields.push(Field {
num: 31,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.gps_accuracy),
is_expanded: false,
});
};
if m.vertical_speed != i16::MAX {
fields.push(Field {
num: 32,
base_type: FitBaseType::SINT16,
value: Value::Int16(m.vertical_speed),
is_expanded: false,
});
};
if m.calories != u16::MAX {
fields.push(Field {
num: 33,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.calories),
is_expanded: false,
});
};
if m.vertical_oscillation != u16::MAX {
fields.push(Field {
num: 39,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.vertical_oscillation),
is_expanded: false,
});
};
if m.stance_time_percent != u16::MAX {
fields.push(Field {
num: 40,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.stance_time_percent),
is_expanded: false,
});
};
if m.stance_time != u16::MAX {
fields.push(Field {
num: 41,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.stance_time),
is_expanded: false,
});
};
if m.activity_type.0 != u8::MAX {
fields.push(Field {
num: 42,
base_type: FitBaseType::ENUM,
value: Value::Uint8(m.activity_type.0),
is_expanded: false,
});
};
if m.left_torque_effectiveness != u8::MAX {
fields.push(Field {
num: 43,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.left_torque_effectiveness),
is_expanded: false,
});
};
if m.right_torque_effectiveness != u8::MAX {
fields.push(Field {
num: 44,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.right_torque_effectiveness),
is_expanded: false,
});
};
if m.left_pedal_smoothness != u8::MAX {
fields.push(Field {
num: 45,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.left_pedal_smoothness),
is_expanded: false,
});
};
if m.right_pedal_smoothness != u8::MAX {
fields.push(Field {
num: 46,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.right_pedal_smoothness),
is_expanded: false,
});
};
if m.combined_pedal_smoothness != u8::MAX {
fields.push(Field {
num: 47,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.combined_pedal_smoothness),
is_expanded: false,
});
};
if m.time128 != u8::MAX {
fields.push(Field {
num: 48,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.time128),
is_expanded: false,
});
};
if m.stroke_type.0 != u8::MAX {
fields.push(Field {
num: 49,
base_type: FitBaseType::ENUM,
value: Value::Uint8(m.stroke_type.0),
is_expanded: false,
});
};
if m.zone != u8::MAX {
fields.push(Field {
num: 50,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.zone),
is_expanded: false,
});
};
if m.ball_speed != u16::MAX {
fields.push(Field {
num: 51,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.ball_speed),
is_expanded: false,
});
};
if m.cadence256 != u16::MAX {
fields.push(Field {
num: 52,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.cadence256),
is_expanded: false,
});
};
if m.fractional_cadence != u8::MAX {
fields.push(Field {
num: 53,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.fractional_cadence),
is_expanded: false,
});
};
if m.total_hemoglobin_conc != u16::MAX {
fields.push(Field {
num: 54,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.total_hemoglobin_conc),
is_expanded: false,
});
};
if m.total_hemoglobin_conc_min != u16::MAX {
fields.push(Field {
num: 55,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.total_hemoglobin_conc_min),
is_expanded: false,
});
};
if m.total_hemoglobin_conc_max != u16::MAX {
fields.push(Field {
num: 56,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.total_hemoglobin_conc_max),
is_expanded: false,
});
};
if m.saturated_hemoglobin_percent != u16::MAX {
fields.push(Field {
num: 57,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.saturated_hemoglobin_percent),
is_expanded: false,
});
};
if m.saturated_hemoglobin_percent_min != u16::MAX {
fields.push(Field {
num: 58,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.saturated_hemoglobin_percent_min),
is_expanded: false,
});
};
if m.saturated_hemoglobin_percent_max != u16::MAX {
fields.push(Field {
num: 59,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.saturated_hemoglobin_percent_max),
is_expanded: false,
});
};
if m.device_index.0 != u8::MAX {
fields.push(Field {
num: 62,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.device_index.0),
is_expanded: false,
});
};
if m.left_pco != i8::MAX {
fields.push(Field {
num: 67,
base_type: FitBaseType::SINT8,
value: Value::Int8(m.left_pco),
is_expanded: false,
});
};
if m.right_pco != i8::MAX {
fields.push(Field {
num: 68,
base_type: FitBaseType::SINT8,
value: Value::Int8(m.right_pco),
is_expanded: false,
});
};
if !m.left_power_phase.is_empty() {
fields.push(Field {
num: 69,
base_type: FitBaseType::UINT8,
value: Value::VecUint8(m.left_power_phase),
is_expanded: false,
});
};
if !m.left_power_phase_peak.is_empty() {
fields.push(Field {
num: 70,
base_type: FitBaseType::UINT8,
value: Value::VecUint8(m.left_power_phase_peak),
is_expanded: false,
});
};
if !m.right_power_phase.is_empty() {
fields.push(Field {
num: 71,
base_type: FitBaseType::UINT8,
value: Value::VecUint8(m.right_power_phase),
is_expanded: false,
});
};
if !m.right_power_phase_peak.is_empty() {
fields.push(Field {
num: 72,
base_type: FitBaseType::UINT8,
value: Value::VecUint8(m.right_power_phase_peak),
is_expanded: false,
});
};
if m.enhanced_speed != u32::MAX {
fields.push(Field {
num: 73,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.enhanced_speed),
is_expanded: is_expanded(&m.state, 73),
});
};
if m.enhanced_altitude != u32::MAX {
fields.push(Field {
num: 78,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.enhanced_altitude),
is_expanded: is_expanded(&m.state, 78),
});
};
if m.battery_soc != u8::MAX {
fields.push(Field {
num: 81,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.battery_soc),
is_expanded: false,
});
};
if m.motor_power != u16::MAX {
fields.push(Field {
num: 82,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.motor_power),
is_expanded: false,
});
};
if m.vertical_ratio != u16::MAX {
fields.push(Field {
num: 83,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.vertical_ratio),
is_expanded: false,
});
};
if m.stance_time_balance != u16::MAX {
fields.push(Field {
num: 84,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.stance_time_balance),
is_expanded: false,
});
};
if m.step_length != u16::MAX {
fields.push(Field {
num: 85,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.step_length),
is_expanded: false,
});
};
if m.cycle_length16 != u16::MAX {
fields.push(Field {
num: 87,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.cycle_length16),
is_expanded: false,
});
};
if m.absolute_pressure != u32::MAX {
fields.push(Field {
num: 91,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.absolute_pressure),
is_expanded: false,
});
};
if m.depth != u32::MAX {
fields.push(Field {
num: 92,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.depth),
is_expanded: false,
});
};
if m.next_stop_depth != u32::MAX {
fields.push(Field {
num: 93,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.next_stop_depth),
is_expanded: false,
});
};
if m.next_stop_time != u32::MAX {
fields.push(Field {
num: 94,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.next_stop_time),
is_expanded: false,
});
};
if m.time_to_surface != u32::MAX {
fields.push(Field {
num: 95,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.time_to_surface),
is_expanded: false,
});
};
if m.ndl_time != u32::MAX {
fields.push(Field {
num: 96,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.ndl_time),
is_expanded: false,
});
};
if m.cns_load != u8::MAX {
fields.push(Field {
num: 97,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.cns_load),
is_expanded: false,
});
};
if m.n2_load != u16::MAX {
fields.push(Field {
num: 98,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.n2_load),
is_expanded: false,
});
};
if m.respiration_rate != u8::MAX {
fields.push(Field {
num: 99,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.respiration_rate),
is_expanded: false,
});
};
if m.enhanced_respiration_rate != u16::MAX {
fields.push(Field {
num: 108,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.enhanced_respiration_rate),
is_expanded: is_expanded(&m.state, 108),
});
};
if m.grit.to_bits() != u32::MAX {
fields.push(Field {
num: 114,
base_type: FitBaseType::FLOAT32,
value: Value::Float32(m.grit),
is_expanded: false,
});
};
if m.flow.to_bits() != u32::MAX {
fields.push(Field {
num: 115,
base_type: FitBaseType::FLOAT32,
value: Value::Float32(m.flow),
is_expanded: false,
});
};
if m.current_stress != u16::MAX {
fields.push(Field {
num: 116,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.current_stress),
is_expanded: false,
});
};
if m.ebike_travel_range != u16::MAX {
fields.push(Field {
num: 117,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.ebike_travel_range),
is_expanded: false,
});
};
if m.ebike_battery_level != u8::MAX {
fields.push(Field {
num: 118,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.ebike_battery_level),
is_expanded: false,
});
};
if m.ebike_assist_mode != u8::MAX {
fields.push(Field {
num: 119,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.ebike_assist_mode),
is_expanded: false,
});
};
if m.ebike_assist_level_percent != u8::MAX {
fields.push(Field {
num: 120,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.ebike_assist_level_percent),
is_expanded: false,
});
};
if m.air_time_remaining != u32::MAX {
fields.push(Field {
num: 123,
base_type: FitBaseType::UINT32,
value: Value::Uint32(m.air_time_remaining),
is_expanded: false,
});
};
if m.pressure_sac != u16::MAX {
fields.push(Field {
num: 124,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.pressure_sac),
is_expanded: false,
});
};
if m.volume_sac != u16::MAX {
fields.push(Field {
num: 125,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.volume_sac),
is_expanded: false,
});
};
if m.rmv != u16::MAX {
fields.push(Field {
num: 126,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.rmv),
is_expanded: false,
});
};
if m.ascent_rate != i32::MAX {
fields.push(Field {
num: 127,
base_type: FitBaseType::SINT32,
value: Value::Int32(m.ascent_rate),
is_expanded: false,
});
};
if m.po2 != u8::MAX {
fields.push(Field {
num: 129,
base_type: FitBaseType::UINT8,
value: Value::Uint8(m.po2),
is_expanded: false,
});
};
if m.core_temperature != u16::MAX {
fields.push(Field {
num: 139,
base_type: FitBaseType::UINT16,
value: Value::Uint16(m.core_temperature),
is_expanded: false,
});
};
fields.extend_from_slice(&m.unknown_fields);
Self {
header: 0,
num: typedef::MesgNum::RECORD,
fields,
developer_fields: m.developer_fields,
}
}
}
#[cfg(feature = "serde")]
impl Serialize for Record {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let n = self.count_valid_fields() + 2;
let mut state = serializer.serialize_struct("Record", n)?;
if let Some(v) = self.timestamp.unix_timestamp() {
state.serialize_field("timestamp", &v)?;
}
if let Some(v) = self.position_lat_degrees() {
state.serialize_field("position_lat", &v)?;
}
if let Some(v) = self.position_long_degrees() {
state.serialize_field("position_long", &v)?;
}
if let Some(v) = self.altitude_scaled() {
state.serialize_field("altitude", &v)?;
}
if self.heart_rate != u8::MAX {
state.serialize_field("heart_rate", &self.heart_rate)?;
}
if self.cadence != u8::MAX {
state.serialize_field("cadence", &self.cadence)?;
}
if let Some(v) = self.distance_scaled() {
state.serialize_field("distance", &v)?;
}
if let Some(v) = self.speed_scaled() {
state.serialize_field("speed", &v)?;
}
if self.power != u16::MAX {
state.serialize_field("power", &self.power)?;
}
if self.compressed_speed_distance != [u8::MAX; 3] {
state.serialize_field("compressed_speed_distance", &self.compressed_speed_distance)?;
}
if let Some(v) = self.grade_scaled() {
state.serialize_field("grade", &v)?;
}
if self.resistance != u8::MAX {
state.serialize_field("resistance", &self.resistance)?;
}
if let Some(v) = self.time_from_course_scaled() {
state.serialize_field("time_from_course", &v)?;
}
if let Some(v) = self.cycle_length_scaled() {
state.serialize_field("cycle_length", &v)?;
}
if self.temperature != i8::MAX {
state.serialize_field("temperature", &self.temperature)?;
}
if let Some(v) = self.speed_1s_scaled() {
state.serialize_field("speed_1s", &v)?;
}
if self.cycles != u8::MAX {
state.serialize_field("cycles", &self.cycles)?;
}
if self.total_cycles != u32::MAX {
state.serialize_field("total_cycles", &self.total_cycles)?;
}
if self.compressed_accumulated_power != u16::MAX {
state.serialize_field(
"compressed_accumulated_power",
&self.compressed_accumulated_power,
)?;
}
if self.accumulated_power != u32::MAX {
state.serialize_field("accumulated_power", &self.accumulated_power)?;
}
if self.left_right_balance.0 != u8::MAX {
state.serialize_field("left_right_balance", &self.left_right_balance)?;
}
if self.gps_accuracy != u8::MAX {
state.serialize_field("gps_accuracy", &self.gps_accuracy)?;
}
if let Some(v) = self.vertical_speed_scaled() {
state.serialize_field("vertical_speed", &v)?;
}
if self.calories != u16::MAX {
state.serialize_field("calories", &self.calories)?;
}
if let Some(v) = self.vertical_oscillation_scaled() {
state.serialize_field("vertical_oscillation", &v)?;
}
if let Some(v) = self.stance_time_percent_scaled() {
state.serialize_field("stance_time_percent", &v)?;
}
if let Some(v) = self.stance_time_scaled() {
state.serialize_field("stance_time", &v)?;
}
if self.activity_type.0 != u8::MAX {
state.serialize_field("activity_type", &self.activity_type)?;
}
if let Some(v) = self.left_torque_effectiveness_scaled() {
state.serialize_field("left_torque_effectiveness", &v)?;
}
if let Some(v) = self.right_torque_effectiveness_scaled() {
state.serialize_field("right_torque_effectiveness", &v)?;
}
if let Some(v) = self.left_pedal_smoothness_scaled() {
state.serialize_field("left_pedal_smoothness", &v)?;
}
if let Some(v) = self.right_pedal_smoothness_scaled() {
state.serialize_field("right_pedal_smoothness", &v)?;
}
if let Some(v) = self.combined_pedal_smoothness_scaled() {
state.serialize_field("combined_pedal_smoothness", &v)?;
}
if let Some(v) = self.time128_scaled() {
state.serialize_field("time128", &v)?;
}
if self.stroke_type.0 != u8::MAX {
state.serialize_field("stroke_type", &self.stroke_type)?;
}
if self.zone != u8::MAX {
state.serialize_field("zone", &self.zone)?;
}
if let Some(v) = self.ball_speed_scaled() {
state.serialize_field("ball_speed", &v)?;
}
if let Some(v) = self.cadence256_scaled() {
state.serialize_field("cadence256", &v)?;
}
if let Some(v) = self.fractional_cadence_scaled() {
state.serialize_field("fractional_cadence", &v)?;
}
if let Some(v) = self.total_hemoglobin_conc_scaled() {
state.serialize_field("total_hemoglobin_conc", &v)?;
}
if let Some(v) = self.total_hemoglobin_conc_min_scaled() {
state.serialize_field("total_hemoglobin_conc_min", &v)?;
}
if let Some(v) = self.total_hemoglobin_conc_max_scaled() {
state.serialize_field("total_hemoglobin_conc_max", &v)?;
}
if let Some(v) = self.saturated_hemoglobin_percent_scaled() {
state.serialize_field("saturated_hemoglobin_percent", &v)?;
}
if let Some(v) = self.saturated_hemoglobin_percent_min_scaled() {
state.serialize_field("saturated_hemoglobin_percent_min", &v)?;
}
if let Some(v) = self.saturated_hemoglobin_percent_max_scaled() {
state.serialize_field("saturated_hemoglobin_percent_max", &v)?;
}
if self.device_index.0 != u8::MAX {
state.serialize_field("device_index", &self.device_index)?;
}
if self.left_pco != i8::MAX {
state.serialize_field("left_pco", &self.left_pco)?;
}
if self.right_pco != i8::MAX {
state.serialize_field("right_pco", &self.right_pco)?;
}
if let Some(v) = self.left_power_phase_scaled() {
state.serialize_field("left_power_phase", &v)?;
}
if let Some(v) = self.left_power_phase_peak_scaled() {
state.serialize_field("left_power_phase_peak", &v)?;
}
if let Some(v) = self.right_power_phase_scaled() {
state.serialize_field("right_power_phase", &v)?;
}
if let Some(v) = self.right_power_phase_peak_scaled() {
state.serialize_field("right_power_phase_peak", &v)?;
}
if let Some(v) = self.enhanced_speed_scaled() {
state.serialize_field("enhanced_speed", &v)?;
}
if let Some(v) = self.enhanced_altitude_scaled() {
state.serialize_field("enhanced_altitude", &v)?;
}
if let Some(v) = self.battery_soc_scaled() {
state.serialize_field("battery_soc", &v)?;
}
if self.motor_power != u16::MAX {
state.serialize_field("motor_power", &self.motor_power)?;
}
if let Some(v) = self.vertical_ratio_scaled() {
state.serialize_field("vertical_ratio", &v)?;
}
if let Some(v) = self.stance_time_balance_scaled() {
state.serialize_field("stance_time_balance", &v)?;
}
if let Some(v) = self.step_length_scaled() {
state.serialize_field("step_length", &v)?;
}
if let Some(v) = self.cycle_length16_scaled() {
state.serialize_field("cycle_length16", &v)?;
}
if self.absolute_pressure != u32::MAX {
state.serialize_field("absolute_pressure", &self.absolute_pressure)?;
}
if let Some(v) = self.depth_scaled() {
state.serialize_field("depth", &v)?;
}
if let Some(v) = self.next_stop_depth_scaled() {
state.serialize_field("next_stop_depth", &v)?;
}
if self.next_stop_time != u32::MAX {
state.serialize_field("next_stop_time", &self.next_stop_time)?;
}
if self.time_to_surface != u32::MAX {
state.serialize_field("time_to_surface", &self.time_to_surface)?;
}
if self.ndl_time != u32::MAX {
state.serialize_field("ndl_time", &self.ndl_time)?;
}
if self.cns_load != u8::MAX {
state.serialize_field("cns_load", &self.cns_load)?;
}
if self.n2_load != u16::MAX {
state.serialize_field("n2_load", &self.n2_load)?;
}
if self.respiration_rate != u8::MAX {
state.serialize_field("respiration_rate", &self.respiration_rate)?;
}
if let Some(v) = self.enhanced_respiration_rate_scaled() {
state.serialize_field("enhanced_respiration_rate", &v)?;
}
if self.grit.to_bits() != u32::MAX {
state.serialize_field("grit", &self.grit)?;
}
if self.flow.to_bits() != u32::MAX {
state.serialize_field("flow", &self.flow)?;
}
if let Some(v) = self.current_stress_scaled() {
state.serialize_field("current_stress", &v)?;
}
if self.ebike_travel_range != u16::MAX {
state.serialize_field("ebike_travel_range", &self.ebike_travel_range)?;
}
if self.ebike_battery_level != u8::MAX {
state.serialize_field("ebike_battery_level", &self.ebike_battery_level)?;
}
if self.ebike_assist_mode != u8::MAX {
state.serialize_field("ebike_assist_mode", &self.ebike_assist_mode)?;
}
if self.ebike_assist_level_percent != u8::MAX {
state.serialize_field(
"ebike_assist_level_percent",
&self.ebike_assist_level_percent,
)?;
}
if self.air_time_remaining != u32::MAX {
state.serialize_field("air_time_remaining", &self.air_time_remaining)?;
}
if let Some(v) = self.pressure_sac_scaled() {
state.serialize_field("pressure_sac", &v)?;
}
if let Some(v) = self.volume_sac_scaled() {
state.serialize_field("volume_sac", &v)?;
}
if let Some(v) = self.rmv_scaled() {
state.serialize_field("rmv", &v)?;
}
if let Some(v) = self.ascent_rate_scaled() {
state.serialize_field("ascent_rate", &v)?;
}
if let Some(v) = self.po2_scaled() {
state.serialize_field("po2", &v)?;
}
if let Some(v) = self.core_temperature_scaled() {
state.serialize_field("core_temperature", &v)?;
}
if !self.unknown_fields.is_empty() {
state.serialize_field("unknown_fields", &self.unknown_fields)?;
}
if !self.developer_fields.is_empty() {
state.serialize_field("developer_fields", &self.developer_fields)?;
}
state.end()
}
}
#[cfg(feature = "serde")]
#[cfg_attr(feature = "serde", derive(Deserialize), serde(default))]
struct De {
timestamp: Option<i64>,
position_lat: f64,
position_long: f64,
altitude: f64,
heart_rate: u8,
cadence: u8,
distance: f64,
speed: f64,
power: u16,
compressed_speed_distance: [u8; 3],
grade: f64,
resistance: u8,
time_from_course: f64,
cycle_length: f64,
temperature: i8,
speed_1s: Vec<f64>,
cycles: u8,
total_cycles: u32,
compressed_accumulated_power: u16,
accumulated_power: u32,
left_right_balance: typedef::LeftRightBalance,
gps_accuracy: u8,
vertical_speed: f64,
calories: u16,
vertical_oscillation: f64,
stance_time_percent: f64,
stance_time: f64,
activity_type: typedef::ActivityType,
left_torque_effectiveness: f64,
right_torque_effectiveness: f64,
left_pedal_smoothness: f64,
right_pedal_smoothness: f64,
combined_pedal_smoothness: f64,
time128: f64,
stroke_type: typedef::StrokeType,
zone: u8,
ball_speed: f64,
cadence256: f64,
fractional_cadence: f64,
total_hemoglobin_conc: f64,
total_hemoglobin_conc_min: f64,
total_hemoglobin_conc_max: f64,
saturated_hemoglobin_percent: f64,
saturated_hemoglobin_percent_min: f64,
saturated_hemoglobin_percent_max: f64,
device_index: typedef::DeviceIndex,
left_pco: i8,
right_pco: i8,
left_power_phase: Vec<f64>,
left_power_phase_peak: Vec<f64>,
right_power_phase: Vec<f64>,
right_power_phase_peak: Vec<f64>,
enhanced_speed: f64,
enhanced_altitude: f64,
battery_soc: f64,
motor_power: u16,
vertical_ratio: f64,
stance_time_balance: f64,
step_length: f64,
cycle_length16: f64,
absolute_pressure: u32,
depth: f64,
next_stop_depth: f64,
next_stop_time: u32,
time_to_surface: u32,
ndl_time: u32,
cns_load: u8,
n2_load: u16,
respiration_rate: u8,
enhanced_respiration_rate: f64,
grit: f32,
flow: f32,
current_stress: f64,
ebike_travel_range: u16,
ebike_battery_level: u8,
ebike_assist_mode: u8,
ebike_assist_level_percent: u8,
air_time_remaining: u32,
pressure_sac: f64,
volume_sac: f64,
rmv: f64,
ascent_rate: f64,
po2: f64,
core_temperature: f64,
unknown_fields: Vec<Field>,
developer_fields: Vec<DeveloperField>,
}
#[cfg(feature = "serde")]
impl From<De> for Record {
fn from(m: De) -> Self {
Self {
timestamp: m.timestamp.map_or_else(
|| typedef::DateTime(u32::MAX),
typedef::DateTime::from_unix_timestamp,
),
position_lat: semconv::to_semicircles(m.position_lat).unwrap_or(i32::MAX),
position_long: semconv::to_semicircles(m.position_long).unwrap_or(i32::MAX),
altitude: {
let unscaled = (m.altitude + 500.0) * 5.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
heart_rate: m.heart_rate,
cadence: m.cadence,
distance: {
let unscaled = (m.distance + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
u32::MAX
} else {
unscaled as u32
}
},
speed: {
let unscaled = (m.speed + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
power: m.power,
compressed_speed_distance: m.compressed_speed_distance,
grade: {
let unscaled = (m.grade + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i16::MAX as f64 {
i16::MAX
} else {
unscaled as i16
}
},
resistance: m.resistance,
time_from_course: {
let unscaled = (m.time_from_course + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i32::MAX as f64 {
i32::MAX
} else {
unscaled as i32
}
},
cycle_length: {
let unscaled = (m.cycle_length + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
temperature: m.temperature,
speed_1s: {
if m.speed_1s.is_empty() {
Vec::new()
} else {
let mut vals = Vec::with_capacity(m.speed_1s.len());
for &x in m.speed_1s.iter() {
let unscaled = (x + 0.0) * 16.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64
{
vals.push(u8::MAX);
continue;
}
vals.push(unscaled as u8);
}
vals
}
},
cycles: m.cycles,
total_cycles: m.total_cycles,
compressed_accumulated_power: m.compressed_accumulated_power,
accumulated_power: m.accumulated_power,
left_right_balance: m.left_right_balance,
gps_accuracy: m.gps_accuracy,
vertical_speed: {
let unscaled = (m.vertical_speed + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i16::MAX as f64 {
i16::MAX
} else {
unscaled as i16
}
},
calories: m.calories,
vertical_oscillation: {
let unscaled = (m.vertical_oscillation + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
stance_time_percent: {
let unscaled = (m.stance_time_percent + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
stance_time: {
let unscaled = (m.stance_time + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
activity_type: m.activity_type,
left_torque_effectiveness: {
let unscaled = (m.left_torque_effectiveness + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
right_torque_effectiveness: {
let unscaled = (m.right_torque_effectiveness + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
left_pedal_smoothness: {
let unscaled = (m.left_pedal_smoothness + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
right_pedal_smoothness: {
let unscaled = (m.right_pedal_smoothness + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
combined_pedal_smoothness: {
let unscaled = (m.combined_pedal_smoothness + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
time128: {
let unscaled = (m.time128 + 0.0) * 128.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
stroke_type: m.stroke_type,
zone: m.zone,
ball_speed: {
let unscaled = (m.ball_speed + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
cadence256: {
let unscaled = (m.cadence256 + 0.0) * 256.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
fractional_cadence: {
let unscaled = (m.fractional_cadence + 0.0) * 128.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
total_hemoglobin_conc: {
let unscaled = (m.total_hemoglobin_conc + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
total_hemoglobin_conc_min: {
let unscaled = (m.total_hemoglobin_conc_min + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
total_hemoglobin_conc_max: {
let unscaled = (m.total_hemoglobin_conc_max + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
saturated_hemoglobin_percent: {
let unscaled = (m.saturated_hemoglobin_percent + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
saturated_hemoglobin_percent_min: {
let unscaled = (m.saturated_hemoglobin_percent_min + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
saturated_hemoglobin_percent_max: {
let unscaled = (m.saturated_hemoglobin_percent_max + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
device_index: m.device_index,
left_pco: m.left_pco,
right_pco: m.right_pco,
left_power_phase: {
if m.left_power_phase.is_empty() {
Vec::new()
} else {
let mut vals = Vec::with_capacity(m.left_power_phase.len());
for &x in m.left_power_phase.iter() {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64
{
vals.push(u8::MAX);
continue;
}
vals.push(unscaled as u8);
}
vals
}
},
left_power_phase_peak: {
if m.left_power_phase_peak.is_empty() {
Vec::new()
} else {
let mut vals = Vec::with_capacity(m.left_power_phase_peak.len());
for &x in m.left_power_phase_peak.iter() {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64
{
vals.push(u8::MAX);
continue;
}
vals.push(unscaled as u8);
}
vals
}
},
right_power_phase: {
if m.right_power_phase.is_empty() {
Vec::new()
} else {
let mut vals = Vec::with_capacity(m.right_power_phase.len());
for &x in m.right_power_phase.iter() {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64
{
vals.push(u8::MAX);
continue;
}
vals.push(unscaled as u8);
}
vals
}
},
right_power_phase_peak: {
if m.right_power_phase_peak.is_empty() {
Vec::new()
} else {
let mut vals = Vec::with_capacity(m.right_power_phase_peak.len());
for &x in m.right_power_phase_peak.iter() {
let unscaled = (x + 0.0) * 0.7111111;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64
{
vals.push(u8::MAX);
continue;
}
vals.push(unscaled as u8);
}
vals
}
},
enhanced_speed: {
let unscaled = (m.enhanced_speed + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
u32::MAX
} else {
unscaled as u32
}
},
enhanced_altitude: {
let unscaled = (m.enhanced_altitude + 500.0) * 5.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
u32::MAX
} else {
unscaled as u32
}
},
battery_soc: {
let unscaled = (m.battery_soc + 0.0) * 2.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
motor_power: m.motor_power,
vertical_ratio: {
let unscaled = (m.vertical_ratio + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
stance_time_balance: {
let unscaled = (m.stance_time_balance + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
step_length: {
let unscaled = (m.step_length + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
cycle_length16: {
let unscaled = (m.cycle_length16 + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
absolute_pressure: m.absolute_pressure,
depth: {
let unscaled = (m.depth + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
u32::MAX
} else {
unscaled as u32
}
},
next_stop_depth: {
let unscaled = (m.next_stop_depth + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u32::MAX as f64 {
u32::MAX
} else {
unscaled as u32
}
},
next_stop_time: m.next_stop_time,
time_to_surface: m.time_to_surface,
ndl_time: m.ndl_time,
cns_load: m.cns_load,
n2_load: m.n2_load,
respiration_rate: m.respiration_rate,
enhanced_respiration_rate: {
let unscaled = (m.enhanced_respiration_rate + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
grit: m.grit,
flow: m.flow,
current_stress: {
let unscaled = (m.current_stress + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
ebike_travel_range: m.ebike_travel_range,
ebike_battery_level: m.ebike_battery_level,
ebike_assist_mode: m.ebike_assist_mode,
ebike_assist_level_percent: m.ebike_assist_level_percent,
air_time_remaining: m.air_time_remaining,
pressure_sac: {
let unscaled = (m.pressure_sac + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
volume_sac: {
let unscaled = (m.volume_sac + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
rmv: {
let unscaled = (m.rmv + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
ascent_rate: {
let unscaled = (m.ascent_rate + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > i32::MAX as f64 {
i32::MAX
} else {
unscaled as i32
}
},
po2: {
let unscaled = (m.po2 + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
u8::MAX
} else {
unscaled as u8
}
},
core_temperature: {
let unscaled = (m.core_temperature + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
u16::MAX
} else {
unscaled as u16
}
},
state: [0u8; 14],
unknown_fields: m.unknown_fields,
developer_fields: m.developer_fields,
}
}
}
#[cfg(feature = "serde")]
impl Default for De {
fn default() -> Self {
Self {
timestamp: None,
position_lat: f64::from_bits(u64::MAX),
position_long: f64::from_bits(u64::MAX),
altitude: f64::from_bits(u64::MAX),
heart_rate: u8::MAX,
cadence: u8::MAX,
distance: f64::from_bits(u64::MAX),
speed: f64::from_bits(u64::MAX),
power: u16::MAX,
compressed_speed_distance: [u8::MAX; 3],
grade: f64::from_bits(u64::MAX),
resistance: u8::MAX,
time_from_course: f64::from_bits(u64::MAX),
cycle_length: f64::from_bits(u64::MAX),
temperature: i8::MAX,
speed_1s: Vec::new(),
cycles: u8::MAX,
total_cycles: u32::MAX,
compressed_accumulated_power: u16::MAX,
accumulated_power: u32::MAX,
left_right_balance: typedef::LeftRightBalance(u8::MAX),
gps_accuracy: u8::MAX,
vertical_speed: f64::from_bits(u64::MAX),
calories: u16::MAX,
vertical_oscillation: f64::from_bits(u64::MAX),
stance_time_percent: f64::from_bits(u64::MAX),
stance_time: f64::from_bits(u64::MAX),
activity_type: typedef::ActivityType(u8::MAX),
left_torque_effectiveness: f64::from_bits(u64::MAX),
right_torque_effectiveness: f64::from_bits(u64::MAX),
left_pedal_smoothness: f64::from_bits(u64::MAX),
right_pedal_smoothness: f64::from_bits(u64::MAX),
combined_pedal_smoothness: f64::from_bits(u64::MAX),
time128: f64::from_bits(u64::MAX),
stroke_type: typedef::StrokeType(u8::MAX),
zone: u8::MAX,
ball_speed: f64::from_bits(u64::MAX),
cadence256: f64::from_bits(u64::MAX),
fractional_cadence: f64::from_bits(u64::MAX),
total_hemoglobin_conc: f64::from_bits(u64::MAX),
total_hemoglobin_conc_min: f64::from_bits(u64::MAX),
total_hemoglobin_conc_max: f64::from_bits(u64::MAX),
saturated_hemoglobin_percent: f64::from_bits(u64::MAX),
saturated_hemoglobin_percent_min: f64::from_bits(u64::MAX),
saturated_hemoglobin_percent_max: f64::from_bits(u64::MAX),
device_index: typedef::DeviceIndex(u8::MAX),
left_pco: i8::MAX,
right_pco: i8::MAX,
left_power_phase: Vec::new(),
left_power_phase_peak: Vec::new(),
right_power_phase: Vec::new(),
right_power_phase_peak: Vec::new(),
enhanced_speed: f64::from_bits(u64::MAX),
enhanced_altitude: f64::from_bits(u64::MAX),
battery_soc: f64::from_bits(u64::MAX),
motor_power: u16::MAX,
vertical_ratio: f64::from_bits(u64::MAX),
stance_time_balance: f64::from_bits(u64::MAX),
step_length: f64::from_bits(u64::MAX),
cycle_length16: f64::from_bits(u64::MAX),
absolute_pressure: u32::MAX,
depth: f64::from_bits(u64::MAX),
next_stop_depth: f64::from_bits(u64::MAX),
next_stop_time: u32::MAX,
time_to_surface: u32::MAX,
ndl_time: u32::MAX,
cns_load: u8::MAX,
n2_load: u16::MAX,
respiration_rate: u8::MAX,
enhanced_respiration_rate: f64::from_bits(u64::MAX),
grit: f32::from_bits(u32::MAX),
flow: f32::from_bits(u32::MAX),
current_stress: f64::from_bits(u64::MAX),
ebike_travel_range: u16::MAX,
ebike_battery_level: u8::MAX,
ebike_assist_mode: u8::MAX,
ebike_assist_level_percent: u8::MAX,
air_time_remaining: u32::MAX,
pressure_sac: f64::from_bits(u64::MAX),
volume_sac: f64::from_bits(u64::MAX),
rmv: f64::from_bits(u64::MAX),
ascent_rate: f64::from_bits(u64::MAX),
po2: f64::from_bits(u64::MAX),
core_temperature: f64::from_bits(u64::MAX),
unknown_fields: Vec::new(),
developer_fields: Vec::new(),
}
}
}