use std::ops::{Deref, DerefMut};
use compact_str::CompactString;
use serde::Deserialize;
use time::{Date, OffsetDateTime};
use crate::model::VideoGame;
#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize)]
pub struct Player {
#[serde(flatten)]
pub inner: CompactPlayer,
#[serde(rename = "current_videogame")]
pub current_video_game: Option<VideoGame>,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize)]
pub struct CompactPlayer {
pub active: bool,
pub age: Option<u8>,
#[serde(with = "birthday_format", default)]
pub birthday: Option<Date>,
pub first_name: Option<CompactString>,
pub id: u64,
pub image_url: Option<String>,
pub last_name: Option<CompactString>,
#[serde(with = "time::serde::iso8601")]
pub modified_at: OffsetDateTime,
pub name: String,
pub nationality: Option<CompactString>,
pub role: Option<CompactString>,
pub slug: Option<CompactString>,
}
mod birthday_format {
use serde::Deserialize;
use time::{format_description::BorrowedFormatItem, Date};
const FORMAT: &[BorrowedFormatItem<'static>] =
time::macros::format_description!("[year]-[month]-[day]");
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Date>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: Option<&'de str> = Deserialize::deserialize(deserializer)?;
s.map(|s| Date::parse(s, FORMAT).map_err(serde::de::Error::custom))
.transpose()
}
}
impl Deref for Player {
type Target = CompactPlayer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for Player {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl AsRef<CompactPlayer> for Player {
fn as_ref(&self) -> &CompactPlayer {
&self.inner
}
}
impl AsMut<CompactPlayer> for Player {
fn as_mut(&mut self) -> &mut CompactPlayer {
&mut self.inner
}
}
impl From<Player> for CompactPlayer {
fn from(player: Player) -> Self {
player.inner
}
}