use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TaskLabel {
SendMessage,
MarkRead,
MarkUnread,
UnsendMessage,
ReactMessage,
SearchMessage,
PinMessage,
TypingIndicator,
CreateGroup,
SendGroupBootstrap,
ChangeThreadApproval,
ChangeThreadMessageShare,
ChangeReadReceipts,
AddParticipants,
RemoveParticipant,
SetThreadAdmin,
ChangeThreadImage,
ChangeThreadName,
ChangeThreadTheme,
ChangeThreadEmoji,
ChangeNickname,
MuteThreadMessages,
MuteThreadCalls,
RestrictUser,
RemovePinnedThreadOnRestrict,
AcceptFriendRequest,
ThreadRangeQuery,
ContactQuery,
IntegrityCheck,
SearchContacts,
PullMailbox,
ProjectSync,
Unknown(String),
}
impl TaskLabel {
pub fn parse(code: &str) -> Self {
match code {
"46" => Self::SendMessage,
"21" => Self::MarkRead,
"49" => Self::MarkUnread,
"33" => Self::UnsendMessage,
"29" => Self::ReactMessage,
"107" => Self::SearchMessage,
"751" => Self::PinMessage,
"3" => Self::TypingIndicator,
"153" => Self::CreateGroup,
"130" => Self::SendGroupBootstrap,
"28" => Self::ChangeThreadApproval,
"210002" => Self::ChangeThreadMessageShare,
"60003" => Self::ChangeReadReceipts,
"23" => Self::AddParticipants,
"140" => Self::RemoveParticipant,
"25" => Self::SetThreadAdmin,
"37" => Self::ChangeThreadImage,
"32" => Self::ChangeThreadName,
"43" => Self::ChangeThreadTheme,
"100003" => Self::ChangeThreadEmoji,
"44" => Self::ChangeNickname,
"144" => Self::MuteThreadMessages,
"229" => Self::MuteThreadCalls,
"367" => Self::RestrictUser,
"810" => Self::RemovePinnedThreadOnRestrict,
"207" => Self::AcceptFriendRequest,
"145" => Self::ThreadRangeQuery,
"701" => Self::IntegrityCheck,
"452" => Self::SearchContacts,
"17" => Self::PullMailbox,
"351" => Self::ProjectSync,
unknown => Self::Unknown(unknown.to_string()),
}
}
pub fn code(&self) -> &str {
match self {
Self::SendMessage => "46",
Self::MarkRead => "21",
Self::MarkUnread => "49",
Self::UnsendMessage => "33",
Self::ReactMessage => "29",
Self::SearchMessage => "107",
Self::PinMessage => "751",
Self::TypingIndicator => "3",
Self::CreateGroup => "153",
Self::SendGroupBootstrap => "130",
Self::ChangeThreadApproval => "28",
Self::ChangeThreadMessageShare => "210002",
Self::ChangeReadReceipts => "60003",
Self::AddParticipants => "23",
Self::RemoveParticipant => "140",
Self::SetThreadAdmin => "25",
Self::ChangeThreadImage => "37",
Self::ChangeThreadName => "32",
Self::ChangeThreadTheme => "43",
Self::ChangeThreadEmoji => "100003",
Self::ChangeNickname => "44",
Self::MuteThreadMessages => "144",
Self::MuteThreadCalls => "229",
Self::RestrictUser => "367",
Self::RemovePinnedThreadOnRestrict => "810",
Self::AcceptFriendRequest => "207",
Self::ThreadRangeQuery => "145",
Self::ContactQuery => "207",
Self::IntegrityCheck => "701",
Self::SearchContacts => "452",
Self::PullMailbox => "17",
Self::ProjectSync => "351",
Self::Unknown(code) => code,
}
}
pub fn name(&self) -> &'static str {
match self {
Self::SendMessage => "send_message",
Self::MarkRead => "mark_read",
Self::MarkUnread => "mark_unread",
Self::UnsendMessage => "unsend_message",
Self::ReactMessage => "react_message",
Self::SearchMessage => "search_message",
Self::PinMessage => "pin_message",
Self::TypingIndicator => "typing_indicator",
Self::CreateGroup => "create_group",
Self::SendGroupBootstrap => "send_group_bootstrap",
Self::ChangeThreadApproval => "change_thread_approval",
Self::ChangeThreadMessageShare => "change_thread_message_share",
Self::ChangeReadReceipts => "change_read_receipts",
Self::AddParticipants => "add_participants",
Self::RemoveParticipant => "remove_participant",
Self::SetThreadAdmin => "set_thread_admin",
Self::ChangeThreadImage => "change_thread_image",
Self::ChangeThreadName => "change_thread_name",
Self::ChangeThreadTheme => "change_thread_theme",
Self::ChangeThreadEmoji => "change_thread_emoji",
Self::ChangeNickname => "change_nickname",
Self::MuteThreadMessages => "mute_thread_messages",
Self::MuteThreadCalls => "mute_thread_calls",
Self::RestrictUser => "restrict_user",
Self::RemovePinnedThreadOnRestrict => "remove_pinned_thread_on_restrict",
Self::AcceptFriendRequest => "accept_friend_request",
Self::ThreadRangeQuery => "thread_range_query",
Self::ContactQuery => "contact_query",
Self::IntegrityCheck => "integrity_check",
Self::SearchContacts => "search_contacts",
Self::PullMailbox => "pull_mailbox",
Self::ProjectSync => "project_sync",
Self::Unknown(_) => "unknown",
}
}
}
#[derive(Debug, Clone)]
pub struct Task {
pub label: TaskLabel,
pub label_code: String,
pub payload: Value,
pub queue_name: String,
pub task_id: Option<u64>,
pub failure_count: Option<u64>,
pub raw: Value,
}
impl Task {
pub fn new(label: TaskLabel, payload: Value, queue_name: String, task_id: u64) -> Self {
let label_code = label.code().to_string();
Self {
label,
label_code,
payload,
queue_name,
task_id: Some(task_id),
failure_count: None,
raw: Value::Null,
}
}
pub fn parse(raw: &Value) -> Option<Self> {
let label_code = raw.get("label")?.as_str()?.to_string();
let payload = decode_task_payload(raw.get("payload"));
let queue_name = raw
.get("queue_name")
.and_then(Value::as_str)
.map(ToString::to_string)
.unwrap_or_default();
let task_id = raw.get("task_id").and_then(|value| {
value
.as_u64()
.or_else(|| value.as_str()?.parse::<u64>().ok())
});
let failure_count = raw.get("failure_count").and_then(|value| {
value
.as_u64()
.or_else(|| value.as_str()?.parse::<u64>().ok())
});
Some(Self {
label: TaskLabel::parse(&label_code),
label_code,
payload,
queue_name,
task_id,
failure_count,
raw: raw.clone(),
})
}
pub fn encode_value(&self) -> Value {
let payload = if self.payload.is_string() {
self.payload.clone()
} else {
Value::String(self.payload.to_string())
};
serde_json::json!({
"failure_count": self.failure_count,
"label": self.label_code,
"payload": payload,
"queue_name": self.queue_name,
"task_id": self.task_id,
})
}
}
fn decode_task_payload(value: Option<&Value>) -> Value {
match value {
Some(Value::String(text)) => {
serde_json::from_str::<Value>(text).unwrap_or_else(|_| Value::String(text.clone()))
}
Some(other) => other.clone(),
None => Value::Null,
}
}