use std::num::NonZeroU64;
use derive_getters::{Dissolve, Getters};
use serde::Deserialize;
#[cfg(feature = "serde")]
use serde::Serialize;
use super::{
Empty,
course::{Role, SelfUserCourse},
realm::{Realm, RealmID},
};
#[derive(Clone, Debug, Deserialize, Getters, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct SelfUser {
courses: Vec<SelfUserCourse>,
push_key: String,
realms: Vec<Realm>,
time: String,
user: User,
}
impl SelfUser {
pub async fn get(client: &crate::Client) -> crate::Result<Self> {
client.get_self_user().await
}
}
#[derive(Copy, Clone, Debug, Deserialize, Hash, PartialEq, Eq, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct UserID(u64);
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum ThreadListStyle {
#[serde(rename = "full")]
Full,
#[serde(rename = "compact")]
Compact,
#[serde(rename = "ultra-compact")]
UltraCompact,
Other(String),
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Dissolve)]
pub struct DigestInterval(Option<NonZeroU64>);
impl<'de> Deserialize<'de> for DigestInterval {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let got = Option::<u64>::deserialize(deserializer)?;
Ok(Self(got.map(NonZeroU64::new).flatten()))
}
}
#[cfg(feature = "serde")]
impl Serialize for DigestInterval {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.map(|o| o.get()).unwrap_or(0).serialize(serializer)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum Theme {
#[serde(rename = "os")]
OS,
#[serde(rename = "light")]
Light,
#[serde(rename = "dark")]
Dark,
Other(String),
}
#[derive(Clone, Debug, Deserialize, Getters, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DesktopNotificationScopes {
announcement: bool,
thread: bool,
direct_reply: bool,
mention: bool,
chat: bool,
watch: bool,
}
#[derive(Clone, Debug, Deserialize, Getters, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct UserSettings {
digest_interval: DigestInterval,
discuss_feed_style: ThreadListStyle,
accessible: bool,
locale: String,
theme: Theme,
character_key_shortcuts_disabled: bool,
set_tz_automatically: bool,
tz: String,
reply_via_email: bool,
email_announcements: bool,
email_watched_threads: bool,
email_thread_replies: bool,
email_comment_replies: bool,
email_mentions: bool,
mention_direct_message_digest_interval: String,
channel_digest_interval: String,
allow_password_login: bool,
desktop_notifications_enabled: bool,
desktop_notifications_scopes: DesktopNotificationScopes,
snooze_end: String,
deactivated: bool,
}
#[derive(Clone, Debug, Deserialize, Getters, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct User {
id: UserID,
role: String,
name: String,
email: String,
username: Option<String>,
avatar: Option<String>,
features: Empty,
settings: UserSettings,
activated: bool,
created_at: String,
course_role: Option<Role>,
secondary_emails: Vec<String>,
has_password: bool,
is_lti: bool,
is_sso: bool,
can_change_name: bool,
has_pats: bool,
realm_id: Option<RealmID>,
}
#[derive(Clone, Debug, Deserialize, Getters, Dissolve)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ThreadParticipant {
id: UserID,
role: String,
name: String,
avatar: Option<String>,
course_role: Option<Role>,
}
impl Into<ThreadParticipant> for User {
fn into(self) -> ThreadParticipant {
ThreadParticipant {
id: self.id,
role: String::from("user"),
name: self.name,
avatar: self.avatar,
course_role: self.course_role,
}
}
}