aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-15 08:12:53 -0800
committerAustin Hellyer <[email protected]>2016-11-15 08:12:53 -0800
commitb0be1414dc75c8ace19fa033fd54046c71640c13 (patch)
tree7b125327e35b21506a8c25b54e1cb3a9dfe41e70 /src
parentDecode embed/role colours into Colour struct (diff)
downloadserenity-b0be1414dc75c8ace19fa033fd54046c71640c13.tar.xz
serenity-b0be1414dc75c8ace19fa033fd54046c71640c13.zip
State: on update, return old instances
When updating the State, return the old instance of removed/updated fields where possible, so that they can be used to send to event handlers as a "this is what it used to look like, this is what it looks like now" type of thing. Very descriptive, I know.
Diffstat (limited to 'src')
-rw-r--r--src/client/dispatch.rs85
-rw-r--r--src/client/event_store.rs16
-rw-r--r--src/client/mod.rs58
-rw-r--r--src/ext/state/mod.rs225
4 files changed, 236 insertions, 148 deletions
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs
index 7efee75..985f03e 100644
--- a/src/client/dispatch.rs
+++ b/src/client/dispatch.rs
@@ -20,7 +20,10 @@ macro_rules! handler {
macro_rules! update {
($method:ident, $event:expr) => {
STATE.lock().unwrap().$method(&$event);
- }
+ };
+ ($method:ident, $event:expr, $old:expr) => {
+ STATE.lock().unwrap().$method(&$event, $old);
+ };
}
fn context(channel_id: Option<ChannelId>,
@@ -71,13 +74,7 @@ pub fn dispatch(event: Result<Event>,
},
Ok(Event::CallUpdate(event)) => {
if let Some(ref handler) = handler!(on_call_update, event_store) {
- let before = STATE
- .lock()
- .unwrap()
- .calls
- .get(&event.channel_id)
- .cloned();
- update!(update_with_call_update, event);
+ let before = update!(update_with_call_update, event, true);
let after = STATE
.lock()
.unwrap()
@@ -92,7 +89,7 @@ pub fn dispatch(event: Result<Event>,
(handler)(context, before, after);
});
} else {
- update!(update_with_call_update, event);
+ update!(update_with_call_update, event, false);
}
},
Ok(Event::ChannelCreate(event)) => {
@@ -226,15 +223,16 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildDelete(event)) => {
- update!(update_with_guild_delete, event);
-
if let Some(ref handler) = handler!(on_guild_delete, event_store) {
+ let full = update!(update_with_guild_delete, event);
let context = context(None, conn, login_type);
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event.guild);
+ (handler)(context, event.guild, full);
});
+ } else {
+ let _full = update!(update_with_guild_delete, event);
}
},
Ok(Event::GuildEmojisUpdate(event)) => {
@@ -245,7 +243,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id, event.emojis);
});
}
},
@@ -255,7 +253,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id);
});
}
},
@@ -272,30 +270,21 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildMemberRemove(event)) => {
- update!(update_with_guild_member_remove, event);
-
if let Some(ref handler) = handler!(on_guild_member_removal, event_store) {
+ let member = update!(update_with_guild_member_remove, event);
let context = context(None, conn, login_type);
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event.guild_id, event.user);
+ (handler)(context, event.guild_id, event.user, member);
});
+ } else {
+ let _member = update!(update_with_guild_member_remove, event);
}
},
Ok(Event::GuildMemberUpdate(event)) => {
if let Some(ref handler) = handler!(on_guild_member_update, event_store) {
- let before = STATE.lock()
- .unwrap()
- .guilds
- .get_mut(&event.guild_id)
- .map(|mut guild| {
- guild.members.remove(&event.user.id)
- }).and_then(|x| match x {
- Some(x) => Some(x),
- _ => None,
- });
- update!(update_with_guild_member_update, event);
+ let before = update!(update_with_guild_member_update, event, true);
// This is safe, as the update would have created the member
// if it did not exist. Thus, there _should_ be no way that this
@@ -311,6 +300,8 @@ pub fn dispatch(event: Result<Event>,
thread::spawn(move || {
(handler)(context, before, after);
});
+ } else {
+ let _ = update!(update_with_guild_member_update, event, false);
}
},
Ok(Event::GuildMembersChunk(event)) => {
@@ -338,26 +329,25 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildRoleDelete(event)) => {
- update!(update_with_guild_role_delete, event);
-
if let Some(ref handler) = handler!(on_guild_role_delete, event_store) {
+ let role = update!(update_with_guild_role_delete, event);
let context = context(None, conn, login_type);
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event.guild_id, event.role_id);
+ (handler)(context, event.guild_id, event.role_id, role);
});
}
},
Ok(Event::GuildRoleUpdate(event)) => {
- update!(update_with_guild_role_update, event);
+ let before = update!(update_with_guild_role_update, event);
if let Some(ref handler) = handler!(on_guild_role_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event.guild_id, event.role);
+ (handler)(context, event.guild_id, before, event.role);
});
}
},
@@ -596,13 +586,9 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::UserGuildSettingsUpdate(event)) => {
- if let Some(ref handler) = handler!(on_user_guild_settings_update, event_store) {
- let before = STATE.lock()
- .unwrap()
- .guild_settings
- .remove(&event.settings.guild_id);
- update!(update_with_user_guild_settings_update, event);
+ let before = update!(update_with_user_guild_settings_update, event);
+ if let Some(ref handler) = handler!(on_user_guild_settings_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -612,19 +598,20 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::UserNoteUpdate(event)) => {
+ let before = update!(update_with_user_note_update, event);
+
if let Some(ref handler) = handler!(on_note_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event.user_id, event.note);
+ (handler)(context, event.user_id, before, event.note);
});
}
},
Ok(Event::UserSettingsUpdate(event)) => {
if let Some(ref handler) = handler!(on_user_settings_update, event_store) {
- let before = STATE.lock().unwrap().settings.clone();
- update!(update_with_user_settings_update, event);
+ let before = update!(update_with_user_settings_update, event, true);
let after = STATE.lock().unwrap().settings.clone();
let context = context(None, conn, login_type);
@@ -634,19 +621,13 @@ pub fn dispatch(event: Result<Event>,
(handler)(context, before.unwrap(), after.unwrap());
});
} else {
- update!(update_with_user_settings_update, event);
+ update!(update_with_user_settings_update, event, false);
}
},
Ok(Event::UserUpdate(event)) => {
- if let Some(ref handler) = handler!(on_user_update, event_store) {
- // This is equivilant to performing a
- // `update_with_voice_state_update`, and will be more efficient.
- let before = {
- let mut state = STATE.lock().unwrap();
-
- mem::replace(&mut state.user, event.current_user.clone())
- };
+ let before = update!(update_with_user_update, event);
+ if let Some(ref handler) = handler!(on_user_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -673,7 +654,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id, event.voice_state);
});
}
},
diff --git a/src/client/event_store.rs b/src/client/event_store.rs
index 576fe29..387f9e7 100644
--- a/src/client/event_store.rs
+++ b/src/client/event_store.rs
@@ -38,16 +38,16 @@ pub struct EventStore {
pub on_guild_ban_addition: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>,
pub on_guild_ban_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>,
pub on_guild_create: Option<Arc<Fn(Context, LiveGuild) + Send + Sync + 'static>>,
- pub on_guild_delete: Option<Arc<Fn(Context, Guild) + Send + Sync + 'static>>,
- pub on_guild_emojis_update: Option<Arc<Fn(Context, GuildEmojisUpdateEvent) + Send + Sync + 'static>>,
- pub on_guild_integrations_update: Option<Arc<Fn(Context, GuildIntegrationsUpdateEvent) + Send + Sync + 'static>>,
+ pub on_guild_delete: Option<Arc<Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static>>,
+ pub on_guild_emojis_update: Option<Arc<Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static>>,
+ pub on_guild_integrations_update: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>,
pub on_guild_member_addition: Option<Arc<Fn(Context, GuildId, Member) + Send + Sync + 'static>>,
- pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>,
+ pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static>>,
pub on_guild_member_update: Option<Arc<Fn(Context, Option<Member>, Member) + Send + Sync + 'static>>,
pub on_guild_members_chunk: Option<Arc<Fn(Context, GuildId, HashMap<UserId, Member>) + Send + Sync + 'static>>,
pub on_guild_role_create: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>,
- pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId) + Send + Sync + 'static>>,
- pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>,
+ pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static>>,
+ pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static>>,
pub on_guild_sync: Option<Arc<Fn(Context, GuildSyncEvent) + Send + Sync + 'static>>,
pub on_guild_unavailable: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>,
pub on_guild_update: Option<Arc<Fn(Context, Option<LiveGuild>, Guild) + Send + Sync + 'static>>,
@@ -59,7 +59,7 @@ pub struct EventStore {
pub on_reaction_remove: Option<Arc<Fn(Context, Reaction) + Send + Sync + 'static>>,
pub on_reaction_remove_all: Option<Arc<Fn(Context, ChannelId, MessageId) + Send + Sync + 'static>>,
pub on_message_update: Option<Arc<Fn(Context, MessageUpdateEvent) + Send + Sync + 'static>>,
- pub on_note_update: Option<Arc<Fn(Context, UserId, String) + Send + Sync + 'static>>,
+ pub on_note_update: Option<Arc<Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static>>,
pub on_presence_replace: Option<Arc<Fn(Context, Vec<Presence>) + Send + Sync + 'static>>,
pub on_presence_update: Option<Arc<Fn(Context, PresenceUpdateEvent) + Send + Sync + 'static>>,
pub on_ready: Option<Arc<Fn(Context, Ready) + Send + Sync + 'static>>,
@@ -71,7 +71,7 @@ pub struct EventStore {
pub on_user_guild_settings_update: Option<Arc<Fn(Context, Option<UserGuildSettings>, UserGuildSettings) + Send + Sync + 'static>>,
pub on_user_update: Option<Arc<Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static>>,
pub on_user_settings_update: Option<Arc<Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static>>,
- pub on_voice_state_update: Option<Arc<Fn(Context, VoiceStateUpdateEvent) + Send + Sync + 'static>>,
pub on_voice_server_update: Option<Arc<Fn(Context, VoiceServerUpdateEvent) + Send + Sync + 'static>>,
+ pub on_voice_state_update: Option<Arc<Fn(Context, Option<GuildId>, VoiceState) + Send + Sync + 'static>>,
pub on_webhook_update: Option<Arc<Fn(Context, GuildId, ChannelId) + Send + Sync + 'static>>,
}
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 661d477..f270b31 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -475,9 +475,19 @@ impl Client {
/// Attaches a handler for when a [`GuilDelete`] is received.
///
- /// [`GuilDelete`]: ../model/enum.Event.html#variant.GuildDelete
+ /// Returns a partial guild as well as - optionally - the full guild, with
+ /// data like [`Role`]s. This can be `None` in the event that it was not in
+ /// the [`State`].
+ ///
+ /// **Note**: The relevant guild is _removed_ from the State when this event
+ /// is received. If you need to keep it, you can either re-insert it
+ /// yourself back into the State or manage it in another way.
+ ///
+ /// [`GuildDelete`]: ../model/enum.Event.html#variant.GuildDelete
+ /// [`Role`]: ../model/struct.Role.html
+ /// [`State`]: ../ext/state/struct.State.html
pub fn on_guild_delete<F>(&mut self, handler: F)
- where F: Fn(Context, Guild) + Send + Sync + 'static {
+ where F: Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_delete = Some(Arc::new(handler));
@@ -485,9 +495,11 @@ impl Client {
/// Attaches a handler for when a [`GuildEmojisUpdate`] is received.
///
+ /// The `HashMap` of emojis is the new full list of emojis.
+ ///
/// [`GuildEmojisUpdate`]: ../model/enum.Event.html#variant.GuildEmojisUpdate
pub fn on_guild_emojis_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildEmojisUpdateEvent) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_emojis_update = Some(Arc::new(handler));
@@ -497,7 +509,7 @@ impl Client {
///
/// [`GuildIntegrationsUpdate`]: ../model/enum.Event.html#variant.GuildIntegrationsUpdate
pub fn on_guild_integrations_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildIntegrationsUpdateEvent) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_integrations_update = Some(Arc::new(handler));
@@ -515,9 +527,12 @@ impl Client {
/// Attaches a handler for when a [`GuildMemberRemove`] is received.
///
+ /// Returns the user's associated `Member` object, _if_ it existed in the
+ /// state.
+ ///
/// [`GuildMemberRemove`]: ../model/enum.Event.html#variant.GuildMemberRemove
pub fn on_guild_member_remove<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, User) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_member_removal = Some(Arc::new(handler));
@@ -557,7 +572,7 @@ impl Client {
///
/// [`GuildRoleDelete`]: ../model/enum.Event.html#variant.GuildRoleDelete
pub fn on_guild_role_delete<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, RoleId) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_role_delete = Some(Arc::new(handler));
@@ -565,9 +580,13 @@ impl Client {
/// Attaches a handler for when a [`GuildRoleUpdate`] is received.
///
+ /// The optional `Role` is the role prior to updating. This can be `None` if
+ /// it did not exist in the [`State`] before the update.
+ ///
/// [`GuildRoleUpdate`]: ../model/enum.Event.html#variant.GuildRoleUpdate
+ /// [`State`]: ../ext/state/struct.State.html
pub fn on_guild_role_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Role) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_role_update = Some(Arc::new(handler));
@@ -676,9 +695,12 @@ impl Client {
/// Attaches a handler for when a [`UserNoteUpdate`] is received.
///
+ /// Optionally returns the old note for the [`User`], if one existed.
+ ///
+ /// [`User`]: ../model/struct.User.html
/// [`UserNoteUpdate`]: ../model/enum.Event.html#variant.UserNoteUpdate
pub fn on_note_update<F>(&mut self, handler: F)
- where F: Fn(Context, UserId, String) + Send + Sync + 'static {
+ where F: Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_note_update = Some(Arc::new(handler));
@@ -866,16 +888,6 @@ impl Client {
.on_user_settings_update = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`VoiceStateUpdate`] is received.
- ///
- /// [`VoiceStateUpdate`]: ../model/enum.Event.html#variant.VoiceStateUpdate
- pub fn on_voice_state_update<F>(&mut self, handler: F)
- where F: Fn(Context, VoiceStateUpdateEvent) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_voice_state_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`VoiceServerUpdate`] is received.
///
/// [`VoiceServerUpdate`]: ../model/enum.Event.html#variant.VoiceServerUpdate
@@ -886,6 +898,16 @@ impl Client {
.on_voice_server_update = Some(Arc::new(handler));
}
+ /// Attaches a handler for when a [`VoiceStateUpdate`] is received.
+ ///
+ /// [`VoiceStateUpdate`]: ../model/enum.Event.html#variant.VoiceStateUpdate
+ pub fn on_voice_state_update<F>(&mut self, handler: F)
+ where F: Fn(Context, Option<GuildId>, VoiceState) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_voice_state_update = Some(Arc::new(handler));
+ }
+
/// Attaches a handler for when a [`WebhookUpdate`] is received.
///
/// [`WebhookUpdate`]: ../model/enum.Event.html#variant.WebhookUpdate
diff --git a/src/ext/state/mod.rs b/src/ext/state/mod.rs
index 04e77d9..fa38b6f 100644
--- a/src/ext/state/mod.rs
+++ b/src/ext/state/mod.rs
@@ -1,6 +1,7 @@
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::default::Default;
+use std::mem;
use ::model::*;
/// Known state composed from received events.
@@ -35,11 +36,6 @@ impl State {
if guild.member_count > members {
total += guild.member_count - members;
- } else if guild.member_count < members {
- warn!("Inconsistent member count for {:?}: {} < {}",
- guild.id,
- guild.member_count,
- members);
}
}
@@ -130,12 +126,12 @@ impl State {
Event::CallCreate(ref event) => {
self.update_with_call_create(event);
},
- Event::CallUpdate(ref event) => {
- self.update_with_call_update(event);
- },
Event::CallDelete(ref event) => {
self.update_with_call_delete(event);
},
+ Event::CallUpdate(ref event) => {
+ self.update_with_call_update(event, false);
+ },
Event::ChannelCreate(ref event) => {
self.update_with_channel_create(event);
},
@@ -170,7 +166,7 @@ impl State {
self.update_with_guild_member_remove(event);
},
Event::GuildMemberUpdate(ref event) => {
- self.update_with_guild_member_update(event);
+ self.update_with_guild_member_update(event, false);
},
Event::GuildMembersChunk(ref event) => {
self.update_with_guild_members_chunk(event);
@@ -215,7 +211,7 @@ impl State {
self.update_with_user_note_update(event);
},
Event::UserSettingsUpdate(ref event) => {
- self.update_with_user_settings_update(event);
+ self.update_with_user_settings_update(event, false);
},
Event::UserUpdate(ref event) => {
self.update_with_user_update(event);
@@ -223,7 +219,23 @@ impl State {
Event::VoiceStateUpdate(ref event) => {
self.update_with_voice_state_update(event);
},
- _ => {},
+ Event::ChannelPinsAck(_) |
+ Event::GuildBanAdd(_) |
+ Event::GuildBanRemove(_) |
+ Event::GuildIntegrationsUpdate(_) |
+ Event::MessageAck(_) |
+ Event::MessageCreate(_) |
+ Event::MessageDelete(_) |
+ Event::MessageDeleteBulk(_) |
+ Event::MessageUpdate(_) |
+ Event::ReactionAdd(_) |
+ Event::ReactionRemove(_) |
+ Event::ReactionRemoveAll(_) |
+ Event::Resumed(_) |
+ Event::TypingStart(_) |
+ Event::VoiceServerUpdate(_) |
+ Event::WebhookUpdate(_) |
+ Event::Unknown(_) => {},
}
}
@@ -238,48 +250,78 @@ impl State {
}
}
- pub fn update_with_call_delete(&mut self, event: &CallDeleteEvent) {
- self.calls.remove(&event.channel_id);
+ pub fn update_with_call_delete(&mut self, event: &CallDeleteEvent)
+ -> Option<Call> {
+ self.calls.remove(&event.channel_id)
}
- pub fn update_with_call_update(&mut self, event: &CallUpdateEvent) {
+ pub fn update_with_call_update(&mut self, event: &CallUpdateEvent, old: bool)
+ -> Option<Call> {
+ let item = if old {
+ self.calls.get(&event.channel_id).cloned()
+ } else {
+ None
+ };
+
self.calls
.get_mut(&event.channel_id)
.map(|call| {
call.region.clone_from(&event.region);
call.ringing.clone_from(&event.ringing);
});
+
+ item
}
- pub fn update_with_channel_create(&mut self, event: &ChannelCreateEvent) {
+ pub fn update_with_channel_create(&mut self, event: &ChannelCreateEvent)
+ -> Option<Channel> {
match event.channel {
Channel::Group(ref group) => {
- self.groups.insert(group.channel_id, group.clone());
+ let ch = self.groups.insert(group.channel_id, group.clone());
+
+ ch.map(|x| Channel::Group(x))
},
Channel::Private(ref channel) => {
- self.private_channels.insert(channel.id, channel.clone());
+ let ch = self.private_channels.insert(channel.id, channel.clone());
+
+ ch.map(|x| Channel::Private(x))
},
Channel::Public(ref channel) => {
- self.guilds
+ let ch = self.guilds
.get_mut(&channel.guild_id)
- .map(|guild| guild.channels.insert(channel.id,
- channel.clone()));
+ .map(|guild| {
+ guild.channels.insert(channel.id, channel.clone())
+ });
+
+ let ch = match ch {
+ Some(Some(ch)) => Some(ch),
+ _ => None,
+ };
+
+ ch.map(|x| Channel::Public(x))
},
}
}
- pub fn update_with_channel_delete(&mut self, event: &ChannelDeleteEvent) {
+ pub fn update_with_channel_delete(&mut self, event: &ChannelDeleteEvent)
+ -> Option<Channel> {
match event.channel {
Channel::Group(ref group) => {
- self.groups.remove(&group.channel_id);
+ self.groups.remove(&group.channel_id).map(|x| Channel::Group(x))
},
Channel::Private(ref channel) => {
- self.private_channels.remove(&channel.id);
+ self.private_channels.remove(&channel.id)
+ .map(|private| Channel::Private(private))
},
Channel::Public(ref channel) => {
- self.guilds
+ let ch = self.guilds
.get_mut(&channel.guild_id)
.map(|guild| guild.channels.remove(&channel.id));
+
+ match ch {
+ Some(Some(ch)) => Some(Channel::Public(ch)),
+ _ => None,
+ }
},
}
}
@@ -335,10 +377,12 @@ impl State {
},
Entry::Occupied(mut e) => {
let dest = e.get_mut();
+
if group.recipients.is_empty() {
- // if the update omits the recipient list, preserve it
- let recipients = ::std::mem::replace(&mut dest.recipients, HashMap::new());
+ let recipients = mem::replace(&mut dest.recipients, HashMap::new());
+
dest.clone_from(group);
+
dest.recipients = recipients;
} else {
dest.clone_from(group);
@@ -349,7 +393,7 @@ impl State {
Channel::Private(ref channel) => {
self.private_channels
.get_mut(&channel.id)
- .map(|chan| chan.clone_from(channel));
+ .map(|private| private.clone_from(channel));
},
Channel::Public(ref channel) => {
self.guilds
@@ -364,8 +408,9 @@ impl State {
self.guilds.insert(event.guild.id, event.guild.clone());
}
- pub fn update_with_guild_delete(&mut self, event: &GuildDeleteEvent) {
- self.guilds.remove(&event.guild.id);
+ pub fn update_with_guild_delete(&mut self, event: &GuildDeleteEvent)
+ -> Option<LiveGuild> {
+ self.guilds.remove(&event.guild.id)
}
pub fn update_with_guild_emojis_update(&mut self,
@@ -387,41 +432,58 @@ impl State {
}
pub fn update_with_guild_member_remove(&mut self,
- event: &GuildMemberRemoveEvent) {
- self.guilds
+ event: &GuildMemberRemoveEvent)
+ -> Option<Member> {
+ let member = self.guilds
.get_mut(&event.guild_id)
.map(|guild| {
guild.member_count -= 1;
- guild.members.remove(&event.user.id);
+ guild.members.remove(&event.user.id)
});
+
+ match member {
+ Some(Some(member)) => Some(member),
+ _ => None,
+ }
}
pub fn update_with_guild_member_update(&mut self,
- event: &GuildMemberUpdateEvent) {
- self.guilds
- .get_mut(&event.guild_id)
- .map(|guild| {
- let mut found = false;
-
- if let Some(member) = guild.members.get_mut(&event.user.id) {
- member.nick.clone_from(&event.nick);
- member.roles.clone_from(&event.roles);
- member.user.clone_from(&event.user);
-
- found = true;
- }
+ event: &GuildMemberUpdateEvent,
+ old: bool)
+ -> Option<Member> {
+
+ if let Some(guild) = self.guilds.get_mut(&event.guild_id) {
+ let mut found = false;
+
+ let item = if let Some(member) = guild.members.get_mut(&event.user.id) {
+ let item = Some(member.clone());
+
+ member.nick.clone_from(&event.nick);
+ member.roles.clone_from(&event.roles);
+ member.user.clone_from(&event.user);
+
+ found = true;
+
+ item
+ } else {
+ None
+ };
+
+ if !found {
+ guild.members.insert(event.user.id, Member {
+ deaf: false,
+ joined_at: String::default(),
+ mute: false,
+ nick: event.nick.clone(),
+ roles: event.roles.clone(),
+ user: event.user.clone(),
+ });
+ }
- if !found {
- guild.members.insert(event.user.id, Member {
- deaf: false,
- joined_at: String::default(),
- mute: false,
- nick: event.nick.clone(),
- roles: event.roles.clone(),
- user: event.user.clone(),
- });
- }
- });
+ item
+ } else {
+ None
+ }
}
pub fn update_with_guild_members_chunk(&mut self,
@@ -439,19 +501,31 @@ impl State {
}
pub fn update_with_guild_role_delete(&mut self,
- event: &GuildRoleDeleteEvent) {
- self.guilds
+ event: &GuildRoleDeleteEvent)
+ -> Option<Role> {
+ let role = self.guilds
.get_mut(&event.guild_id)
.map(|guild| guild.roles.remove(&event.role_id));
+
+ match role {
+ Some(Some(x)) => Some(x),
+ _ => None,
+ }
}
pub fn update_with_guild_role_update(&mut self,
- event: &GuildRoleUpdateEvent) {
- self.guilds
+ event: &GuildRoleUpdateEvent)
+ -> Option<Role> {
+ let item = self.guilds
.get_mut(&event.guild_id)
.map(|guild| guild.roles
.get_mut(&event.role.id)
- .map(|role| role.clone_from(&event.role)));
+ .map(|role| mem::replace(role, event.role.clone())));
+
+ match item {
+ Some(Some(x)) => Some(x),
+ _ => None,
+ }
}
pub fn update_with_guild_sync(&mut self, event: &GuildSyncEvent) {
@@ -475,7 +549,6 @@ impl State {
self.guilds
.get_mut(&event.guild.id)
.map(|guild| {
- // todo: embed
guild.afk_timeout = event.guild.afk_timeout;
guild.afk_channel_id.clone_from(&event.guild.afk_channel_id);
guild.icon.clone_from(&event.guild.icon);
@@ -574,23 +647,32 @@ impl State {
}
pub fn update_with_user_guild_settings_update(&mut self,
- event: &UserGuildSettingsUpdateEvent) {
+ event: &UserGuildSettingsUpdateEvent)
+ -> Option<UserGuildSettings> {
self.guild_settings
.get_mut(&event.settings.guild_id)
- .map(|guild_setting| guild_setting.clone_from(&event.settings));
+ .map(|guild_setting| mem::replace(guild_setting, event.settings.clone()))
}
pub fn update_with_user_note_update(&mut self,
- event: &UserNoteUpdateEvent) {
+ event: &UserNoteUpdateEvent)
+ -> Option<String> {
if event.note.is_empty() {
- self.notes.remove(&event.user_id);
+ self.notes.remove(&event.user_id)
} else {
- self.notes.insert(event.user_id, event.note.clone());
+ self.notes.insert(event.user_id, event.note.clone())
}
}
pub fn update_with_user_settings_update(&mut self,
- event: &UserSettingsUpdateEvent) {
+ event: &UserSettingsUpdateEvent,
+ old: bool)
+ -> Option<UserSettings> {
+ let item = match old {
+ true => self.settings.clone(),
+ false => None,
+ };
+
self.settings
.as_mut()
.map(|settings| {
@@ -605,10 +687,13 @@ impl State {
opt_modify(&mut settings.convert_emoticons, &event.convert_emoticons);
opt_modify(&mut settings.friend_source_flags, &event.friend_source_flags);
});
+
+ item
}
- pub fn update_with_user_update(&mut self, event: &UserUpdateEvent) {
- self.user = event.current_user.clone();
+ pub fn update_with_user_update(&mut self, event: &UserUpdateEvent)
+ -> CurrentUser {
+ mem::replace(&mut self.user, event.current_user.clone())
}
pub fn update_with_voice_state_update(&mut self,