use core::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer, de, ser::SerializeStruct};
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Activity(pub u8);
impl Activity {
pub const MANUAL: Activity = Activity(0);
pub const AUTO_MULTI_SPORT: Activity = Activity(1);
fn as_str(self) -> Option<&'static str> {
match self.0 {
0 => Some("manual"),
1 => Some("auto_multi_sport"),
_ => None,
}
}
}
impl Default for Activity {
fn default() -> Self {
Self(u8::MAX)
}
}
impl fmt::Display for Activity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.as_str() {
Some(s) => write!(f, "{}", s),
None => write!(f, "Activity({})", self.0),
}
}
}
#[cfg(feature = "serde")]
impl Serialize for Activity {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Activity", 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 Activity {
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)
}
}