From 642c4cb2c7be68f0a1467ed989d39dd26fe45974 Mon Sep 17 00:00:00 2001 From: naskya Date: Thu, 6 Jun 2024 17:10:39 +0900 Subject: [PATCH] refactor (backend-rs): remove strum derives --- Cargo.lock | 31 +----- Cargo.toml | 1 - packages/backend-rs/Cargo.toml | 1 - packages/backend-rs/index.d.ts | 14 +-- packages/backend-rs/src/database/cache.rs | 16 +-- .../src/service/push_notification.rs | 56 ++++++----- packages/backend-rs/src/service/stream.rs | 98 ++++++++++--------- .../backend-rs/src/service/stream/antenna.rs | 2 +- .../backend-rs/src/service/stream/channel.rs | 2 +- .../backend-rs/src/service/stream/chat.rs | 14 +-- .../src/service/stream/chat_index.rs | 10 +- .../src/service/stream/custom_emoji.rs | 2 +- .../src/service/stream/group_chat.rs | 9 +- .../src/service/stream/moderation.rs | 2 +- 14 files changed, 124 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index add1b1c0dc..4eefdd76b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,7 +226,6 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "strum 0.26.2", "sysinfo", "thiserror", "tokio", @@ -2644,12 +2643,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - [[package]] name = "ryu" version = "1.0.18" @@ -2712,7 +2705,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "strum 0.25.0", + "strum", "thiserror", "time", "tracing", @@ -3240,28 +3233,6 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -[[package]] -name = "strum" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.66", -] - [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index a75cfc0190..ce4f502ba5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ sea-orm = { version = "0.12.15", default-features = false } serde = { version = "1.0.203", default-features = false } serde_json = { version = "1.0.117", default-features = false } serde_yaml = { version = "0.9.34", default-features = false } -strum = { version = "0.26.2", default-features = false } syn = { version = "2.0.66", default-features = false } sysinfo = { version = "0.30.12", default-features = false } thiserror = { version = "1.0.61", default-features = false } diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index d4942cd61c..a9bcb3777f 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -39,7 +39,6 @@ sea-orm = { workspace = true, features = ["macros", "runtime-tokio-rustls", "sql serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } serde_yaml = { workspace = true } -strum = { workspace = true, features = ["derive"] } sysinfo = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["fs", "io-std", "io-util", "macros", "process", "rt-multi-thread", "signal", "sync", "time"] } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index f9cb459f27..ace0f4fb52 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1365,13 +1365,13 @@ export function updateAntennasOnNewNote(note: Note, noteAuthor: Acct, noteMutedU export function watchNote(watcherId: string, noteAuthorId: string, noteId: string): Promise export function unwatchNote(watcherId: string, noteId: string): Promise export enum PushNotificationKind { - Generic = 'generic', - Chat = 'chat', - ReadAllChats = 'readAllChats', - ReadAllChatsInTheRoom = 'readAllChatsInTheRoom', - ReadNotifications = 'readNotifications', - ReadAllNotifications = 'readAllNotifications', - Mastodon = 'mastodon' + Generic = 0, + Chat = 1, + ReadAllChats = 2, + ReadAllChatsInTheRoom = 3, + ReadNotifications = 4, + ReadAllNotifications = 5, + Mastodon = 6 } export function sendPushNotification(receiverUserId: string, kind: PushNotificationKind, content: any): Promise export function publishToChannelStream(channelId: string, userId: string): Promise diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index a5dd62a75e..c49806afdf 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -4,16 +4,12 @@ use crate::database::{redis_conn, redis_key, RedisConnError}; use redis::{AsyncCommands, RedisError}; use serde::{Deserialize, Serialize}; -#[derive(strum::Display, Debug)] +#[cfg_attr(test, derive(Debug))] pub enum Category { - #[strum(serialize = "fetchUrl")] FetchUrl, - #[strum(serialize = "blocking")] Block, - #[strum(serialize = "following")] Follow, #[cfg(test)] - #[strum(serialize = "usedOnlyForTesting")] Test, } @@ -32,9 +28,15 @@ fn prefix_key(key: &str) -> String { redis_key(format!("cache:{}", key)) } -#[inline] fn categorize(category: Category, key: &str) -> String { - format!("{}:{}", category, key) + let prefix = match category { + Category::FetchUrl => "fetchUrl", + Category::Block => "blocking", + Category::Follow => "following", + #[cfg(test)] + Category::Test => "usedOnlyForTesting", + }; + format!("{}:{}", prefix, key) } #[inline] diff --git a/packages/backend-rs/src/service/push_notification.rs b/packages/backend-rs/src/service/push_notification.rs index 9d19aceab1..b417630194 100644 --- a/packages/backend-rs/src/service/push_notification.rs +++ b/packages/backend-rs/src/service/push_notification.rs @@ -32,32 +32,18 @@ fn get_client() -> Result { .cloned()?) } -#[derive(strum::Display, PartialEq)] -#[crate::export(string_enum = "camelCase")] +#[crate::export] pub enum PushNotificationKind { - #[strum(serialize = "notification")] Generic, - #[strum(serialize = "unreadMessagingMessage")] Chat, - #[strum(serialize = "readAllMessagingMessages")] ReadAllChats, - #[strum(serialize = "readAllMessagingMessagesOfARoom")] ReadAllChatsInTheRoom, - #[strum(serialize = "readNotifications")] ReadNotifications, - #[strum(serialize = "readAllNotifications")] ReadAllNotifications, Mastodon, } -fn compact_content( - kind: &PushNotificationKind, - mut content: serde_json::Value, -) -> Result { - if kind != &PushNotificationKind::Generic { - return Ok(content); - } - +fn compact_content(mut content: serde_json::Value) -> Result { if !content.is_object() { return Err(Error::InvalidContent("not a JSON object".to_string())); } @@ -159,24 +145,40 @@ pub async fn send_push_notification( .all(db) .await?; + let use_mastodon_api = matches!(kind, PushNotificationKind::Mastodon); + // TODO: refactoring - let payload = if kind == PushNotificationKind::Mastodon { + let payload = if use_mastodon_api { // Leave the `content` as it is serde_json::to_string(content)? } else { // Format the `content` passed from the TypeScript backend // for Firefish push notifications + let label = match kind { + PushNotificationKind::Generic => "notification", + PushNotificationKind::Chat => "unreadMessagingMessage", + PushNotificationKind::ReadAllChats => "readAllMessagingMessages", + PushNotificationKind::ReadAllChatsInTheRoom => "readAllMessagingMessagesOfARoom", + PushNotificationKind::ReadNotifications => "readNotifications", + PushNotificationKind::ReadAllNotifications => "readAllNotifications", + // unreachable + _ => "unknown", + }; format!( "{{\"type\":\"{}\",\"userId\":\"{}\",\"dateTime\":{},\"body\":{}}}", - kind, + label, receiver_user_id, chrono::Utc::now().timestamp_millis(), - serde_json::to_string(&compact_content(&kind, content.clone())?)? + match kind { + PushNotificationKind::Generic => + serde_json::to_string(&compact_content(content.to_owned())?)?, + _ => serde_json::to_string(&content)?, + } ) }; tracing::trace!("payload: {}", payload); - let encoding = if kind == PushNotificationKind::Mastodon { + let encoding = if use_mastodon_api { ContentEncoding::AesGcm } else { ContentEncoding::Aes128Gcm @@ -184,13 +186,13 @@ pub async fn send_push_notification( for subscription in subscriptions.iter() { if !subscription.send_read_message - && [ - PushNotificationKind::ReadAllChats, - PushNotificationKind::ReadAllChatsInTheRoom, - PushNotificationKind::ReadAllNotifications, - PushNotificationKind::ReadNotifications, - ] - .contains(&kind) + && matches!( + kind, + PushNotificationKind::ReadAllChats + | PushNotificationKind::ReadAllChatsInTheRoom + | PushNotificationKind::ReadAllNotifications + | PushNotificationKind::ReadNotifications + ) { continue; } diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index b87ded9261..47cff7de1f 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -10,39 +10,44 @@ use crate::config::CONFIG; use crate::database::{redis_conn, RedisConnError}; use redis::{AsyncCommands, RedisError}; -#[derive(strum::Display)] pub enum Stream { - #[strum(serialize = "internal")] Internal, - #[strum(serialize = "broadcast")] CustomEmoji, - #[strum(to_string = "adminStream:{moderator_id}")] - Moderation { moderator_id: String }, - #[strum(to_string = "user:{user_id}")] - User { user_id: String }, - #[strum(to_string = "channelStream:{channel_id}")] - Channel { channel_id: String }, - #[strum(to_string = "noteStream:{note_id}")] - Note { note_id: String }, - #[strum(serialize = "notesStream")] + Moderation { + moderator_id: String, + }, + User { + user_id: String, + }, + Channel { + channel_id: String, + }, + Note { + note_id: String, + }, Notes, - #[strum(to_string = "userListStream:{list_id}")] - UserList { list_id: String }, - #[strum(to_string = "mainStream:{user_id}")] - Main { user_id: String }, - #[strum(to_string = "driveStream:{user_id}")] - Drive { user_id: String }, - #[strum(to_string = "antennaStream:{antenna_id}")] - Antenna { antenna_id: String }, - #[strum(to_string = "messagingStream:{sender_user_id}-{receiver_user_id}")] + UserList { + list_id: String, + }, + Main { + user_id: String, + }, + Drive { + user_id: String, + }, + Antenna { + antenna_id: String, + }, Chat { sender_user_id: String, receiver_user_id: String, }, - #[strum(to_string = "messagingStream:{group_id}")] - GroupChat { group_id: String }, - #[strum(to_string = "messagingIndexStream:{user_id}")] - ChatIndex { user_id: String }, + GroupChat { + group_id: String, + }, + ChatIndex { + user_id: String, + }, } #[derive(thiserror::Error, Debug)] @@ -59,9 +64,29 @@ pub enum Error { pub async fn publish_to_stream( stream: &Stream, - kind: Option, + kind: Option<&str>, value: Option, ) -> Result<(), Error> { + let channel = match stream { + Stream::Internal => "internal".to_string(), + Stream::CustomEmoji => "broadcast".to_string(), + Stream::Moderation { moderator_id } => format!("adminStream:{moderator_id}"), + Stream::User { user_id } => format!("user:{user_id}"), + Stream::Channel { channel_id } => format!("channelStream:{channel_id}"), + Stream::Note { note_id } => format!("noteStream:{note_id}"), + Stream::Notes => "notesStream".to_string(), + Stream::UserList { list_id } => format!("userListStream:{list_id}"), + Stream::Main { user_id } => format!("mainStream:{user_id}"), + Stream::Drive { user_id } => format!("driveStream:{user_id}"), + Stream::Antenna { antenna_id } => format!("antennaStream:{antenna_id}"), + Stream::Chat { + sender_user_id, + receiver_user_id, + } => format!("messagingStream:{sender_user_id}-{receiver_user_id}"), + Stream::GroupChat { group_id } => format!("messagingStream:{group_id}"), + Stream::ChatIndex { user_id } => format!("messagingIndexStream:{user_id}"), + }; + let message = if let Some(kind) = kind { format!( "{{\"type\":\"{}\",\"body\":{}}}", @@ -76,28 +101,9 @@ pub async fn publish_to_stream( .await? .publish( &CONFIG.host, - format!("{{\"channel\":\"{}\",\"message\":{}}}", stream, message), + format!("{{\"channel\":\"{}\",\"message\":{}}}", channel, message), ) .await?; Ok(()) } - -#[cfg(test)] -mod unit_test { - use super::Stream; - use pretty_assertions::assert_eq; - - #[test] - fn channel_to_string() { - assert_eq!(Stream::Internal.to_string(), "internal"); - assert_eq!(Stream::CustomEmoji.to_string(), "broadcast"); - assert_eq!( - Stream::Moderation { - moderator_id: "9tb42br63g5apjcq".to_string() - } - .to_string(), - "adminStream:9tb42br63g5apjcq" - ); - } -} diff --git a/packages/backend-rs/src/service/stream/antenna.rs b/packages/backend-rs/src/service/stream/antenna.rs index 3058d9f04c..7210719c93 100644 --- a/packages/backend-rs/src/service/stream/antenna.rs +++ b/packages/backend-rs/src/service/stream/antenna.rs @@ -4,7 +4,7 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; pub async fn publish(antenna_id: String, note: ¬e::Model) -> Result<(), Error> { publish_to_stream( &Stream::Antenna { antenna_id }, - Some("note".to_string()), + Some("note"), Some(serde_json::to_string(note)?), ) .await diff --git a/packages/backend-rs/src/service/stream/channel.rs b/packages/backend-rs/src/service/stream/channel.rs index 9f5cf3802a..028aab69c7 100644 --- a/packages/backend-rs/src/service/stream/channel.rs +++ b/packages/backend-rs/src/service/stream/channel.rs @@ -4,7 +4,7 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; pub async fn publish(channel_id: String, user_id: String) -> Result<(), Error> { publish_to_stream( &Stream::Channel { channel_id }, - Some("typing".to_string()), + Some("typing"), Some(format!("\"{}\"", user_id)), ) .await diff --git a/packages/backend-rs/src/service/stream/chat.rs b/packages/backend-rs/src/service/stream/chat.rs index 84280c319c..62701d3976 100644 --- a/packages/backend-rs/src/service/stream/chat.rs +++ b/packages/backend-rs/src/service/stream/chat.rs @@ -1,15 +1,10 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; -#[derive(strum::Display)] #[crate::export(string_enum = "camelCase")] pub enum ChatEvent { - #[strum(serialize = "message")] Message, - #[strum(serialize = "read")] Read, - #[strum(serialize = "deleted")] Deleted, - #[strum(serialize = "typing")] Typing, } @@ -23,12 +18,19 @@ pub async fn publish( kind: ChatEvent, object: &serde_json::Value, ) -> Result<(), Error> { + let kind = match kind { + ChatEvent::Message => "message", + ChatEvent::Read => "read", + ChatEvent::Deleted => "deleted", + ChatEvent::Typing => "typing", + }; + publish_to_stream( &Stream::Chat { sender_user_id, receiver_user_id, }, - Some(kind.to_string()), + Some(kind), Some(serde_json::to_string(object)?), ) .await diff --git a/packages/backend-rs/src/service/stream/chat_index.rs b/packages/backend-rs/src/service/stream/chat_index.rs index 6619c5589c..790dd905ea 100644 --- a/packages/backend-rs/src/service/stream/chat_index.rs +++ b/packages/backend-rs/src/service/stream/chat_index.rs @@ -1,11 +1,8 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; -#[derive(strum::Display)] #[crate::export(string_enum = "camelCase")] pub enum ChatIndexEvent { - #[strum(serialize = "message")] Message, - #[strum(serialize = "read")] Read, } @@ -18,9 +15,14 @@ pub async fn publish( kind: ChatIndexEvent, object: &serde_json::Value, ) -> Result<(), Error> { + let kind = match kind { + ChatIndexEvent::Message => "message", + ChatIndexEvent::Read => "read", + }; + publish_to_stream( &Stream::ChatIndex { user_id }, - Some(kind.to_string()), + Some(kind), Some(serde_json::to_string(object)?), ) .await diff --git a/packages/backend-rs/src/service/stream/custom_emoji.rs b/packages/backend-rs/src/service/stream/custom_emoji.rs index 29b655b6e6..164d89b957 100644 --- a/packages/backend-rs/src/service/stream/custom_emoji.rs +++ b/packages/backend-rs/src/service/stream/custom_emoji.rs @@ -21,7 +21,7 @@ pub struct PackedEmoji { pub async fn publish(emoji: &PackedEmoji) -> Result<(), Error> { publish_to_stream( &Stream::CustomEmoji, - Some("emojiAdded".to_string()), + Some("emojiAdded"), Some(format!("{{\"emoji\":{}}}", serde_json::to_string(emoji)?)), ) .await diff --git a/packages/backend-rs/src/service/stream/group_chat.rs b/packages/backend-rs/src/service/stream/group_chat.rs index 20c04c6fa2..6cf3c5f671 100644 --- a/packages/backend-rs/src/service/stream/group_chat.rs +++ b/packages/backend-rs/src/service/stream/group_chat.rs @@ -9,9 +9,16 @@ pub async fn publish( kind: ChatEvent, object: &serde_json::Value, ) -> Result<(), Error> { + let kind = match kind { + ChatEvent::Message => "message", + ChatEvent::Read => "read", + ChatEvent::Deleted => "deleted", + ChatEvent::Typing => "typing", + }; + publish_to_stream( &Stream::GroupChat { group_id }, - Some(kind.to_string()), + Some(kind), Some(serde_json::to_string(object)?), ) .await diff --git a/packages/backend-rs/src/service/stream/moderation.rs b/packages/backend-rs/src/service/stream/moderation.rs index e9e17d2399..218441e15f 100644 --- a/packages/backend-rs/src/service/stream/moderation.rs +++ b/packages/backend-rs/src/service/stream/moderation.rs @@ -15,7 +15,7 @@ pub struct AbuseUserReportLike { pub async fn publish(moderator_id: String, report: &AbuseUserReportLike) -> Result<(), Error> { publish_to_stream( &Stream::Moderation { moderator_id }, - Some("newAbuseUserReport".to_string()), + Some("newAbuseUserReport"), Some(serde_json::to_string(report)?), ) .await