//! Module containing all info about notifications. use super::{account::Account, status::Status}; use chrono::prelude::*; use serde::Deserialize; /// A struct containing info about a notification. #[derive(Debug, Clone, Deserialize, PartialEq)] pub struct Notification { /// The notification ID. pub id: String, /// The type of notification. #[serde(rename = "type")] pub notification_type: NotificationType, /// The time the notification was created. pub created_at: DateTime, /// The Account sending the notification to the user. pub account: Account, /// The Status associated with the notification, if applicable. pub status: Option, } /// The type of notification. #[derive(Debug, Clone, Deserialize, PartialEq)] #[serde(rename_all = "lowercase")] // Deserialize "Other" trick from https://github.com/serde-rs/serde/issues/912#issuecomment-803097289 #[serde(remote = "NotificationType")] pub enum NotificationType { /// Someone mentioned the application client in another status. Mention, /// Someone reblogged one of the application client's statuses. Reblog, /// Someone favourited one of the application client's statuses. Favourite, /// Someone followed the application client. Follow, /// Anything else #[serde(skip_deserializing)] Other(String), } use std::str::FromStr; use serde::de::{value, Deserializer, IntoDeserializer}; impl FromStr for NotificationType { type Err = value::Error; fn from_str(s: &str) -> Result { Self::deserialize(s.into_deserializer()) } } impl<'de> Deserialize<'de> for NotificationType { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { let s = String::deserialize(deserializer)?; let deserialized = Self::from_str(&s).unwrap_or_else(|_| { Self::Other(s) }); Ok(deserialized) } }