use core::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer, de, ser::SerializeStruct};
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct File(pub u8);
impl File {
pub const DEVICE: File = File(1);
pub const SETTINGS: File = File(2);
pub const SPORT: File = File(3);
pub const ACTIVITY: File = File(4);
pub const WORKOUT: File = File(5);
pub const COURSE: File = File(6);
pub const SCHEDULES: File = File(7);
pub const WEIGHT: File = File(9);
pub const TOTALS: File = File(10);
pub const GOALS: File = File(11);
pub const BLOOD_PRESSURE: File = File(14);
pub const MONITORING_A: File = File(15);
pub const ACTIVITY_SUMMARY: File = File(20);
pub const MONITORING_DAILY: File = File(28);
pub const MONITORING_B: File = File(32);
pub const SEGMENT: File = File(34);
pub const SEGMENT_LIST: File = File(35);
pub const EXD_CONFIGURATION: File = File(40);
pub const MFG_RANGE_MIN: File = File(0xF7);
pub const MFG_RANGE_MAX: File = File(0xFE);
fn as_str(self) -> Option<&'static str> {
match self.0 {
1 => Some("device"),
2 => Some("settings"),
3 => Some("sport"),
4 => Some("activity"),
5 => Some("workout"),
6 => Some("course"),
7 => Some("schedules"),
9 => Some("weight"),
10 => Some("totals"),
11 => Some("goals"),
14 => Some("blood_pressure"),
15 => Some("monitoring_a"),
20 => Some("activity_summary"),
28 => Some("monitoring_daily"),
32 => Some("monitoring_b"),
34 => Some("segment"),
35 => Some("segment_list"),
40 => Some("exd_configuration"),
0xF7 => Some("mfg_range_min"),
0xFE => Some("mfg_range_max"),
_ => None,
}
}
}
impl Default for File {
fn default() -> Self {
Self(u8::MAX)
}
}
impl fmt::Display for File {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.as_str() {
Some(s) => write!(f, "{}", s),
None => write!(f, "File({})", self.0),
}
}
}
#[cfg(feature = "serde")]
impl Serialize for File {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("File", 2)?;
if let Some(s) = self.as_str() {
state.serialize_field("t", s)?;
}
state.serialize_field("c", &self.0)?;
state.end()
}
}
#[cfg(feature = "serde")]
#[cfg_attr(feature = "serde", derive(Deserialize))]
struct De<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
t: Option<&'a str>,
c: u8,
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for File {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let repr = De::deserialize(deserializer)?;
let v = Self(repr.c);
if let Some(t) = repr.t
&& let Some(s) = v.as_str()
&& t != s
{
return Err(de::Error::custom("tag and content mismatch"));
}
Ok(v)
}
}