#![allow(unused, clippy::comparison_to_empty, clippy::manual_range_patterns)]
use crate::profile::{ProfileType, typedef};
use crate::proto::*;
#[derive(Debug, Clone)]
pub struct UserProfile {
pub message_index: typedef::MessageIndex,
pub friendly_name: String,
pub gender: typedef::Gender,
pub age: u8,
pub height: u8,
pub weight: u16,
pub language: typedef::Language,
pub elev_setting: typedef::DisplayMeasure,
pub weight_setting: typedef::DisplayMeasure,
pub resting_heart_rate: u8,
pub default_max_running_heart_rate: u8,
pub default_max_biking_heart_rate: u8,
pub default_max_heart_rate: u8,
pub hr_setting: typedef::DisplayHeart,
pub speed_setting: typedef::DisplayMeasure,
pub dist_setting: typedef::DisplayMeasure,
pub power_setting: typedef::DisplayPower,
pub activity_class: typedef::ActivityClass,
pub position_setting: typedef::DisplayPosition,
pub temperature_setting: typedef::DisplayMeasure,
pub local_id: typedef::UserLocalId,
pub global_id: [u8; 6],
pub wake_time: typedef::LocaltimeIntoDay,
pub sleep_time: typedef::LocaltimeIntoDay,
pub height_setting: typedef::DisplayMeasure,
pub user_running_step_length: u16,
pub user_walking_step_length: u16,
pub depth_setting: typedef::DisplayMeasure,
pub dive_count: u32,
pub unknown_fields: Vec<Field>,
pub developer_fields: Vec<DeveloperField>,
}
impl UserProfile {
pub const MESSAGE_INDEX: u8 = 254;
pub const FRIENDLY_NAME: u8 = 0;
pub const GENDER: u8 = 1;
pub const AGE: u8 = 2;
pub const HEIGHT: u8 = 3;
pub const WEIGHT: u8 = 4;
pub const LANGUAGE: u8 = 5;
pub const ELEV_SETTING: u8 = 6;
pub const WEIGHT_SETTING: u8 = 7;
pub const RESTING_HEART_RATE: u8 = 8;
pub const DEFAULT_MAX_RUNNING_HEART_RATE: u8 = 9;
pub const DEFAULT_MAX_BIKING_HEART_RATE: u8 = 10;
pub const DEFAULT_MAX_HEART_RATE: u8 = 11;
pub const HR_SETTING: u8 = 12;
pub const SPEED_SETTING: u8 = 13;
pub const DIST_SETTING: u8 = 14;
pub const POWER_SETTING: u8 = 16;
pub const ACTIVITY_CLASS: u8 = 17;
pub const POSITION_SETTING: u8 = 18;
pub const TEMPERATURE_SETTING: u8 = 21;
pub const LOCAL_ID: u8 = 22;
pub const GLOBAL_ID: u8 = 23;
pub const WAKE_TIME: u8 = 28;
pub const SLEEP_TIME: u8 = 29;
pub const HEIGHT_SETTING: u8 = 30;
pub const USER_RUNNING_STEP_LENGTH: u8 = 31;
pub const USER_WALKING_STEP_LENGTH: u8 = 32;
pub const DEPTH_SETTING: u8 = 47;
pub const DIVE_COUNT: u8 = 49;
pub const fn new() -> Self {
Self {
message_index: typedef::MessageIndex(u16::MAX),
friendly_name: String::new(),
gender: typedef::Gender(u8::MAX),
age: u8::MAX,
height: u8::MAX,
weight: u16::MAX,
language: typedef::Language(u8::MAX),
elev_setting: typedef::DisplayMeasure(u8::MAX),
weight_setting: typedef::DisplayMeasure(u8::MAX),
resting_heart_rate: u8::MAX,
default_max_running_heart_rate: u8::MAX,
default_max_biking_heart_rate: u8::MAX,
default_max_heart_rate: u8::MAX,
hr_setting: typedef::DisplayHeart(u8::MAX),
speed_setting: typedef::DisplayMeasure(u8::MAX),
dist_setting: typedef::DisplayMeasure(u8::MAX),
power_setting: typedef::DisplayPower(u8::MAX),
activity_class: typedef::ActivityClass(u8::MAX),
position_setting: typedef::DisplayPosition(u8::MAX),
temperature_setting: typedef::DisplayMeasure(u8::MAX),
local_id: typedef::UserLocalId(u16::MAX),
global_id: [u8::MAX; 6],
wake_time: typedef::LocaltimeIntoDay(u32::MAX),
sleep_time: typedef::LocaltimeIntoDay(u32::MAX),
height_setting: typedef::DisplayMeasure(u8::MAX),
user_running_step_length: u16::MAX,
user_walking_step_length: u16::MAX,
depth_setting: typedef::DisplayMeasure(u8::MAX),
dive_count: u32::MAX,
unknown_fields: Vec::new(),
developer_fields: Vec::new(),
}
}
pub fn height_scaled(&self) -> f64 {
if self.height == u8::MAX {
return f64::from_bits(u64::MAX);
}
self.height as f64 / 100.0 - 0.0
}
pub fn set_height_scaled(&mut self, v: f64) -> &mut UserProfile {
let unscaled = (v + 0.0) * 100.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u8::MAX as f64 {
self.height = u8::MAX;
return self;
}
self.height = unscaled as u8;
self
}
pub fn weight_scaled(&self) -> f64 {
if self.weight == u16::MAX {
return f64::from_bits(u64::MAX);
}
self.weight as f64 / 10.0 - 0.0
}
pub fn set_weight_scaled(&mut self, v: f64) -> &mut UserProfile {
let unscaled = (v + 0.0) * 10.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.weight = u16::MAX;
return self;
}
self.weight = unscaled as u16;
self
}
pub fn user_running_step_length_scaled(&self) -> f64 {
if self.user_running_step_length == u16::MAX {
return f64::from_bits(u64::MAX);
}
self.user_running_step_length as f64 / 1000.0 - 0.0
}
pub fn set_user_running_step_length_scaled(&mut self, v: f64) -> &mut UserProfile {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.user_running_step_length = u16::MAX;
return self;
}
self.user_running_step_length = unscaled as u16;
self
}
pub fn user_walking_step_length_scaled(&self) -> f64 {
if self.user_walking_step_length == u16::MAX {
return f64::from_bits(u64::MAX);
}
self.user_walking_step_length as f64 / 1000.0 - 0.0
}
pub fn set_user_walking_step_length_scaled(&mut self, v: f64) -> &mut UserProfile {
let unscaled = (v + 0.0) * 1000.0;
if unscaled.is_nan() || unscaled.is_infinite() || unscaled > u16::MAX as f64 {
self.user_walking_step_length = u16::MAX;
return self;
}
self.user_walking_step_length = unscaled as u16;
self
}
}
impl Default for UserProfile {
fn default() -> Self {
Self::new()
}
}
impl From<&Message> for UserProfile {
fn from(mesg: &Message) -> Self {
let mut vals: [&Value; 255] = [const { &Value::Invalid }; 255];
const KNOWN_NUMS: [u64; 4] = [703695778447359, 0, 0, 4611686018427387904];
let mut n = 0u64;
for field in &mesg.fields {
n += (KNOWN_NUMS[field.num as usize >> 6] >> (field.num & 63)) & 1 ^ 1
}
let mut unknown_fields: Vec<Field> = Vec::with_capacity(n as usize);
for field in &mesg.fields {
if (KNOWN_NUMS[field.num as usize >> 6] >> (field.num & 63)) & 1 == 0 {
unknown_fields.push(field.clone());
continue;
}
vals[field.num as usize] = &field.value;
}
Self {
message_index: typedef::MessageIndex(vals[254].as_u16()),
friendly_name: vals[0].as_string(),
gender: typedef::Gender(vals[1].as_u8()),
age: vals[2].as_u8(),
height: vals[3].as_u8(),
weight: vals[4].as_u16(),
language: typedef::Language(vals[5].as_u8()),
elev_setting: typedef::DisplayMeasure(vals[6].as_u8()),
weight_setting: typedef::DisplayMeasure(vals[7].as_u8()),
resting_heart_rate: vals[8].as_u8(),
default_max_running_heart_rate: vals[9].as_u8(),
default_max_biking_heart_rate: vals[10].as_u8(),
default_max_heart_rate: vals[11].as_u8(),
hr_setting: typedef::DisplayHeart(vals[12].as_u8()),
speed_setting: typedef::DisplayMeasure(vals[13].as_u8()),
dist_setting: typedef::DisplayMeasure(vals[14].as_u8()),
power_setting: typedef::DisplayPower(vals[16].as_u8()),
activity_class: typedef::ActivityClass(vals[17].as_u8()),
position_setting: typedef::DisplayPosition(vals[18].as_u8()),
temperature_setting: typedef::DisplayMeasure(vals[21].as_u8()),
local_id: typedef::UserLocalId(vals[22].as_u16()),
global_id: match &vals[23] {
Value::VecUint8(v) => {
let mut arr: [u8; 6] = [u8::MAX; 6];
for (i, x) in v.iter().enumerate() {
arr[i] = *x;
}
arr
}
_ => [u8::MAX; 6],
},
wake_time: typedef::LocaltimeIntoDay(vals[28].as_u32()),
sleep_time: typedef::LocaltimeIntoDay(vals[29].as_u32()),
height_setting: typedef::DisplayMeasure(vals[30].as_u8()),
user_running_step_length: vals[31].as_u16(),
user_walking_step_length: vals[32].as_u16(),
depth_setting: typedef::DisplayMeasure(vals[47].as_u8()),
dive_count: vals[49].as_u32(),
unknown_fields,
developer_fields: mesg.developer_fields.clone(),
}
}
}
impl From<UserProfile> for Message {
fn from(m: UserProfile) -> Self {
let mut arr = [const {
Field {
num: 0,
profile_type: ProfileType(0),
value: Value::Invalid,
is_expanded: false,
}
}; 29];
let mut len = 0usize;
if m.message_index != typedef::MessageIndex(u16::MAX) {
arr[len] = Field {
num: 254,
profile_type: ProfileType::MESSAGE_INDEX,
value: Value::Uint16(m.message_index.0),
is_expanded: false,
};
len += 1;
}
if m.friendly_name != String::new() {
arr[len] = Field {
num: 0,
profile_type: ProfileType::STRING,
value: Value::String(m.friendly_name),
is_expanded: false,
};
len += 1;
}
if m.gender != typedef::Gender(u8::MAX) {
arr[len] = Field {
num: 1,
profile_type: ProfileType::GENDER,
value: Value::Uint8(m.gender.0),
is_expanded: false,
};
len += 1;
}
if m.age != u8::MAX {
arr[len] = Field {
num: 2,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.age),
is_expanded: false,
};
len += 1;
}
if m.height != u8::MAX {
arr[len] = Field {
num: 3,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.height),
is_expanded: false,
};
len += 1;
}
if m.weight != u16::MAX {
arr[len] = Field {
num: 4,
profile_type: ProfileType::UINT16,
value: Value::Uint16(m.weight),
is_expanded: false,
};
len += 1;
}
if m.language != typedef::Language(u8::MAX) {
arr[len] = Field {
num: 5,
profile_type: ProfileType::LANGUAGE,
value: Value::Uint8(m.language.0),
is_expanded: false,
};
len += 1;
}
if m.elev_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 6,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.elev_setting.0),
is_expanded: false,
};
len += 1;
}
if m.weight_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 7,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.weight_setting.0),
is_expanded: false,
};
len += 1;
}
if m.resting_heart_rate != u8::MAX {
arr[len] = Field {
num: 8,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.resting_heart_rate),
is_expanded: false,
};
len += 1;
}
if m.default_max_running_heart_rate != u8::MAX {
arr[len] = Field {
num: 9,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.default_max_running_heart_rate),
is_expanded: false,
};
len += 1;
}
if m.default_max_biking_heart_rate != u8::MAX {
arr[len] = Field {
num: 10,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.default_max_biking_heart_rate),
is_expanded: false,
};
len += 1;
}
if m.default_max_heart_rate != u8::MAX {
arr[len] = Field {
num: 11,
profile_type: ProfileType::UINT8,
value: Value::Uint8(m.default_max_heart_rate),
is_expanded: false,
};
len += 1;
}
if m.hr_setting != typedef::DisplayHeart(u8::MAX) {
arr[len] = Field {
num: 12,
profile_type: ProfileType::DISPLAY_HEART,
value: Value::Uint8(m.hr_setting.0),
is_expanded: false,
};
len += 1;
}
if m.speed_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 13,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.speed_setting.0),
is_expanded: false,
};
len += 1;
}
if m.dist_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 14,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.dist_setting.0),
is_expanded: false,
};
len += 1;
}
if m.power_setting != typedef::DisplayPower(u8::MAX) {
arr[len] = Field {
num: 16,
profile_type: ProfileType::DISPLAY_POWER,
value: Value::Uint8(m.power_setting.0),
is_expanded: false,
};
len += 1;
}
if m.activity_class != typedef::ActivityClass(u8::MAX) {
arr[len] = Field {
num: 17,
profile_type: ProfileType::ACTIVITY_CLASS,
value: Value::Uint8(m.activity_class.0),
is_expanded: false,
};
len += 1;
}
if m.position_setting != typedef::DisplayPosition(u8::MAX) {
arr[len] = Field {
num: 18,
profile_type: ProfileType::DISPLAY_POSITION,
value: Value::Uint8(m.position_setting.0),
is_expanded: false,
};
len += 1;
}
if m.temperature_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 21,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.temperature_setting.0),
is_expanded: false,
};
len += 1;
}
if m.local_id != typedef::UserLocalId(u16::MAX) {
arr[len] = Field {
num: 22,
profile_type: ProfileType::USER_LOCAL_ID,
value: Value::Uint16(m.local_id.0),
is_expanded: false,
};
len += 1;
}
if m.global_id != [u8::MAX; 6] {
arr[len] = Field {
num: 23,
profile_type: ProfileType::BYTE,
value: Value::VecUint8(Vec::from(&m.global_id)),
is_expanded: false,
};
len += 1;
}
if m.wake_time != typedef::LocaltimeIntoDay(u32::MAX) {
arr[len] = Field {
num: 28,
profile_type: ProfileType::LOCALTIME_INTO_DAY,
value: Value::Uint32(m.wake_time.0),
is_expanded: false,
};
len += 1;
}
if m.sleep_time != typedef::LocaltimeIntoDay(u32::MAX) {
arr[len] = Field {
num: 29,
profile_type: ProfileType::LOCALTIME_INTO_DAY,
value: Value::Uint32(m.sleep_time.0),
is_expanded: false,
};
len += 1;
}
if m.height_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 30,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.height_setting.0),
is_expanded: false,
};
len += 1;
}
if m.user_running_step_length != u16::MAX {
arr[len] = Field {
num: 31,
profile_type: ProfileType::UINT16,
value: Value::Uint16(m.user_running_step_length),
is_expanded: false,
};
len += 1;
}
if m.user_walking_step_length != u16::MAX {
arr[len] = Field {
num: 32,
profile_type: ProfileType::UINT16,
value: Value::Uint16(m.user_walking_step_length),
is_expanded: false,
};
len += 1;
}
if m.depth_setting != typedef::DisplayMeasure(u8::MAX) {
arr[len] = Field {
num: 47,
profile_type: ProfileType::DISPLAY_MEASURE,
value: Value::Uint8(m.depth_setting.0),
is_expanded: false,
};
len += 1;
}
if m.dive_count != u32::MAX {
arr[len] = Field {
num: 49,
profile_type: ProfileType::UINT32,
value: Value::Uint32(m.dive_count),
is_expanded: false,
};
len += 1;
}
Message {
header: 0,
num: typedef::MesgNum::USER_PROFILE,
fields: {
let mut fields: Vec<Field> = Vec::with_capacity(len + m.unknown_fields.len());
fields.extend_from_slice(&arr[..len]);
fields.extend_from_slice(&m.unknown_fields);
fields
},
developer_fields: m.developer_fields,
}
}
}