2023-04-28 18:18:32 +02:00
use crate ::errors ::ObserverError ;
use crate ::gateway ::events ::Events ;
2023-05-26 12:59:32 +02:00
use crate ::types ;
2023-05-25 23:09:18 +02:00
use futures_util ::stream ::SplitSink ;
2023-04-30 14:45:15 +02:00
use futures_util ::SinkExt ;
2023-04-28 23:21:55 +02:00
use futures_util ::StreamExt ;
2023-04-30 11:56:14 +02:00
use native_tls ::TlsConnector ;
2023-05-25 23:09:18 +02:00
use std ::sync ::Arc ;
2023-04-28 18:18:32 +02:00
use tokio ::net ::TcpStream ;
2023-05-05 18:38:04 +02:00
use tokio ::sync ::mpsc ;
2023-05-07 11:58:12 +02:00
use tokio ::sync ::mpsc ::error ::TryRecvError ;
2023-05-13 16:35:42 +02:00
use tokio ::sync ::mpsc ::Sender ;
2023-04-30 11:56:14 +02:00
use tokio ::sync ::Mutex ;
2023-04-30 14:45:15 +02:00
use tokio ::task ;
2023-05-05 18:38:04 +02:00
use tokio ::time ;
use tokio ::time ::Instant ;
2023-05-07 11:58:12 +02:00
use tokio_tungstenite ::MaybeTlsStream ;
2023-05-25 23:09:18 +02:00
use tokio_tungstenite ::{ connect_async_tls_with_config , Connector , WebSocketStream } ;
2023-05-03 21:06:01 +02:00
2023-05-11 22:47:31 +02:00
#[ derive(Debug) ]
2023-04-28 13:40:29 +02:00
/**
2023-05-11 22:47:31 +02:00
Represents a handle to a Gateway connection . A Gateway connection will create observable
2023-04-28 18:18:32 +02:00
[ ` GatewayEvents ` ] ( GatewayEvent ) , which you can subscribe to . Gateway events include all currently
implemented [ Types ] with the trait [ ` WebSocketEvent ` ]
2023-05-11 22:47:31 +02:00
Using this handle you can also send Gateway Events directly .
2023-04-28 18:18:32 +02:00
* /
2023-05-11 22:47:31 +02:00
pub struct GatewayHandle {
2023-04-28 18:18:32 +02:00
pub url : String ,
2023-05-11 22:47:31 +02:00
pub events : Arc < Mutex < Events > > ,
2023-05-25 23:09:18 +02:00
pub websocket_tx : Arc <
Mutex <
SplitSink <
WebSocketStream < MaybeTlsStream < TcpStream > > ,
tokio_tungstenite ::tungstenite ::Message ,
> ,
> ,
> ,
2023-04-28 18:18:32 +02:00
}
2023-05-11 22:47:31 +02:00
impl GatewayHandle {
2023-05-05 19:23:57 +02:00
/// Sends json to the gateway with an opcode
2023-05-17 17:24:29 +02:00
async fn send_json_event ( & self , op : u8 , to_send : serde_json ::Value ) {
2023-05-05 19:23:57 +02:00
2023-05-26 19:36:41 +02:00
let gateway_payload = types ::GatewaySendPayload {
2023-05-25 23:09:18 +02:00
op ,
2023-05-26 19:36:41 +02:00
d : Some ( to_send ) ,
s : None
2023-05-25 23:09:18 +02:00
} ;
2023-05-05 19:23:57 +02:00
let payload_json = serde_json ::to_string ( & gateway_payload ) . unwrap ( ) ;
let message = tokio_tungstenite ::tungstenite ::Message ::text ( payload_json ) ;
2023-05-11 22:47:31 +02:00
self . websocket_tx . lock ( ) . await . send ( message ) . await . unwrap ( ) ;
2023-05-05 19:23:57 +02:00
}
/// Sends an identify event to the gateway
2023-05-26 12:59:32 +02:00
pub async fn send_identify ( & self , to_send : types ::GatewayIdentifyPayload ) {
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-05 19:23:57 +02:00
2023-05-07 12:44:11 +02:00
println! ( " GW: Sending Identify.. " ) ;
2023-05-05 20:58:00 +02:00
self . send_json_event ( 2 , to_send_value ) . await ;
2023-05-05 19:23:57 +02:00
}
/// Sends a resume event to the gateway
2023-05-26 12:59:32 +02:00
pub async fn send_resume ( & self , to_send : types ::GatewayResume ) {
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-05 19:23:57 +02:00
2023-05-07 12:44:11 +02:00
println! ( " GW: Sending Resume.. " ) ;
2023-05-05 20:58:00 +02:00
self . send_json_event ( 6 , to_send_value ) . await ;
2023-05-05 19:23:57 +02:00
}
/// Sends an update presence event to the gateway
2023-05-26 12:59:32 +02:00
pub async fn send_update_presence ( & self , to_send : types ::PresenceUpdate ) {
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-05 19:23:57 +02:00
2023-05-13 15:59:46 +02:00
println! ( " GW: Sending Presence Update.. " ) ;
2023-05-05 20:58:00 +02:00
self . send_json_event ( 3 , to_send_value ) . await ;
2023-04-30 14:45:15 +02:00
}
2023-05-13 15:59:46 +02:00
2023-05-22 18:42:12 +02:00
/// Sends a request guild members to the server
2023-05-26 12:59:32 +02:00
pub async fn send_request_guild_members ( & self , to_send : types ::GatewayRequestGuildMembers ) {
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-13 15:59:46 +02:00
println! ( " GW: Sending Request Guild Members.. " ) ;
self . send_json_event ( 8 , to_send_value ) . await ;
}
2023-05-22 18:42:12 +02:00
/// Sends an update voice state to the server
2023-05-26 19:47:41 +02:00
pub async fn send_update_voice_state ( & self , to_send : types ::UpdateVoiceState ) {
2023-05-13 15:59:46 +02:00
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-13 15:59:46 +02:00
2023-05-22 18:42:12 +02:00
println! ( " GW: Sending Update Voice State.. " ) ;
2023-05-13 15:59:46 +02:00
self . send_json_event ( 4 , to_send_value ) . await ;
}
2023-05-14 11:43:17 +02:00
2023-05-22 18:42:12 +02:00
/// Sends a call sync to the server
2023-05-26 19:36:41 +02:00
pub async fn send_call_sync ( & self , to_send : types ::CallSync ) {
2023-05-14 11:43:17 +02:00
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-14 11:43:17 +02:00
println! ( " GW: Sending Call Sync.. " ) ;
self . send_json_event ( 13 , to_send_value ) . await ;
}
/// Sends a Lazy Request
2023-05-26 19:36:41 +02:00
pub async fn send_lazy_request ( & self , to_send : types ::LazyRequest ) {
2023-05-14 11:43:17 +02:00
2023-05-17 17:24:29 +02:00
let to_send_value = serde_json ::to_value ( & to_send ) . unwrap ( ) ;
2023-05-14 11:43:17 +02:00
println! ( " GW: Sending Lazy Request.. " ) ;
self . send_json_event ( 14 , to_send_value ) . await ;
}
2023-04-30 14:45:15 +02:00
}
2023-05-11 22:47:31 +02:00
pub struct Gateway {
pub events : Arc < Mutex < Events > > ,
heartbeat_handler : Option < HeartbeatHandler > ,
2023-05-25 23:09:18 +02:00
pub websocket_tx : Arc <
Mutex <
SplitSink <
WebSocketStream < MaybeTlsStream < TcpStream > > ,
tokio_tungstenite ::tungstenite ::Message ,
> ,
> ,
> ,
2023-05-11 22:47:31 +02:00
}
2023-05-13 16:43:29 +02:00
impl Gateway {
2023-05-11 22:47:31 +02:00
pub async fn new (
websocket_url : String ,
) -> Result < GatewayHandle , tokio_tungstenite ::tungstenite ::Error > {
let ( ws_stream , _ ) = match connect_async_tls_with_config (
& websocket_url ,
None ,
2023-05-20 08:39:02 +02:00
false ,
2023-05-11 22:47:31 +02:00
Some ( Connector ::NativeTls (
TlsConnector ::builder ( ) . build ( ) . unwrap ( ) ,
) ) ,
)
. await
{
Ok ( ws_stream ) = > ws_stream ,
2023-05-13 09:47:12 +02:00
Err ( e ) = > return Err ( e ) ,
2023-05-11 22:47:31 +02:00
} ;
let ( ws_tx , mut ws_rx ) = ws_stream . split ( ) ;
let shared_tx = Arc ::new ( Mutex ::new ( ws_tx ) ) ;
2023-05-25 23:09:18 +02:00
let mut gateway = Gateway {
events : Arc ::new ( Mutex ::new ( Events ::default ( ) ) ) ,
heartbeat_handler : None ,
websocket_tx : shared_tx . clone ( ) ,
} ;
2023-05-11 22:47:31 +02:00
let shared_events = gateway . events . clone ( ) ;
2023-05-13 09:47:12 +02:00
// Wait for the first hello and then spawn both tasks so we avoid nested tasks
// This automatically spawns the heartbeat task, but from the main thread
let msg = ws_rx . next ( ) . await . unwrap ( ) . unwrap ( ) ;
2023-05-26 19:36:41 +02:00
let gateway_payload : types ::GatewayReceivePayload = serde_json ::from_str ( msg . to_text ( ) . unwrap ( ) ) . unwrap ( ) ;
2023-05-13 09:47:12 +02:00
if gateway_payload . op ! = 10 {
println! ( " Recieved non hello on gateway init, what is happening? " ) ;
2023-05-25 23:09:18 +02:00
return Err ( tokio_tungstenite ::tungstenite ::Error ::Protocol (
tokio_tungstenite ::tungstenite ::error ::ProtocolError ::InvalidOpcode (
gateway_payload . op ,
) ,
) ) ;
2023-05-13 09:47:12 +02:00
}
println! ( " GW: Received Hello " ) ;
2023-05-26 19:36:41 +02:00
let gateway_hello : types ::HelloData = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 09:47:12 +02:00
gateway . heartbeat_handler = Some ( HeartbeatHandler ::new ( gateway_hello . heartbeat_interval , shared_tx . clone ( ) ) ) ;
// Now we can continously check for messages in a different task, since we aren't going to receive another hello
2023-05-11 22:47:31 +02:00
task ::spawn ( async move {
loop {
let msg = ws_rx . next ( ) . await ;
if msg . as_ref ( ) . is_some ( ) {
let msg_unwrapped = msg . unwrap ( ) . unwrap ( ) ;
gateway . handle_event ( msg_unwrapped ) . await ;
} ;
}
} ) ;
return Ok ( GatewayHandle {
url : websocket_url . clone ( ) ,
events : shared_events ,
websocket_tx : shared_tx . clone ( ) ,
} ) ;
}
/// This handles a message as a websocket event and updates its events along with the events' observers
pub async fn handle_event ( & mut self , msg : tokio_tungstenite ::tungstenite ::Message ) {
if msg . to_string ( ) = = String ::new ( ) {
return ;
}
2023-05-26 19:36:41 +02:00
let gateway_payload : types ::GatewayReceivePayload = serde_json ::from_str ( msg . to_text ( ) . unwrap ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
// See https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes
match gateway_payload . op {
// Dispatch
// An event was dispatched, we need to look at the gateway event name t
0 = > {
2023-05-14 19:55:43 +02:00
let gateway_payload_t = gateway_payload . clone ( ) . t . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
println! ( " GW: Received {} .. " , gateway_payload_t ) ;
2023-05-17 16:24:04 +02:00
2023-05-20 08:39:02 +02:00
println! ( " Event data dump: {} " , gateway_payload . d . clone ( ) . unwrap ( ) . get ( ) ) ;
2023-05-14 19:55:43 +02:00
2023-05-11 22:47:31 +02:00
// See https://discord.com/developers/docs/topics/gateway-events#receive-events
2023-05-17 16:24:04 +02:00
// "Some" of these are uncodumented
2023-05-11 22:47:31 +02:00
match gateway_payload_t . as_str ( ) {
" READY " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GatewayReady = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . session . ready . update_data ( new_data ) . await ;
2023-05-14 14:03:18 +02:00
} ,
" READY_SUPPLEMENTAL " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GatewayReadySupplemental = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . session . ready_supplimental . update_data ( new_data ) . await ;
2023-05-11 22:47:31 +02:00
}
2023-05-13 16:24:34 +02:00
" RESUMED " = > { }
2023-05-27 17:29:30 +02:00
" APPLICATION_COMMAND_PERMISSIONS_UPDATE " = > {
let new_data : types ::ApplicationCommandPermissionsUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . application . command_permissions_update . update_data ( new_data ) . await ;
}
2023-05-27 16:50:38 +02:00
" AUTO_MODERATION_RULE_CREATE " = > {
let new_data : types ::AutoModerationRuleCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . auto_moderation . rule_create . update_data ( new_data ) . await ;
}
" AUTO_MODERATION_RULE_UPDATE " = > {
let new_data : types ::AutoModerationRuleUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . auto_moderation . rule_update . update_data ( new_data ) . await ;
}
" AUTO_MODERATION_RULE_DELETE " = > {
let new_data : types ::AutoModerationRuleDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . auto_moderation . rule_delete . update_data ( new_data ) . await ;
}
" AUTO_MODERATION_ACTION_EXECUTION " = > {
let new_data : types ::AutoModerationActionExecution = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . auto_moderation . action_execution . update_data ( new_data ) . await ;
}
2023-05-13 21:27:44 +02:00
" CHANNEL_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ChannelCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . channel . create . update_data ( new_data ) . await ;
}
" CHANNEL_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ChannelUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . channel . update . update_data ( new_data ) . await ;
}
2023-05-15 20:45:33 +02:00
" CHANNEL_UNREAD_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ChannelUnreadUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-15 20:45:33 +02:00
self . events . lock ( ) . await . channel . unread_update . update_data ( new_data ) . await ;
}
2023-05-13 21:27:44 +02:00
" CHANNEL_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ChannelDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . channel . delete . update_data ( new_data ) . await ;
}
" CHANNEL_PINS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ChannelPinsUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . channel . pins_update . update_data ( new_data ) . await ;
}
2023-05-14 08:20:25 +02:00
" CALL_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::CallCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . call . create . update_data ( new_data ) . await ;
2023-05-14 08:39:23 +02:00
} ,
" CALL_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::CallUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:39:23 +02:00
self . events . lock ( ) . await . call . update . update_data ( new_data ) . await ;
}
" CALL_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::CallDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:39:23 +02:00
self . events . lock ( ) . await . call . delete . update_data ( new_data ) . await ;
2023-05-14 08:20:25 +02:00
}
2023-05-13 21:27:44 +02:00
" THREAD_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . create . update_data ( new_data ) . await ;
}
" THREAD_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . update . update_data ( new_data ) . await ;
}
" THREAD_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . delete . update_data ( new_data ) . await ;
}
" THREAD_LIST_SYNC " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadListSync = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . list_sync . update_data ( new_data ) . await ;
}
" THREAD_MEMBER_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadMemberUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . member_update . update_data ( new_data ) . await ;
}
" THREAD_MEMBERS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::ThreadMembersUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . thread . members_update . update_data ( new_data ) . await ;
}
" GUILD_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . guild . create . update_data ( new_data ) . await ;
}
2023-05-14 08:20:25 +02:00
" GUILD_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . guild . update . update_data ( new_data ) . await ;
}
2023-05-13 16:24:34 +02:00
" GUILD_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . guild . delete . update_data ( new_data ) . await ;
2023-05-13 16:24:34 +02:00
}
2023-05-20 13:03:44 +02:00
" GUILD_AUDIT_LOG_ENTRY_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildAuditLogEntryCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-20 13:03:44 +02:00
self . events . lock ( ) . await . guild . audit_log_entry_create . update_data ( new_data ) . await ;
}
2023-05-13 16:24:34 +02:00
" GUILD_BAN_ADD " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildBanAdd = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . guild . ban_add . update_data ( new_data ) . await ;
2023-05-13 16:24:34 +02:00
}
" GUILD_BAN_REMOVE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildBanRemove = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . guild . ban_remove . update_data ( new_data ) . await ;
}
" GUILD_EMOJIS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildEmojisUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 08:20:25 +02:00
self . events . lock ( ) . await . guild . emojis_update . update_data ( new_data ) . await ;
2023-05-13 16:24:34 +02:00
}
2023-05-14 15:55:20 +02:00
" GUILD_STICKERS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildStickersUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . stickers_update . update_data ( new_data ) . await ;
}
" GUILD_INTEGRATIONS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildIntegrationsUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . integrations_update . update_data ( new_data ) . await ;
}
" GUILD_MEMBER_ADD " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildMemberAdd = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . member_add . update_data ( new_data ) . await ;
}
" GUILD_MEMBER_REMOVE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildMemberRemove = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . member_remove . update_data ( new_data ) . await ;
}
" GUILD_MEMBER_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildMemberUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . member_update . update_data ( new_data ) . await ;
}
" GUILD_MEMBERS_CHUNK " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildMembersChunk = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . members_chunk . update_data ( new_data ) . await ;
}
" GUILD_ROLE_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildRoleCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . role_create . update_data ( new_data ) . await ;
}
" GUILD_ROLE_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildRoleUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . role_update . update_data ( new_data ) . await ;
}
" GUILD_ROLE_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::GuildRoleDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . guild . role_delete . update_data ( new_data ) . await ;
}
2023-05-22 16:46:49 +02:00
" GUILD_SCHEDULED_EVENT_CREATE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::GuildScheduledEventCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 16:46:49 +02:00
self . events . lock ( ) . await . guild . role_scheduled_event_create . update_data ( new_data ) . await ;
}
" GUILD_SCHEDULED_EVENT_UPDATE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::GuildScheduledEventUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 16:46:49 +02:00
self . events . lock ( ) . await . guild . role_scheduled_event_update . update_data ( new_data ) . await ;
}
" GUILD_SCHEDULED_EVENT_DELETE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::GuildScheduledEventDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 16:46:49 +02:00
self . events . lock ( ) . await . guild . role_scheduled_event_delete . update_data ( new_data ) . await ;
}
" GUILD_SCHEDULED_EVENT_USER_ADD " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::GuildScheduledEventUserAdd = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 16:46:49 +02:00
self . events . lock ( ) . await . guild . role_scheduled_event_user_add . update_data ( new_data ) . await ;
}
" GUILD_SCHEDULED_EVENT_USER_REMOVE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::GuildScheduledEventUserRemove = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 16:46:49 +02:00
self . events . lock ( ) . await . guild . role_scheduled_event_user_remove . update_data ( new_data ) . await ;
}
2023-05-20 09:35:48 +02:00
" PASSIVE_UPDATE_V1 " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::PassiveUpdateV1 = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-20 09:35:48 +02:00
self . events . lock ( ) . await . guild . passive_update_v1 . update_data ( new_data ) . await ;
}
2023-05-14 15:55:20 +02:00
" INTEGRATION_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::IntegrationCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . integration . create . update_data ( new_data ) . await ;
}
" INTEGRATION_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::IntegrationUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . integration . update . update_data ( new_data ) . await ;
}
" INTEGRATION_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::IntegrationDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . integration . delete . update_data ( new_data ) . await ;
}
2023-05-27 17:11:47 +02:00
" INTERACTION_CREATE " = > {
let new_data : types ::InteractionCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . interaction . create . update_data ( new_data ) . await ;
}
2023-05-20 12:50:05 +02:00
" INVITE_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::InviteCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-20 12:50:05 +02:00
self . events . lock ( ) . await . invite . create . update_data ( new_data ) . await ;
}
" INVITE_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::InviteDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-20 12:50:05 +02:00
self . events . lock ( ) . await . invite . delete . update_data ( new_data ) . await ;
}
2023-05-11 22:47:31 +02:00
" MESSAGE_CREATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . create . update_data ( new_data ) . await ;
}
" MESSAGE_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . update . update_data ( new_data ) . await ;
}
" MESSAGE_DELETE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . delete . update_data ( new_data ) . await ;
}
" MESSAGE_DELETE_BULK " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageDeleteBulk = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . delete_bulk . update_data ( new_data ) . await ;
}
" MESSAGE_REACTION_ADD " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageReactionAdd = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . reaction_add . update_data ( new_data ) . await ;
}
" MESSAGE_REACTION_REMOVE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageReactionRemove = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . reaction_remove . update_data ( new_data ) . await ;
}
" MESSAGE_REACTION_REMOVE_ALL " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageReactionRemoveAll = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . reaction_remove_all . update_data ( new_data ) . await ;
}
" MESSAGE_REACTION_REMOVE_EMOJI " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageReactionRemoveEmoji = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . message . reaction_remove_emoji . update_data ( new_data ) . await ;
2023-05-14 11:43:17 +02:00
} ,
" MESSAGE_ACK " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::MessageACK = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 11:43:17 +02:00
self . events . lock ( ) . await . message . ack . update_data ( new_data ) . await ;
2023-05-11 22:47:31 +02:00
}
" PRESENCE_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::PresenceUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . user . presence_update . update_data ( new_data ) . await ;
}
2023-05-27 16:03:23 +02:00
" RELATIONSHIP_ADD " = > {
let new_data : types ::RelationshipAdd = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . relationship . add . update_data ( new_data ) . await ;
}
" RELATIONSHIP_REMOVE " = > {
let new_data : types ::RelationshipRemove = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . relationship . remove . update_data ( new_data ) . await ;
}
2023-05-27 17:05:25 +02:00
" STAGE_INSTANCE_CREATE " = > {
let new_data : types ::StageInstanceCreate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . stage_instance . create . update_data ( new_data ) . await ;
}
" STAGE_INSTANCE_UPDATE " = > {
let new_data : types ::StageInstanceUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . stage_instance . update . update_data ( new_data ) . await ;
}
" STAGE_INSTANCE_DELETE " = > {
let new_data : types ::StageInstanceDelete = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
self . events . lock ( ) . await . stage_instance . delete . update_data ( new_data ) . await ;
}
2023-05-14 15:55:20 +02:00
" SESSIONS_REPLACE " = > {
2023-05-26 19:36:41 +02:00
let sessions : Vec < types ::Session > = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
let new_data = types ::SessionsReplace { sessions } ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . session . replace . update_data ( new_data ) . await ;
}
2023-05-11 22:47:31 +02:00
" TYPING_START " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::TypingStartEvent = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-11 22:47:31 +02:00
self . events . lock ( ) . await . user . typing_start_event . update_data ( new_data ) . await ;
}
2023-05-13 16:24:34 +02:00
" USER_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::UserUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-13 21:27:44 +02:00
self . events . lock ( ) . await . user . update . update_data ( new_data ) . await ;
2023-05-13 16:24:34 +02:00
}
2023-05-22 18:42:12 +02:00
" VOICE_STATE_UPDATE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::VoiceStateUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 18:42:12 +02:00
self . events . lock ( ) . await . voice . state_update . update_data ( new_data ) . await ;
}
" VOICE_SERVER_UPDATE " = > {
2023-05-26 19:47:41 +02:00
let new_data : types ::VoiceServerUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-22 18:42:12 +02:00
self . events . lock ( ) . await . voice . server_update . update_data ( new_data ) . await ;
}
2023-05-14 15:55:20 +02:00
" WEBHOOKS_UPDATE " = > {
2023-05-26 19:36:41 +02:00
let new_data : types ::WebhooksUpdate = serde_json ::from_str ( gateway_payload . d . unwrap ( ) . get ( ) ) . unwrap ( ) ;
2023-05-14 15:55:20 +02:00
self . events . lock ( ) . await . webhooks . update . update_data ( new_data ) . await ;
}
2023-05-14 19:55:43 +02:00
_ = > {
2023-05-27 17:31:55 +02:00
println! ( " Received unrecognised gateway event ( {} )! Please open an issue on the chorus github so we can implement it " , & gateway_payload_t ) ;
2023-05-14 19:55:43 +02:00
}
2023-05-11 22:47:31 +02:00
}
}
// Heartbeat
// We received a heartbeat from the server
1 = > { }
// Reconnect
2023-05-25 23:09:18 +02:00
7 = > {
todo! ( )
}
2023-05-11 22:47:31 +02:00
// Invalid Session
2023-05-25 23:09:18 +02:00
9 = > {
todo! ( )
}
2023-05-11 22:47:31 +02:00
// Hello
// Starts our heartbeat
2023-05-13 09:47:12 +02:00
// We should have already handled this in gateway init
2023-05-11 22:47:31 +02:00
10 = > {
2023-05-13 09:47:12 +02:00
panic! ( " Recieved hello when it was unexpected " ) ;
2023-05-11 22:47:31 +02:00
}
// Heartbeat ACK
11 = > {
println! ( " GW: Received Heartbeat ACK " ) ;
}
2023-05-27 17:31:55 +02:00
2 | 3 | 4 | 6 | 8 = > { panic! ( " Received gateway op code that's meant to be sent, not received ( {} ) " , gateway_payload . op ) }
_ = > { println! ( " Received unrecognised gateway op code ( {} )! Please open an issue on the chorus github so we can implement it " , gateway_payload . op ) ; }
2023-05-11 22:47:31 +02:00
}
// If we have an active heartbeat thread and we received a seq number we should let it know
if gateway_payload . s . is_some ( ) {
if self . heartbeat_handler . is_some ( ) {
2023-05-25 23:09:18 +02:00
let heartbeat_communication = HeartbeatThreadCommunication {
op : gateway_payload . op ,
d : gateway_payload . s . unwrap ( ) ,
} ;
2023-05-11 22:47:31 +02:00
2023-05-25 23:09:18 +02:00
self . heartbeat_handler
. as_mut ( )
. unwrap ( )
. tx
. send ( heartbeat_communication )
. await
. unwrap ( ) ;
2023-05-11 22:47:31 +02:00
}
}
}
}
2023-05-05 18:38:04 +02:00
/**
Handles sending heartbeats to the gateway in another thread
* /
struct HeartbeatHandler {
/// The heartbeat interval in milliseconds
heartbeat_interval : u128 ,
tx : Sender < HeartbeatThreadCommunication > ,
}
impl HeartbeatHandler {
2023-05-25 23:09:18 +02:00
pub fn new (
heartbeat_interval : u128 ,
websocket_tx : Arc <
Mutex <
SplitSink <
WebSocketStream < MaybeTlsStream < TcpStream > > ,
tokio_tungstenite ::tungstenite ::Message ,
> ,
> ,
> ,
) -> HeartbeatHandler {
2023-05-07 11:58:12 +02:00
let ( tx , mut rx ) = mpsc ::channel ( 32 ) ;
2023-05-05 18:38:04 +02:00
task ::spawn ( async move {
let mut last_heartbeat : Instant = time ::Instant ::now ( ) ;
let mut last_seq_number : Option < u64 > = None ;
loop {
// If we received a seq number update, use that as the last seq number
2023-05-25 23:09:18 +02:00
let hb_communication : Result < HeartbeatThreadCommunication , TryRecvError > =
rx . try_recv ( ) ;
2023-05-07 11:58:12 +02:00
if hb_communication . is_ok ( ) {
2023-05-05 18:38:04 +02:00
last_seq_number = Some ( hb_communication . unwrap ( ) . d ) ;
}
if last_heartbeat . elapsed ( ) . as_millis ( ) > heartbeat_interval {
2023-05-07 12:44:11 +02:00
println! ( " GW: Sending Heartbeat.. " ) ;
2023-05-06 11:14:38 +02:00
2023-05-26 12:59:32 +02:00
let heartbeat = types ::GatewayHeartbeat {
2023-05-05 18:38:04 +02:00
op : 1 ,
2023-05-25 23:09:18 +02:00
d : last_seq_number ,
2023-05-05 18:38:04 +02:00
} ;
let heartbeat_json = serde_json ::to_string ( & heartbeat ) . unwrap ( ) ;
let msg = tokio_tungstenite ::tungstenite ::Message ::text ( heartbeat_json ) ;
2023-05-25 23:09:18 +02:00
websocket_tx . lock ( ) . await . send ( msg ) . await . unwrap ( ) ;
2023-05-05 18:38:04 +02:00
last_heartbeat = time ::Instant ::now ( ) ;
}
}
} ) ;
2023-05-25 23:09:18 +02:00
Self {
heartbeat_interval ,
tx ,
}
2023-05-05 18:38:04 +02:00
}
}
/**
Used to communicate with the main thread .
Either signifies a sequence number update or a received heartbeat ack
* /
#[ derive(Clone, Copy, Debug) ]
struct HeartbeatThreadCommunication {
/// An opcode for the communication we received
op : u8 ,
/// The sequence number we got from discord
2023-05-25 23:09:18 +02:00
d : u64 ,
2023-05-05 18:38:04 +02:00
}
2023-04-28 13:40:29 +02:00
/**
Trait which defines the behaviour of an Observer . An Observer is an object which is subscribed to
an Observable . The Observer is notified when the Observable ' s data changes .
2023-04-28 18:18:32 +02:00
In this case , the Observable is a [ ` GatewayEvent ` ] , which is a wrapper around a WebSocketEvent .
2023-04-28 13:40:29 +02:00
* /
2023-05-26 12:59:32 +02:00
pub trait Observer < T : types ::WebSocketEvent > : std ::fmt ::Debug {
2023-04-28 12:31:59 +02:00
fn update ( & self , data : & T ) ;
2023-04-27 17:57:10 +02:00
}
2023-04-28 13:40:29 +02:00
/** GatewayEvent is a wrapper around a WebSocketEvent. It is used to notify the observers of a
2023-04-28 18:18:32 +02:00
change in the WebSocketEvent . GatewayEvents are observable .
* /
2023-05-11 22:47:31 +02:00
#[ derive(Default, Debug) ]
2023-05-26 12:59:32 +02:00
pub struct GatewayEvent < T : types ::WebSocketEvent > {
2023-05-11 22:47:31 +02:00
observers : Vec < Arc < Mutex < dyn Observer < T > + Sync + Send > > > ,
2023-04-28 12:31:59 +02:00
pub event_data : T ,
2023-04-27 22:29:07 +02:00
pub is_observed : bool ,
2023-04-27 17:57:10 +02:00
}
2023-05-26 12:59:32 +02:00
impl < T : types ::WebSocketEvent > GatewayEvent < T > {
2023-04-28 12:31:59 +02:00
fn new ( event_data : T ) -> Self {
2023-04-27 17:57:10 +02:00
Self {
2023-04-27 22:29:07 +02:00
is_observed : false ,
2023-04-27 17:57:10 +02:00
observers : Vec ::new ( ) ,
2023-04-28 12:31:59 +02:00
event_data ,
2023-04-27 17:57:10 +02:00
}
}
2023-04-28 13:40:29 +02:00
/**
Returns true if the GatewayEvent is observed by at least one Observer .
2023-04-28 18:18:32 +02:00
* /
2023-04-27 22:29:07 +02:00
pub fn is_observed ( & self ) -> bool {
self . is_observed
}
2023-04-28 13:40:29 +02:00
/**
Subscribes an Observer to the GatewayEvent . Returns an error if the GatewayEvent is already
observed .
# Errors
Returns an error if the GatewayEvent is already observed .
Error type : [ ` ObserverError ::AlreadySubscribedError ` ]
2023-04-28 18:18:32 +02:00
* /
2023-05-25 23:09:18 +02:00
pub fn subscribe (
& mut self ,
observable : Arc < Mutex < dyn Observer < T > + Sync + Send > > ,
) -> Option < ObserverError > {
2023-04-27 22:29:07 +02:00
if self . is_observed {
2023-04-27 22:38:41 +02:00
return Some ( ObserverError ::AlreadySubscribedError ) ;
2023-04-27 22:29:07 +02:00
}
self . is_observed = true ;
2023-04-27 22:38:41 +02:00
self . observers . push ( observable ) ;
None
2023-04-27 17:57:10 +02:00
}
2023-04-28 13:40:29 +02:00
/**
Unsubscribes an Observer from the GatewayEvent .
2023-04-28 18:18:32 +02:00
* /
2023-05-11 22:47:31 +02:00
pub fn unsubscribe ( & mut self , observable : Arc < Mutex < dyn Observer < T > + Sync + Send > > ) {
2023-04-28 12:31:59 +02:00
// .retain()'s closure retains only those elements of the vector, which have a different
// pointer value than observable.
2023-05-11 22:47:31 +02:00
// The usage of the debug format to compare the generic T of observers is quite stupid, but the only thing to compare between them is T and if T == T they are the same
// anddd there is no way to do that without using format
2023-05-25 23:09:18 +02:00
self . observers
. retain ( | obs | ! ( format! ( " {:?} " , obs ) = = format! ( " {:?} " , & observable ) ) ) ;
2023-04-28 12:31:59 +02:00
self . is_observed = ! self . observers . is_empty ( ) ;
2023-04-27 17:57:10 +02:00
}
2023-04-28 13:40:29 +02:00
/**
Updates the GatewayEvent ' s data and notifies the observers .
2023-04-28 18:18:32 +02:00
* /
2023-05-11 22:47:31 +02:00
async fn update_data ( & mut self , new_event_data : T ) {
2023-04-28 12:31:59 +02:00
self . event_data = new_event_data ;
2023-05-11 22:47:31 +02:00
self . notify ( ) . await ;
2023-04-27 17:57:10 +02:00
}
2023-04-28 13:40:29 +02:00
/**
Notifies the observers of the GatewayEvent .
2023-04-28 18:18:32 +02:00
* /
2023-05-11 22:47:31 +02:00
async fn notify ( & self ) {
2023-04-27 17:57:10 +02:00
for observer in & self . observers {
2023-05-11 22:47:31 +02:00
observer . lock ( ) . await . update ( & self . event_data ) ;
2023-04-28 12:31:59 +02:00
}
}
}
2023-04-28 18:18:32 +02:00
mod events {
use super ::* ;
2023-05-11 22:47:31 +02:00
#[ derive(Default, Debug) ]
pub struct Events {
2023-05-27 17:29:30 +02:00
pub application : Application ,
2023-05-27 16:50:38 +02:00
pub auto_moderation : AutoModeration ,
2023-05-14 15:55:20 +02:00
pub session : Session ,
2023-05-11 22:47:31 +02:00
pub message : Message ,
pub user : User ,
2023-05-27 16:03:23 +02:00
pub relationship : Relationship ,
2023-05-13 21:27:44 +02:00
pub channel : Channel ,
pub thread : Thread ,
pub guild : Guild ,
2023-05-20 12:50:05 +02:00
pub invite : Invite ,
2023-05-14 15:55:20 +02:00
pub integration : Integration ,
2023-05-27 17:11:47 +02:00
pub interaction : Interaction ,
2023-05-27 17:05:25 +02:00
pub stage_instance : StageInstance ,
2023-05-14 08:20:25 +02:00
pub call : Call ,
2023-05-22 18:42:12 +02:00
pub voice : Voice ,
2023-05-14 15:55:20 +02:00
pub webhooks : Webhooks ,
2023-05-26 12:59:32 +02:00
pub gateway_identify_payload : GatewayEvent < types ::GatewayIdentifyPayload > ,
pub gateway_resume : GatewayEvent < types ::GatewayResume > ,
2023-04-28 18:18:32 +02:00
}
2023-05-27 17:29:30 +02:00
#[ derive(Default, Debug) ]
pub struct Application {
pub command_permissions_update : GatewayEvent < types ::ApplicationCommandPermissionsUpdate > ,
}
2023-05-27 16:50:38 +02:00
#[ derive(Default, Debug) ]
pub struct AutoModeration {
pub rule_create : GatewayEvent < types ::AutoModerationRuleCreate > ,
pub rule_update : GatewayEvent < types ::AutoModerationRuleUpdate > ,
pub rule_delete : GatewayEvent < types ::AutoModerationRuleDelete > ,
pub action_execution : GatewayEvent < types ::AutoModerationActionExecution > ,
}
2023-05-14 14:03:18 +02:00
#[ derive(Default, Debug) ]
2023-05-14 15:55:20 +02:00
pub struct Session {
2023-05-26 19:36:41 +02:00
pub ready : GatewayEvent < types ::GatewayReady > ,
pub ready_supplimental : GatewayEvent < types ::GatewayReadySupplemental > ,
pub replace : GatewayEvent < types ::SessionsReplace >
2023-05-14 14:03:18 +02:00
}
2023-05-27 17:05:25 +02:00
#[ derive(Default, Debug) ]
pub struct StageInstance {
pub create : GatewayEvent < types ::StageInstanceCreate > ,
pub update : GatewayEvent < types ::StageInstanceUpdate > ,
pub delete : GatewayEvent < types ::StageInstanceDelete > ,
}
2023-05-11 22:47:31 +02:00
#[ derive(Default, Debug) ]
pub struct Message {
2023-05-26 12:59:32 +02:00
pub create : GatewayEvent < types ::MessageCreate > ,
pub update : GatewayEvent < types ::MessageUpdate > ,
pub delete : GatewayEvent < types ::MessageDelete > ,
pub delete_bulk : GatewayEvent < types ::MessageDeleteBulk > ,
pub reaction_add : GatewayEvent < types ::MessageReactionAdd > ,
pub reaction_remove : GatewayEvent < types ::MessageReactionRemove > ,
pub reaction_remove_all : GatewayEvent < types ::MessageReactionRemoveAll > ,
pub reaction_remove_emoji : GatewayEvent < types ::MessageReactionRemoveEmoji > ,
2023-05-26 19:36:41 +02:00
pub ack : GatewayEvent < types ::MessageACK >
2023-04-28 18:18:32 +02:00
}
2023-05-11 22:47:31 +02:00
#[ derive(Default, Debug) ]
pub struct User {
2023-05-26 12:59:32 +02:00
pub update : GatewayEvent < types ::UserUpdate > ,
pub presence_update : GatewayEvent < types ::PresenceUpdate > ,
pub typing_start_event : GatewayEvent < types ::TypingStartEvent > ,
2023-04-28 18:18:32 +02:00
}
2023-05-13 21:27:44 +02:00
2023-05-27 16:03:23 +02:00
#[ derive(Default, Debug) ]
pub struct Relationship {
pub add : GatewayEvent < types ::RelationshipAdd > ,
pub remove : GatewayEvent < types ::RelationshipRemove > ,
}
2023-05-13 21:27:44 +02:00
#[ derive(Default, Debug) ]
pub struct Channel {
2023-05-26 12:59:32 +02:00
pub create : GatewayEvent < types ::ChannelCreate > ,
pub update : GatewayEvent < types ::ChannelUpdate > ,
2023-05-26 19:36:41 +02:00
pub unread_update : GatewayEvent < types ::ChannelUnreadUpdate > ,
2023-05-26 12:59:32 +02:00
pub delete : GatewayEvent < types ::ChannelDelete > ,
pub pins_update : GatewayEvent < types ::ChannelPinsUpdate > ,
2023-05-13 21:27:44 +02:00
}
#[ derive(Default, Debug) ]
pub struct Thread {
2023-05-26 12:59:32 +02:00
pub create : GatewayEvent < types ::ThreadCreate > ,
pub update : GatewayEvent < types ::ThreadUpdate > ,
pub delete : GatewayEvent < types ::ThreadDelete > ,
pub list_sync : GatewayEvent < types ::ThreadListSync > ,
pub member_update : GatewayEvent < types ::ThreadMemberUpdate > ,
pub members_update : GatewayEvent < types ::ThreadMembersUpdate > ,
2023-05-13 21:27:44 +02:00
}
#[ derive(Default, Debug) ]
pub struct Guild {
2023-05-26 12:59:32 +02:00
pub create : GatewayEvent < types ::GuildCreate > ,
2023-05-26 19:36:41 +02:00
pub update : GatewayEvent < types ::GuildUpdate > ,
pub delete : GatewayEvent < types ::GuildDelete > ,
pub audit_log_entry_create : GatewayEvent < types ::GuildAuditLogEntryCreate > ,
pub ban_add : GatewayEvent < types ::GuildBanAdd > ,
pub ban_remove : GatewayEvent < types ::GuildBanRemove > ,
pub emojis_update : GatewayEvent < types ::GuildEmojisUpdate > ,
pub stickers_update : GatewayEvent < types ::GuildStickersUpdate > ,
pub integrations_update : GatewayEvent < types ::GuildIntegrationsUpdate > ,
pub member_add : GatewayEvent < types ::GuildMemberAdd > ,
pub member_remove : GatewayEvent < types ::GuildMemberRemove > ,
pub member_update : GatewayEvent < types ::GuildMemberUpdate > ,
pub members_chunk : GatewayEvent < types ::GuildMembersChunk > ,
pub role_create : GatewayEvent < types ::GuildRoleCreate > ,
pub role_update : GatewayEvent < types ::GuildRoleUpdate > ,
pub role_delete : GatewayEvent < types ::GuildRoleDelete > ,
2023-05-26 19:47:41 +02:00
pub role_scheduled_event_create : GatewayEvent < types ::GuildScheduledEventCreate > ,
pub role_scheduled_event_update : GatewayEvent < types ::GuildScheduledEventUpdate > ,
pub role_scheduled_event_delete : GatewayEvent < types ::GuildScheduledEventDelete > ,
pub role_scheduled_event_user_add : GatewayEvent < types ::GuildScheduledEventUserAdd > ,
pub role_scheduled_event_user_remove : GatewayEvent < types ::GuildScheduledEventUserRemove > ,
2023-05-26 19:36:41 +02:00
pub passive_update_v1 : GatewayEvent < types ::PassiveUpdateV1 > ,
2023-05-13 21:27:44 +02:00
}
2023-05-14 08:20:25 +02:00
2023-05-20 12:50:05 +02:00
#[ derive(Default, Debug) ]
pub struct Invite {
2023-05-26 19:36:41 +02:00
pub create : GatewayEvent < types ::InviteCreate > ,
pub delete : GatewayEvent < types ::InviteDelete >
2023-05-20 12:50:05 +02:00
}
2023-05-14 15:55:20 +02:00
#[ derive(Default, Debug) ]
pub struct Integration {
2023-05-26 19:36:41 +02:00
pub create : GatewayEvent < types ::IntegrationCreate > ,
pub update : GatewayEvent < types ::IntegrationUpdate > ,
pub delete : GatewayEvent < types ::IntegrationDelete >
2023-05-14 15:55:20 +02:00
}
2023-05-27 17:11:47 +02:00
#[ derive(Default, Debug) ]
pub struct Interaction {
pub create : GatewayEvent < types ::InteractionCreate > ,
}
2023-05-14 08:20:25 +02:00
#[ derive(Default, Debug) ]
pub struct Call {
2023-05-26 19:36:41 +02:00
pub create : GatewayEvent < types ::CallCreate > ,
pub update : GatewayEvent < types ::CallUpdate > ,
pub delete : GatewayEvent < types ::CallDelete >
2023-05-14 08:20:25 +02:00
}
2023-05-14 15:55:20 +02:00
2023-05-22 18:42:12 +02:00
#[ derive(Default, Debug) ]
pub struct Voice {
2023-05-26 19:47:41 +02:00
pub state_update : GatewayEvent < types ::VoiceStateUpdate > ,
pub server_update : GatewayEvent < types ::VoiceServerUpdate >
2023-05-22 18:42:12 +02:00
}
2023-05-14 15:55:20 +02:00
#[ derive(Default, Debug) ]
pub struct Webhooks {
2023-05-26 19:36:41 +02:00
pub update : GatewayEvent < types ::WebhooksUpdate > ,
2023-05-14 15:55:20 +02:00
}
2023-04-28 18:18:32 +02:00
}
2023-04-28 12:31:59 +02:00
#[ cfg(test) ]
2023-04-28 12:39:58 +02:00
mod example {
2023-04-28 12:31:59 +02:00
use super ::* ;
2023-05-11 22:47:31 +02:00
#[ derive(Debug) ]
2023-04-28 12:31:59 +02:00
struct Consumer ;
2023-05-26 12:59:32 +02:00
impl Observer < types ::GatewayResume > for Consumer {
fn update ( & self , data : & types ::GatewayResume ) {
2023-04-28 12:31:59 +02:00
println! ( " {} " , data . token )
}
}
2023-05-11 22:47:31 +02:00
#[ tokio::test ]
async fn test_observer_behaviour ( ) {
2023-05-26 12:59:32 +02:00
let mut event = GatewayEvent ::new ( types ::GatewayResume {
2023-04-28 12:31:59 +02:00
token : " start " . to_string ( ) ,
session_id : " start " . to_string ( ) ,
seq : " start " . to_string ( ) ,
} ) ;
2023-05-26 12:59:32 +02:00
let new_data = types ::GatewayResume {
2023-04-28 12:31:59 +02:00
token : " token_3276ha37am3 " . to_string ( ) ,
session_id : " 89346671230 " . to_string ( ) ,
seq : " 3 " . to_string ( ) ,
} ;
let consumer = Consumer ;
2023-05-13 15:36:29 +02:00
let arc_mut_consumer = Arc ::new ( Mutex ::new ( consumer ) ) ;
2023-04-28 12:31:59 +02:00
2023-05-13 15:36:29 +02:00
event . subscribe ( arc_mut_consumer . clone ( ) ) ;
2023-04-28 12:31:59 +02:00
2023-05-11 22:47:31 +02:00
event . notify ( ) . await ;
2023-04-28 12:31:59 +02:00
2023-05-11 22:47:31 +02:00
event . update_data ( new_data ) . await ;
2023-04-28 12:31:59 +02:00
let second_consumer = Consumer ;
2023-05-13 15:36:29 +02:00
let arc_mut_second_consumer = Arc ::new ( Mutex ::new ( second_consumer ) ) ;
2023-04-28 12:31:59 +02:00
2023-05-13 15:36:29 +02:00
match event . subscribe ( arc_mut_second_consumer . clone ( ) ) {
2023-04-28 12:39:58 +02:00
None = > assert! ( false ) ,
2023-04-28 12:31:59 +02:00
Some ( err ) = > println! ( " You cannot subscribe twice: {} " , err ) ,
2023-04-27 17:57:10 +02:00
}
2023-05-13 15:36:29 +02:00
event . unsubscribe ( arc_mut_consumer . clone ( ) ) ;
match event . subscribe ( arc_mut_second_consumer . clone ( ) ) {
None = > assert! ( true ) ,
2023-05-13 16:35:42 +02:00
Some ( _ ) = > assert! ( false ) ,
2023-05-13 15:36:29 +02:00
}
2023-04-27 17:57:10 +02:00
}
2023-04-28 23:21:55 +02:00
#[ tokio::test ]
2023-05-13 15:36:29 +02:00
async fn test_gateway_establish ( ) {
2023-05-09 20:35:53 +02:00
let _gateway = Gateway ::new ( " ws://localhost:3001/ " . to_string ( ) )
2023-04-28 23:21:55 +02:00
. await
. unwrap ( ) ;
}
2023-04-25 17:21:27 +02:00
}