use chrono::{DateTime, Utc};
use serde::Deserialize;
use super::common::{Activity, Platform, UserStatus};
#[derive(Debug, Clone, Deserialize)]
pub struct User {
pub id: String,
#[serde(rename = "ingameName")]
pub ingame_name: String,
#[serde(default)]
pub avatar: Option<String>,
#[serde(default)]
pub reputation: i32,
#[serde(default)]
pub locale: Option<String>,
pub platform: Platform,
#[serde(default)]
pub crossplay: bool,
#[serde(rename = "status", default)]
pub status: UserStatus,
#[serde(default)]
pub activity: Option<Activity>,
#[serde(rename = "lastSeen", default)]
pub last_seen: Option<DateTime<Utc>>,
}
impl User {
pub fn is_available(&self) -> bool {
self.status.is_available()
}
pub fn avatar_url(&self) -> Option<&str> {
self.avatar.as_deref()
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct FullUser {
pub id: String,
#[serde(rename = "ingameName")]
pub ingame_name: String,
#[serde(default)]
pub slug: Option<String>,
#[serde(default)]
pub avatar: Option<String>,
#[serde(default)]
pub background: Option<String>,
#[serde(default)]
pub about: Option<String>,
#[serde(default)]
pub reputation: i32,
#[serde(rename = "masteryLevel", default)]
pub mastery_level: Option<u32>,
pub platform: Platform,
#[serde(default)]
pub crossplay: bool,
#[serde(default)]
pub locale: Option<String>,
#[serde(rename = "status", default)]
pub status: UserStatus,
#[serde(default)]
pub activity: Option<Activity>,
#[serde(rename = "lastSeen", default)]
pub last_seen: Option<DateTime<Utc>>,
#[serde(default)]
pub banned: Option<bool>,
#[serde(rename = "banUntil", default)]
pub ban_until: Option<DateTime<Utc>>,
#[serde(rename = "banMessage", default)]
pub ban_message: Option<String>,
#[serde(default)]
pub warned: Option<bool>,
#[serde(rename = "warnMessage", default)]
pub warn_message: Option<String>,
#[serde(default)]
pub email: Option<String>,
#[serde(rename = "emailVerified", default)]
pub email_verified: Option<bool>,
#[serde(rename = "ingameVerified", default)]
pub ingame_verified: Option<bool>,
}
impl FullUser {
pub fn is_available(&self) -> bool {
self.status.is_available()
}
pub fn is_banned(&self) -> bool {
self.banned.unwrap_or(false)
}
pub fn has_warning(&self) -> bool {
self.warned.unwrap_or(false)
}
pub fn to_user(&self) -> User {
User {
id: self.id.clone(),
ingame_name: self.ingame_name.clone(),
avatar: self.avatar.clone(),
reputation: self.reputation,
locale: self.locale.clone(),
platform: self.platform,
crossplay: self.crossplay,
status: self.status,
activity: self.activity.clone(),
last_seen: self.last_seen,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct UserProfile {
pub id: String,
#[serde(rename = "ingameName")]
pub ingame_name: String,
pub slug: String,
#[serde(default)]
pub avatar: Option<String>,
#[serde(default)]
pub background: Option<String>,
#[serde(default)]
pub about: Option<String>,
#[serde(default)]
pub reputation: i32,
#[serde(rename = "masteryLevel", default)]
pub mastery_level: Option<u32>,
pub platform: Platform,
#[serde(default)]
pub crossplay: bool,
#[serde(default)]
pub locale: Option<String>,
#[serde(rename = "status", default)]
pub status: UserStatus,
#[serde(default)]
pub activity: Option<Activity>,
#[serde(rename = "lastSeen", default)]
pub last_seen: Option<DateTime<Utc>>,
#[serde(rename = "achievementShowcase", default)]
pub achievement_showcase: Vec<Achievement>,
#[serde(default)]
pub banned: Option<bool>,
#[serde(rename = "banUntil", default)]
pub ban_until: Option<DateTime<Utc>>,
#[serde(rename = "banMessage", default)]
pub ban_message: Option<String>,
#[serde(default)]
pub warned: Option<bool>,
#[serde(rename = "warnMessage", default)]
pub warn_message: Option<String>,
}
impl UserProfile {
pub fn is_available(&self) -> bool {
self.status.is_available()
}
pub fn is_banned(&self) -> bool {
self.banned.unwrap_or(false)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct Achievement {
pub id: String,
pub icon: String,
#[serde(default)]
pub thumb: Option<String>,
#[serde(rename = "type")]
pub achievement_type: AchievementType,
#[serde(default)]
pub i18n: Option<AchievementTranslation>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum AchievementType {
Patreon,
Github,
Custom,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AchievementTranslation {
pub name: String,
pub description: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_is_available() {
let user = User {
id: "test".to_string(),
ingame_name: "TestUser".to_string(),
avatar: None,
reputation: 0,
locale: None,
platform: Platform::Pc,
crossplay: true,
status: UserStatus::Online,
activity: None,
last_seen: None,
};
assert!(user.is_available());
}
#[test]
fn test_user_offline_not_available() {
let user = User {
id: "test".to_string(),
ingame_name: "TestUser".to_string(),
avatar: None,
reputation: 0,
locale: None,
platform: Platform::Pc,
crossplay: true,
status: UserStatus::Offline,
activity: None,
last_seen: None,
};
assert!(!user.is_available());
}
}