use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use toolkit_macros::domain_model;
use uuid::Uuid;
#[domain_model]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ReactionType {
Like,
Dislike,
None,
}
impl ReactionType {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Like => "like",
Self::Dislike => "dislike",
Self::None => "none",
}
}
#[must_use]
pub fn from_str_value(s: &str) -> Option<Self> {
match s {
"like" => Some(Self::Like),
"dislike" => Some(Self::Dislike),
"none" => Some(Self::None),
_ => None,
}
}
#[must_use]
pub fn is_persisted(&self) -> bool {
!matches!(self, Self::None)
}
}
#[domain_model]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MessageReaction {
pub message_id: Uuid,
pub user_id: String,
pub reaction_type: ReactionType,
#[serde(with = "time::serde::rfc3339")]
pub created_at: OffsetDateTime,
#[serde(with = "time::serde::rfc3339")]
pub updated_at: OffsetDateTime,
}
#[domain_model]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageReactionEvent {
pub event: &'static str,
pub session_id: Uuid,
pub message_id: Uuid,
pub user_id: String,
pub reaction_type: ReactionType,
pub previous_reaction_type: Option<ReactionType>,
#[serde(with = "time::serde::rfc3339")]
pub timestamp: OffsetDateTime,
}
impl MessageReactionEvent {
pub const EVENT_KIND: &'static str = "message.reaction";
#[must_use]
pub fn new(
session_id: Uuid,
message_id: Uuid,
user_id: String,
reaction_type: ReactionType,
previous_reaction_type: Option<ReactionType>,
) -> Self {
Self {
event: Self::EVENT_KIND,
session_id,
message_id,
user_id,
reaction_type,
previous_reaction_type,
timestamp: OffsetDateTime::now_utc(),
}
}
}
#[cfg(test)]
#[path = "reaction_tests.rs"]
mod reaction_tests;