aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-15 11:36:53 -0800
committerAustin Hellyer <[email protected]>2016-11-15 11:36:53 -0800
commit5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4 (patch)
tree7cf531e4790109d6d7edd26bc5b483378d5ba5ac /src
parentEmbed Author: everything but 'name' is optional (diff)
downloadserenity-5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4.tar.xz
serenity-5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4.zip
Add state/framework/etc. conditional compile flags
This adds conditional compilation for the following features, in addition to the voice conditional compilation flag: - extras (message builder) - framework - methods - state These 4 are enabled _by default_, while the `voice` feature flag is disabled. Disabling the state will allow incredibly low-memory bots.
Diffstat (limited to 'src')
-rw-r--r--src/client/connection.rs19
-rw-r--r--src/client/context.rs27
-rw-r--r--src/client/dispatch.rs430
-rw-r--r--src/client/event_store.rs27
-rw-r--r--src/client/mod.rs398
-rw-r--r--src/ext/mod.rs9
-rw-r--r--src/ext/state/mod.rs6
-rw-r--r--src/model/channel.rs68
-rw-r--r--src/model/gateway.rs4
-rw-r--r--src/model/guild.rs51
-rw-r--r--src/model/id.rs11
-rw-r--r--src/model/invite.rs4
-rw-r--r--src/model/misc.rs1
-rw-r--r--src/model/mod.rs10
-rw-r--r--src/model/permissions.rs3
-rw-r--r--src/model/user.rs25
-rw-r--r--src/model/utils.rs8
-rw-r--r--src/model/webhook.rs4
-rw-r--r--src/utils/builder/edit_role.rs14
-rw-r--r--src/utils/macros.rs300
-rw-r--r--src/utils/mod.rs90
21 files changed, 1096 insertions, 413 deletions
diff --git a/src/client/connection.rs b/src/client/connection.rs
index d1e37e5..4862667 100644
--- a/src/client/connection.rs
+++ b/src/client/connection.rs
@@ -36,25 +36,6 @@ use ::model::{
#[cfg(feature="voice")]
use ::ext::voice::Manager as VoiceManager;
-#[cfg(feature="voice")]
-macro_rules! connection {
- ($($name1:ident: $val1:expr),*; $($name2:ident: $val2:expr,)*) => {
- Connection {
- $($name1: $val1,)*
- $($name2: $val2,)*
- }
- }
-}
-
-#[cfg(not(feature="voice"))]
-macro_rules! connection {
- ($($name1:ident: $val1:expr),*; $($name2:ident: $val2:expr,)*) => {
- Connection {
- $($name1: $val1,)*
- }
- }
-}
-
#[doc(hidden)]
pub enum Status {
SendMessage(Value),
diff --git a/src/client/context.rs b/src/client/context.rs
index 0507bc3..6443efa 100644
--- a/src/client/context.rs
+++ b/src/client/context.rs
@@ -3,7 +3,7 @@ use std::collections::HashMap;
use std::io::Read;
use std::sync::{Arc, Mutex};
use super::connection::Connection;
-use super::{STATE, http};
+use super::http;
use super::login_type::LoginType;
use ::utils::builder::{
CreateInvite,
@@ -19,6 +19,9 @@ use ::internal::prelude::*;
use ::model::*;
use ::utils;
+#[cfg(feature = "state")]
+use super::STATE;
+
#[derive(Clone)]
pub struct Context {
channel_id: Option<ChannelId>,
@@ -553,7 +556,7 @@ impl Context {
let guild_id = guild_id.into();
let role_id = role_id.into();
- let map = {
+ let map = feature_state! {{
let state = STATE.lock().unwrap();
let role = if let Some(role) = {
@@ -565,7 +568,9 @@ impl Context {
};
f(EditRole::new(role)).0.build()
- };
+ } else {
+ f(EditRole::default()).0.build()
+ }};
http::edit_role(guild_id.0, role_id.0, map)
}
@@ -601,9 +606,11 @@ impl Context {
where C: Into<ChannelId> {
let channel_id = channel_id.into();
- if let Some(channel) = STATE.lock().unwrap().find_channel(channel_id) {
- return Ok(channel.clone())
- }
+ feature_state_enabled! {{
+ if let Some(channel) = STATE.lock().unwrap().find_channel(channel_id) {
+ return Ok(channel.clone())
+ }
+ }}
http::get_channel(channel_id.0)
}
@@ -612,13 +619,13 @@ impl Context {
-> Result<HashMap<ChannelId, PublicChannel>> where G: Into<GuildId> {
let guild_id = guild_id.into();
- {
+ feature_state_enabled! {{
let state = STATE.lock().unwrap();
if let Some(guild) = state.find_guild(guild_id) {
return Ok(guild.channels.clone());
}
- }
+ }}
let mut channels = HashMap::new();
@@ -677,13 +684,13 @@ impl Context {
let guild_id = guild_id.into();
let user_id = user_id.into();
- {
+ feature_state_enabled! {{
let state = STATE.lock().unwrap();
if let Some(member) = state.find_member(guild_id, user_id) {
return Ok(member.clone());
}
- }
+ }}
http::get_member(guild_id.0, user_id.0)
}
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs
index 6295bc9..fa41ddc 100644
--- a/src/client/dispatch.rs
+++ b/src/client/dispatch.rs
@@ -2,11 +2,16 @@ use std::sync::{Arc, Mutex};
use std::thread;
use super::event_store::EventStore;
use super::login_type::LoginType;
-use super::{STATE, Connection, Context};
-use ::ext::framework::Framework;
+use super::{Connection, Context};
use ::internal::prelude::*;
use ::model::{ChannelId, Event, Message};
+#[cfg(feature="framework")]
+use ::ext::framework::Framework;
+
+#[cfg(feature = "state")]
+use super::STATE;
+
macro_rules! handler {
($field:ident, $event_store:ident) => {
$event_store.lock()
@@ -19,10 +24,14 @@ macro_rules! handler {
macro_rules! update {
($method:ident, $event:expr) => {
- STATE.lock().unwrap().$method(&$event);
+ feature_state_enabled! {{
+ STATE.lock().unwrap().$method(&$event)
+ }}
};
($method:ident, $event:expr, $old:expr) => {
- STATE.lock().unwrap().$method(&$event, $old);
+ feature_state_enabled! {{
+ STATE.lock().unwrap().$method(&$event, $old)
+ }}
};
}
@@ -32,14 +41,72 @@ fn context(channel_id: Option<ChannelId>,
Context::new(channel_id, conn, login_type)
}
-#[allow(cyclomatic_complexity)]
+#[cfg(feature="framework")]
pub fn dispatch(event: Result<Event>,
conn: Arc<Mutex<Connection>>,
framework: Arc<Mutex<Framework>>,
login_type: LoginType,
event_store: Arc<Mutex<EventStore>>) {
match event {
- Ok(Event::CallCreate(event)) => {
+ Ok(Event::MessageCreate(event)) => {
+ let context = context(Some(event.message.channel_id),
+ conn,
+ login_type);
+ let mut framework = framework.lock().expect("framework poisoned");
+
+ if framework.initialized {
+ dispatch_message(context.clone(),
+ event.message.clone(),
+ event_store);
+
+ framework.dispatch(context, event.message);
+ } else {
+ dispatch_message(context, event.message, event_store);
+ }
+ },
+ Ok(other) => handle_event(other, conn, login_type, event_store),
+ Err(_why) => {},
+ }
+}
+
+#[cfg(not(feature="framework"))]
+pub fn dispatch(event: Result<Event>,
+ conn: Arc<Mutex<Connection>>,
+ login_type: LoginType,
+ event_store: Arc<Mutex<EventStore>>) {
+ match event {
+ Ok(Event::MessageCreate(event)) => {
+ let context = context(Some(event.message.channel_id),
+ conn,
+ login_type);
+ dispatch_message(context.clone(),
+ event.message.clone(),
+ event_store);
+ },
+ Ok(other) => handle_event(other, conn, login_type, event_store),
+ Err(_why) => {},
+ }
+}
+
+fn dispatch_message(context: Context,
+ message: Message,
+ event_store: Arc<Mutex<EventStore>>) {
+ if let Some(ref handler) = handler!(on_message, event_store) {
+ let handler = handler.clone();
+
+ thread::spawn(move || {
+ (handler)(context, message);
+ });
+ }
+}
+
+#[allow(cyclomatic_complexity)]
+fn handle_event(event: Event,
+ conn: Arc<Mutex<Connection>>,
+ login_type: LoginType,
+ event_store: Arc<Mutex<EventStore>>) {
+ match event {
+ Event::CallCreate(event) => {
if let Some(ref handler) = handler!(on_call_create, event_store) {
update!(update_with_call_create, event);
@@ -53,7 +120,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_call_create, event);
}
},
- Ok(Event::CallDelete(event)) => {
+ Event::CallDelete(event) => {
if let Some(ref handler) = handler!(on_call_delete, event_store) {
let call = STATE
.lock()
@@ -72,27 +139,35 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_call_delete, event);
}
},
- Ok(Event::CallUpdate(event)) => {
+ Event::CallUpdate(event) => {
if let Some(ref handler) = handler!(on_call_update, event_store) {
- let before = update!(update_with_call_update, event, true);
- let after = STATE
- .lock()
- .unwrap()
- .calls
- .get(&event.channel_id)
- .cloned();
-
let context = context(None, conn, login_type);
let handler = handler.clone();
- thread::spawn(move || {
- (handler)(context, before, after);
- });
+ feature_state! {{
+ let before = update!(update_with_call_update, event, true);
+ let after = STATE
+ .lock()
+ .unwrap()
+ .calls
+ .get(&event.channel_id)
+ .cloned();
+
+ thread::spawn(move || {
+ (handler)(context, before, after);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event);
+ });
+ }}
} else {
- update!(update_with_call_update, event, false);
+ feature_state_enabled! {{
+ update!(update_with_call_update, event, false);
+ }}
}
},
- Ok(Event::ChannelCreate(event)) => {
+ Event::ChannelCreate(event) => {
if let Some(ref handler) = handler!(on_channel_create, event_store) {
update!(update_with_channel_create, event);
let context = context(Some(event.channel.id()),
@@ -107,7 +182,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_channel_create, event);
}
},
- Ok(Event::ChannelDelete(event)) => {
+ Event::ChannelDelete(event) => {
if let Some(ref handler) = handler!(on_channel_delete, event_store) {
update!(update_with_channel_delete, event);
let context = context(None, conn, login_type);
@@ -120,7 +195,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_channel_delete, event);
}
},
- Ok(Event::ChannelPinsAck(event)) => {
+ Event::ChannelPinsAck(event) => {
if let Some(ref handler) = handler!(on_channel_pins_ack, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -132,7 +207,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ChannelPinsUpdate(event)) => {
+ Event::ChannelPinsUpdate(event) => {
if let Some(ref handler) = handler!(on_channel_pins_update, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -144,7 +219,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ChannelRecipientAdd(event)) => {
+ Event::ChannelRecipientAdd(event) => {
update!(update_with_channel_recipient_add, event);
if let Some(ref handler) = handler!(on_channel_recipient_addition, event_store) {
@@ -158,7 +233,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ChannelRecipientRemove(event)) => {
+ Event::ChannelRecipientRemove(event) => {
update!(update_with_channel_recipient_remove, event);
if let Some(ref handler) = handler!(on_channel_recipient_removal, event_store) {
@@ -172,7 +247,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ChannelUpdate(event)) => {
+ Event::ChannelUpdate(event) => {
if let Some(ref handler) = handler!(on_channel_update, event_store) {
let before = STATE.lock()
.unwrap()
@@ -190,7 +265,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_channel_update, event);
}
},
- Ok(Event::GuildBanAdd(event)) => {
+ Event::GuildBanAdd(event) => {
if let Some(ref handler) = handler!(on_guild_ban_addition, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -200,7 +275,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildBanRemove(event)) => {
+ Event::GuildBanRemove(event) => {
if let Some(ref handler) = handler!(on_guild_ban_removal, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -210,7 +285,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildCreate(event)) => {
+ Event::GuildCreate(event) => {
update!(update_with_guild_create, event);
if let Some(ref handler) = handler!(on_guild_create, event_store) {
@@ -222,20 +297,29 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildDelete(event)) => {
+ Event::GuildDelete(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, full);
- });
+ feature_state! {{
+ let full = update!(update_with_guild_delete, event);
+
+ thread::spawn(move || {
+ (handler)(context, event.guild, full);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.guild);
+ });
+ }}
} else {
- let _full = update!(update_with_guild_delete, event);
+ feature_state_enabled! {{
+ let _full = update!(update_with_guild_delete, event);
+ }}
}
},
- Ok(Event::GuildEmojisUpdate(event)) => {
+ Event::GuildEmojisUpdate(event) => {
update!(update_with_guild_emojis_update, event);
if let Some(ref handler) = handler!(on_guild_emojis_update, event_store) {
@@ -247,7 +331,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildIntegrationsUpdate(event)) => {
+ Event::GuildIntegrationsUpdate(event) => {
if let Some(ref handler) = handler!(on_guild_integrations_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -257,7 +341,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildMemberAdd(event)) => {
+ Event::GuildMemberAdd(event) => {
update!(update_with_guild_member_add, event);
if let Some(ref handler) = handler!(on_guild_member_addition, event_store) {
@@ -269,42 +353,58 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildMemberRemove(event)) => {
+ Event::GuildMemberRemove(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, member);
- });
+ feature_state! {{
+ let member = update!(update_with_guild_member_remove, event);
+
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, event.user, member);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, event.user);
+ });
+ }}
} else {
- let _member = update!(update_with_guild_member_remove, event);
+ feature_state_enabled! {{
+ let _member = update!(update_with_guild_member_remove, event);
+ }}
}
},
- Ok(Event::GuildMemberUpdate(event)) => {
+ Event::GuildMemberUpdate(event) => {
if let Some(ref handler) = handler!(on_guild_member_update, event_store) {
- 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
- // could fail under any circumstance.
- let after = STATE.lock()
- .unwrap()
- .find_member(event.guild_id, event.user.id)
- .unwrap()
- .clone();
let context = context(None, conn, login_type);
let handler = handler.clone();
- thread::spawn(move || {
- (handler)(context, before, after);
- });
+ feature_state! {{
+ let before = update!(update_with_guild_member_update, event);
+
+ // This is safe, as the update would have created the member
+ // if it did not exist. Thus, there _should_ be no way that this
+ // could fail under any circumstance.
+ let after = STATE.lock()
+ .unwrap()
+ .find_member(event.guild_id, event.user.id)
+ .unwrap()
+ .clone();
+
+ thread::spawn(move || {
+ (handler)(context, before, after);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event);
+ });
+ }}
} else {
- let _ = update!(update_with_guild_member_update, event, false);
+ let _ = update!(update_with_guild_member_update, event);
}
},
- Ok(Event::GuildMembersChunk(event)) => {
+ Event::GuildMembersChunk(event) => {
update!(update_with_guild_members_chunk, event);
if let Some(ref handler) = handler!(on_guild_members_chunk, event_store) {
@@ -316,7 +416,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildRoleCreate(event)) => {
+ Event::GuildRoleCreate(event) => {
update!(update_with_guild_role_create, event);
if let Some(ref handler) = handler!(on_guild_role_create, event_store) {
@@ -328,30 +428,51 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildRoleDelete(event)) => {
+ Event::GuildRoleDelete(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, role);
- });
+ feature_state! {{
+ let role = update!(update_with_guild_role_delete, event);
+
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, event.role_id, role);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, event.role_id);
+ });
+ }}
+ } else {
+ feature_state_enabled! {{
+ let _role = update!(update_with_guild_role_delete, event);
+ }}
}
},
- Ok(Event::GuildRoleUpdate(event)) => {
- let before = update!(update_with_guild_role_update, event);
-
+ Event::GuildRoleUpdate(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, before, event.role);
- });
+ feature_state! {{
+ let before = update!(update_with_guild_role_update, event);
+
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, before, event.role);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.guild_id, event.role);
+ });
+ }}
+ } else {
+ feature_state_enabled! {{
+ let _before = update!(update_with_guild_role_update, event);
+ }}
}
},
- Ok(Event::GuildSync(event)) => {
+ Event::GuildSync(event) => {
if let Some(ref handler) = handler!(on_guild_sync, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -361,7 +482,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildUnavailable(event)) => {
+ Event::GuildUnavailable(event) => {
update!(update_with_guild_unavailable, event);
if let Some(ref handler) = handler!(on_guild_unavailable, event_store) {
@@ -373,7 +494,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::GuildUpdate(event)) => {
+ Event::GuildUpdate(event) => {
if let Some(ref handler) = handler!(on_guild_update, event_store) {
let before = STATE.lock()
.unwrap()
@@ -391,7 +512,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_guild_update, event);
}
}
- Ok(Event::MessageAck(event)) => {
+ Event::MessageAck(event) => {
if let Some(ref handler) = handler!(on_message_ack, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -403,23 +524,9 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::MessageCreate(event)) => {
- let context = context(Some(event.message.channel_id),
- conn,
- login_type);
- let mut framework = framework.lock().expect("framework poisoned");
-
- if framework.initialized {
- dispatch_message(context.clone(),
- event.message.clone(),
- event_store);
-
- framework.dispatch(context, event.message);
- } else {
- dispatch_message(context, event.message, event_store);
- }
- },
- Ok(Event::MessageDeleteBulk(event)) => {
+ // Already handled by the framework check macro
+ Event::MessageCreate(_event) => {},
+ Event::MessageDeleteBulk(event) => {
if let Some(ref handler) = handler!(on_message_delete_bulk, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -431,7 +538,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::MessageDelete(event)) => {
+ Event::MessageDelete(event) => {
if let Some(ref handler) = handler!(on_message_delete, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -443,7 +550,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::MessageUpdate(event)) => {
+ Event::MessageUpdate(event) => {
if let Some(ref handler) = handler!(on_message_update, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -455,7 +562,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::PresencesReplace(event)) => {
+ Event::PresencesReplace(event) => {
update!(update_with_presences_replace, event);
if let Some(handler) = handler!(on_presence_replace, event_store) {
@@ -467,7 +574,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::PresenceUpdate(event)) => {
+ Event::PresenceUpdate(event) => {
update!(update_with_presence_update, event);
if let Some(handler) = handler!(on_presence_update, event_store) {
@@ -479,7 +586,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ReactionAdd(event)) => {
+ Event::ReactionAdd(event) => {
if let Some(ref handler) = handler!(on_reaction_add, event_store) {
let context = context(Some(event.reaction.channel_id),
conn,
@@ -491,7 +598,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ReactionRemove(event)) => {
+ Event::ReactionRemove(event) => {
if let Some(ref handler) = handler!(on_reaction_remove, event_store) {
let context = context(Some(event.reaction.channel_id),
conn,
@@ -503,7 +610,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::ReactionRemoveAll(event)) => {
+ Event::ReactionRemoveAll(event) => {
if let Some(ref handler) = handler!(on_reaction_remove_all, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -515,7 +622,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::Ready(event)) => {
+ Event::Ready(event) => {
if let Some(ref handler) = handler!(on_ready, event_store) {
update!(update_with_ready, event);
@@ -529,7 +636,7 @@ pub fn dispatch(event: Result<Event>,
update!(update_with_ready, event);
}
},
- Ok(Event::RelationshipAdd(event)) => {
+ Event::RelationshipAdd(event) => {
update!(update_with_relationship_add, event);
if let Some(ref handler) = handler!(on_relationship_addition, event_store) {
@@ -541,7 +648,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::RelationshipRemove(event)) => {
+ Event::RelationshipRemove(event) => {
update!(update_with_relationship_remove, event);
if let Some(ref handler) = handler!(on_relationship_removal, event_store) {
@@ -553,7 +660,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::Resumed(event)) => {
+ Event::Resumed(event) => {
if let Some(ref handler) = handler!(on_resume, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -563,7 +670,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::TypingStart(event)) => {
+ Event::TypingStart(event) => {
if let Some(ref handler) = handler!(on_typing_start, event_store) {
let context = context(Some(event.channel_id),
conn,
@@ -575,7 +682,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::Unknown(event)) => {
+ Event::Unknown(event) => {
if let Some(ref handler) = handler!(on_unknown, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -585,58 +692,96 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::UserGuildSettingsUpdate(event)) => {
- let before = update!(update_with_user_guild_settings_update, event);
-
+ Event::UserGuildSettingsUpdate(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();
- thread::spawn(move || {
- (handler)(context, before, event.settings);
- });
+ feature_state! {{
+ let before = update!(update_with_user_guild_settings_update, event);
+
+ thread::spawn(move || {
+ (handler)(context, before, event.settings);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.settings);
+ });
+ }}
+ } else {
+ feature_state_enabled! {{
+ let _before = update!(update_with_user_guild_settings_update, event);
+ }}
}
},
- Ok(Event::UserNoteUpdate(event)) => {
- let before = update!(update_with_user_note_update, event);
-
+ Event::UserNoteUpdate(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, before, event.note);
- });
+ feature_state! {{
+ let before = update!(update_with_user_note_update, event);
+
+ thread::spawn(move || {
+ (handler)(context, event.user_id, before, event.note);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.user_id, event.note);
+ });
+ }}
+ } else {
+ feature_state_enabled! {{
+ let _before = update!(update_with_user_note_update, event);
+ }}
}
},
- Ok(Event::UserSettingsUpdate(event)) => {
+ Event::UserSettingsUpdate(event) => {
if let Some(ref handler) = handler!(on_user_settings_update, event_store) {
- let before = update!(update_with_user_settings_update, event, true);
- let after = STATE.lock().unwrap().settings.clone();
-
let context = context(None, conn, login_type);
let handler = handler.clone();
- thread::spawn(move || {
- (handler)(context, before.unwrap(), after.unwrap());
- });
+ feature_state! {{
+ let before = update!(update_with_user_settings_update, event, true);
+ let after = STATE.lock().unwrap().settings.clone();
+
+ thread::spawn(move || {
+ (handler)(context, before.unwrap(), after.unwrap());
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event);
+ });
+ }}
} else {
- update!(update_with_user_settings_update, event, false);
+ feature_state_enabled! {{
+ update!(update_with_user_settings_update, event, false);
+ }}
}
},
- Ok(Event::UserUpdate(event)) => {
- let before = update!(update_with_user_update, event);
-
+ Event::UserUpdate(event) => {
if let Some(ref handler) = handler!(on_user_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
- thread::spawn(move || {
- (handler)(context, before, event.current_user);
- });
+ feature_state! {{
+ let before = update!(update_with_user_update, event);
+
+ thread::spawn(move || {
+ (handler)(context, before, event.current_user);
+ });
+ } else {
+ thread::spawn(move || {
+ (handler)(context, event.current_user);
+ });
+ }}
+ } else {
+ feature_state_enabled! {{
+ let _before = update!(update_with_user_update, event);
+ }}
}
},
- Ok(Event::VoiceServerUpdate(event)) => {
+ Event::VoiceServerUpdate(event) => {
if let Some(ref handler) = handler!(on_voice_server_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -646,7 +791,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::VoiceStateUpdate(event)) => {
+ Event::VoiceStateUpdate(event) => {
update!(update_with_voice_state_update, event);
if let Some(ref handler) = handler!(on_voice_state_update, event_store) {
@@ -658,7 +803,7 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Ok(Event::WebhookUpdate(event)) => {
+ Event::WebhookUpdate(event) => {
if let Some(ref handler) = handler!(on_webhook_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -668,18 +813,5 @@ pub fn dispatch(event: Result<Event>,
});
}
},
- Err(_why) => {},
- }
-}
-
-fn dispatch_message(context: Context,
- message: Message,
- event_store: Arc<Mutex<EventStore>>) {
- if let Some(ref handler) = handler!(on_message, event_store) {
- let handler = handler.clone();
-
- thread::spawn(move || {
- (handler)(context, message);
- });
}
}
diff --git a/src/client/event_store.rs b/src/client/event_store.rs
index 387f9e7..98d874b 100644
--- a/src/client/event_store.rs
+++ b/src/client/event_store.rs
@@ -27,7 +27,10 @@ use ::model::*;
pub struct EventStore {
pub on_call_create: Option<Arc<Fn(Context, Call) + Send + Sync + 'static>>,
pub on_call_delete: Option<Arc<Fn(Context, Option<Call>) + Send + Sync + 'static>>,
+ #[cfg(feature = "state")]
pub on_call_update: Option<Arc<Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_call_update: Option<Arc<Fn(Context, CallUpdateEvent) + Send + Sync + 'static>>,
pub on_channel_create: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>,
pub on_channel_delete: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>,
pub on_channel_pins_ack: Option<Arc<Fn(Context, ChannelPinsAckEvent) + Send + Sync + 'static>>,
@@ -38,16 +41,31 @@ 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>>,
+ #[cfg(feature = "state")]
pub on_guild_delete: Option<Arc<Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_guild_delete: Option<Arc<Fn(Context, Guild) + 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>>,
+ #[cfg(feature = "state")]
pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>,
+ #[cfg(feature = "state")]
pub on_guild_member_update: Option<Arc<Fn(Context, Option<Member>, Member) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_guild_member_update: Option<Arc<Fn(Context, GuildMemberUpdateEvent) + 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>>,
+ #[cfg(feature = "state")]
pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId) + Send + Sync + 'static>>,
+ #[cfg(feature = "state")]
pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, 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 +77,10 @@ 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>>,
+ #[cfg(feature = "state")]
pub on_note_update: Option<Arc<Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_note_update: Option<Arc<Fn(Context, UserId, 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>>,
@@ -69,8 +90,14 @@ pub struct EventStore {
pub on_typing_start: Option<Arc<Fn(Context, TypingStartEvent) + Send + Sync + 'static>>,
pub on_unknown: Option<Arc<Fn(Context, String, BTreeMap<String, Value>) + Send + Sync + 'static>>,
pub on_user_guild_settings_update: Option<Arc<Fn(Context, Option<UserGuildSettings>, UserGuildSettings) + Send + Sync + 'static>>,
+ #[cfg(feature = "state")]
pub on_user_update: Option<Arc<Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_user_update: Option<Arc<Fn(Context, CurrentUser) + Send + Sync + 'static>>,
+ #[cfg(feature = "state")]
pub on_user_settings_update: Option<Arc<Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static>>,
+ #[cfg(not(feature = "state"))]
+ pub on_user_settings_update: Option<Arc<Fn(Context, UserSettingsUpdateEvent) + 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 f270b31..77f1086 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -57,11 +57,16 @@ use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
-use ::ext::framework::Framework;
-use ::ext::state::State;
use ::internal::prelude::*;
use ::model::*;
+#[cfg(feature = "framework")]
+use ::ext::framework::Framework;
+
+#[cfg(feature = "state")]
+use ::ext::state::State;
+
+#[cfg(feature = "state")]
lazy_static! {
/// The STATE is a mutable lazily-initialized static binding. It can be
/// accessed across any function and in any context.
@@ -220,6 +225,7 @@ pub enum ClientError {
pub struct Client {
pub connections: Vec<Arc<Mutex<Connection>>>,
event_store: Arc<Mutex<EventStore>>,
+ #[cfg(feature="framework")]
framework: Arc<Mutex<Framework>>,
login_type: LoginType,
token: String,
@@ -271,6 +277,7 @@ impl Client {
///
/// [`on_message`]: #method.on_message
/// [framework docs]: ../ext/framework/index.html
+ #[cfg(feature="framework")]
pub fn with_framework<F>(&mut self, f: F)
where F: FnOnce(Framework) -> Framework + Send + Sync + 'static {
self.framework = Arc::new(Mutex::new(f(Framework::default())));
@@ -403,16 +410,6 @@ impl Client {
.on_call_delete = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`CallUpdate`] is received.
- ///
- /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate
- pub fn on_call_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_call_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`ChannelCreate`] is received.
///
/// [`ChannelCreate`]: ../model/enum.Event.html#variant.ChannelCreate
@@ -473,26 +470,6 @@ impl Client {
.on_guild_create = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`GuilDelete`] is received.
- ///
- /// 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, Option<LiveGuild>) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_guild_delete = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`GuildEmojisUpdate`] is received.
///
/// The `HashMap` of emojis is the new full list of emojis.
@@ -525,29 +502,6 @@ impl Client {
.on_guild_member_addition = Some(Arc::new(handler));
}
- /// 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, Option<Member>) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_guild_member_removal = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberUpdate`] is received.
- ///
- /// [`GuildMemberUpdate`]: ../model/enum.Event.html#variant.GuildMemberUpdate
- pub fn on_guild_member_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<Member>, Member) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_guild_member_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`GuildMembersChunk`] is received.
///
/// [`GuildMembersChunk`]: ../model/enum.Event.html#variant.GuildMembersChunk
@@ -568,16 +522,6 @@ impl Client {
.on_guild_role_create = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`GuildRoleDelete`] is received.
- ///
- /// [`GuildRoleDelete`]: ../model/enum.Event.html#variant.GuildRoleDelete
- pub fn on_guild_role_delete<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_guild_role_delete = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`GuildRoleUpdate`] is received.
///
/// The optional `Role` is the role prior to updating. This can be `None` if
@@ -693,19 +637,6 @@ impl Client {
.on_message_update = Some(Arc::new(handler));
}
- /// 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, Option<String>, String) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_note_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`PresencesReplace`] is received.
///
/// [`PresencesReplace`]: ../model/enum.Event.html#variant.PresencesReplace
@@ -733,7 +664,7 @@ impl Client {
where F: Fn(Context, Reaction) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
- .on_reaction_add = Some(Arc::new(handler))
+ .on_reaction_add = Some(Arc::new(handler));
}
/// Attached a handler for when a [`ReactionRemove`] is received.
@@ -743,7 +674,7 @@ impl Client {
where F: Fn(Context, Reaction) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
- .on_reaction_remove = Some(Arc::new(handler))
+ .on_reaction_remove = Some(Arc::new(handler));
}
/// Attached a handler for when a [`ReactionRemoveAll`] is received.
@@ -753,7 +684,7 @@ impl Client {
where F: Fn(Context, ChannelId, MessageId) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
- .on_reaction_remove_all = Some(Arc::new(handler))
+ .on_reaction_remove_all = Some(Arc::new(handler));
}
/// Register an event to be called whenever a Ready event is received.
@@ -868,26 +799,6 @@ impl Client {
.on_user_guild_settings_update = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`UserUpdate`] is received.
- ///
- /// [`UserUpdate`]: ../model/enum.Event.html#variant.UserUpdate
- pub fn on_user_update<F>(&mut self, handler: F)
- where F: Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_user_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`UserSettingsUpdate`] is received.
- ///
- /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate
- pub fn on_user_settings_update<F>(&mut self, handler: F)
- where F: Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_user_settings_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`VoiceServerUpdate`] is received.
///
/// [`VoiceServerUpdate`]: ../model/enum.Event.html#variant.VoiceServerUpdate
@@ -936,28 +847,47 @@ impl Client {
Ok((connection, ready)) => {
self.connections.push(Arc::new(Mutex::new(connection)));
- STATE.lock()
- .unwrap()
- .update_with_ready(&ready);
+ feature_state_enabled! {{
+ STATE.lock()
+ .unwrap()
+ .update_with_ready(&ready);
+ }}
match self.connections.last() {
Some(connection) => {
- dispatch(Ok(Event::Ready(ready)),
- connection.clone(),
- self.framework.clone(),
- self.login_type,
- self.event_store.clone());
+ feature_framework! {{
+ dispatch(Ok(Event::Ready(ready)),
+ connection.clone(),
+ self.framework.clone(),
+ self.login_type,
+ self.event_store.clone());
+ } {
+ dispatch(Ok(Event::Ready(ready)),
+ connection.clone(),
+ self.login_type,
+ self.event_store.clone());
+ }}
let connection_clone = connection.clone();
let event_store = self.event_store.clone();
- let framework = self.framework.clone();
let login_type = self.login_type;
- thread::spawn(move || {
- handle_connection(connection_clone,
- framework,
- login_type,
- event_store);
- });
+
+ feature_framework! {{
+ let framework = self.framework.clone();
+
+ thread::spawn(move || {
+ handle_connection(connection_clone,
+ framework,
+ login_type,
+ event_store)
+ });
+ } {
+ thread::spawn(move || {
+ handle_connection(connection_clone,
+ login_type,
+ event_store)
+ });
+ }}
},
None => return Err(Error::Client(ClientError::ConnectionUnknown)),
}
@@ -986,6 +916,201 @@ impl Client {
}
}
+#[cfg(feature = "state")]
+impl Client {
+ /// Attaches a handler for when a [`CallUpdate`] is received.
+ ///
+ /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate
+ pub fn on_call_update<F>(&mut self, handler: F)
+ where F: Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_call_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildDelete`] is received.
+ ///
+ /// 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, Option<LiveGuild>) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_delete = Some(Arc::new(handler));
+ }
+
+ /// 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, Option<Member>) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_member_removal = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildMemberUpdate`] is received.
+ ///
+ /// [`GuildMemberUpdate`]: ../model/enum.Event.html#variant.GuildMemberUpdate
+ pub fn on_guild_member_update<F>(&mut self, handler: F)
+ where F: Fn(Context, Option<Member>, Member) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_member_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildRoleDelete`] is received.
+ ///
+ /// [`GuildRoleDelete`]: ../model/enum.Event.html#variant.GuildRoleDelete
+ pub fn on_guild_role_delete<F>(&mut self, handler: F)
+ where F: Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_role_delete = Some(Arc::new(handler));
+ }
+
+ /// 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, Option<String>, String) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_note_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`UserSettingsUpdate`] is received.
+ ///
+ /// The old user settings will be provided as well.
+ ///
+ /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate
+ pub fn on_user_settings_update<F>(&mut self, handler: F)
+ where F: Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_user_settings_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`UserUpdate`] is received.
+ ///
+ /// The old current user will be provided as well.
+ ///
+ /// [`UserUpdate`]: ../model/enum.Event.html#variant.UserUpdate
+ pub fn on_user_update<F>(&mut self, handler: F)
+ where F: Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_user_update = Some(Arc::new(handler));
+ }
+}
+
+#[cfg(not(feature = "state"))]
+impl Client {
+ /// Attaches a handler for when a [`CallUpdate`] is received.
+ ///
+ /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate
+ pub fn on_call_update<F>(&mut self, handler: F)
+ where F: Fn(Context, CallUpdateEvent) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_call_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildDelete`] is received.
+ ///
+ /// [`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, Option<LiveGuild>) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_delete = Some(Arc::new(handler));
+ }
+
+ /// 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 {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_member_removal = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildMemberUpdate`] is received.
+ ///
+ /// [`GuildMemberUpdate`]: ../model/enum.Event.html#variant.GuildMemberUpdate
+ pub fn on_guild_member_update<F>(&mut self, handler: F)
+ where F: Fn(Context, GuildMemberUpdateEvent) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_member_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`GuildRoleDelete`] is received.
+ ///
+ /// [`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 {
+ self.event_store.lock()
+ .unwrap()
+ .on_guild_role_delete = Some(Arc::new(handler));
+ }
+
+ /// 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 {
+ self.event_store.lock()
+ .unwrap()
+ .on_note_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`UserSettingsUpdate`] is received.
+ ///
+ /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate
+ pub fn on_user_settings_update<F>(&mut self, handler: F)
+ where F: Fn(Context, UserSettingsEvent) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_user_settings_update = Some(Arc::new(handler));
+ }
+
+ /// Attaches a handler for when a [`UserUpdate`] is received.
+ ///
+ /// [`UserUpdate`]: ../model/enum.Event.html#variant.UserUpdate
+ pub fn on_user_update<F>(&mut self, handler: F)
+ where F: Fn(Context, CurrentUser) + Send + Sync + 'static {
+ self.event_store.lock()
+ .unwrap()
+ .on_user_update = Some(Arc::new(handler));
+ }
+}
+
+#[cfg(feature="framework")]
fn handle_connection(connection: Arc<Mutex<Connection>>,
framework: Arc<Mutex<Framework>>,
login_type: LoginType,
@@ -1005,18 +1130,45 @@ fn handle_connection(connection: Arc<Mutex<Connection>>,
}
}
+#[cfg(not(feature="framework"))]
+fn handle_connection(connection: Arc<Mutex<Connection>>,
+ login_type: LoginType,
+ event_store: Arc<Mutex<EventStore>>) {
+ loop {
+ let event = {
+ let mut connection = connection.lock().unwrap();
+
+ connection.receive()
+ };
+
+ dispatch(event,
+ connection.clone(),
+ login_type,
+ event_store.clone());
+ }
+}
+
fn login(token: &str, login_type: LoginType) -> Client {
let token = token.to_owned();
http::set_token(&token);
- Client {
- connections: Vec::default(),
- event_store: Arc::new(Mutex::new(EventStore::default())),
- framework: Arc::new(Mutex::new(Framework::default())),
- login_type: login_type,
- token: token.to_owned(),
- }
+ feature_framework! {{
+ Client {
+ connections: Vec::default(),
+ event_store: Arc::new(Mutex::new(EventStore::default())),
+ framework: Arc::new(Mutex::new(Framework::default())),
+ login_type: login_type,
+ token: token.to_owned(),
+ }
+ } {
+ Client {
+ connections: Vec::default(),
+ event_store: Arc::new(Mutex::new(EventStore::default())),
+ login_type: login_type,
+ token: token.to_owned(),
+ }
+ }}
}
/// Validates that a token is likely in a valid format.
diff --git a/src/ext/mod.rs b/src/ext/mod.rs
index bb87911..312074b 100644
--- a/src/ext/mod.rs
+++ b/src/ext/mod.rs
@@ -5,10 +5,17 @@
//!
//! See each extension's module-level documentation for more information.
//!
+//! Note that the framework module requires the `framework` feature to be
+//! enabled (enabled by default), the state requires the `state` feature to be
+//! enabled (enabled by default), and voice support requires the `voice` feature
+//! to be enabled (disabled by default).
+//!
//! [`Client`]: ../client/struct.Client.html
//! [`Connection`]: ../client/struct.Connection.html
+#[cfg(feature = "framework")]
pub mod framework;
+#[cfg(feature = "state")]
pub mod state;
-#[cfg(feature="voice")]
+#[cfg(feature = "voice")]
pub mod voice;
diff --git a/src/ext/state/mod.rs b/src/ext/state/mod.rs
index fa38b6f..5c56a54 100644
--- a/src/ext/state/mod.rs
+++ b/src/ext/state/mod.rs
@@ -166,7 +166,7 @@ impl State {
self.update_with_guild_member_remove(event);
},
Event::GuildMemberUpdate(ref event) => {
- self.update_with_guild_member_update(event, false);
+ self.update_with_guild_member_update(event);
},
Event::GuildMembersChunk(ref event) => {
self.update_with_guild_members_chunk(event);
@@ -448,10 +448,8 @@ impl State {
}
pub fn update_with_guild_member_update(&mut self,
- event: &GuildMemberUpdateEvent,
- old: bool)
+ event: &GuildMemberUpdateEvent)
-> Option<Member> {
-
if let Some(guild) = self.guilds.get_mut(&event.guild_id) {
let mut found = false;
diff --git a/src/model/channel.rs b/src/model/channel.rs
index 429fa01..72a1f09 100644
--- a/src/model/channel.rs
+++ b/src/model/channel.rs
@@ -1,11 +1,5 @@
-use hyper::Client as HyperClient;
-use serde_json::builder::ObjectBuilder;
use std::borrow::Cow;
use std::fmt::{self, Write};
-use std::fs::File;
-use std::io::{Read, Write as IoWrite};
-use std::mem;
-use std::path::{Path, PathBuf};
use super::utils::{
decode_id,
into_map,
@@ -15,16 +9,34 @@ use super::utils::{
warn_field,
};
use super::*;
-use super::utils;
-use ::utils::builder::{CreateEmbed, CreateInvite, EditChannel};
-use ::client::{STATE, http};
use ::constants;
use ::internal::prelude::*;
use ::utils::decode_array;
+#[cfg(feature = "methods")]
+use hyper::Client as HyperClient;
+#[cfg(feature = "methods")]
+use serde_json::builder::ObjectBuilder;
+#[cfg(feature = "methods")]
+use std::fs::File;
+#[cfg(feature = "methods")]
+use std::io::{Read, Write as IoWrite};
+#[cfg(feature = "methods")]
+use std::mem;
+#[cfg(feature = "methods")]
+use std::path::{Path, PathBuf};
+#[cfg(feature = "methods")]
+use super::utils;
+
+#[cfg(feature = "methods")]
+use ::utils::builder::{CreateEmbed, CreateInvite, EditChannel};
+#[cfg(feature = "methods")]
+use ::client::{STATE, http};
+
impl Attachment {
/// If this attachment is an image, then a tuple of the width and height
/// in pixels is returned.
+ #[cfg(feature = "methods")]
pub fn dimensions(&self) -> Option<(u64, u64)> {
if let (Some(width), Some(height)) = (self.width, self.height) {
Some((width, height))
@@ -99,6 +111,7 @@ impl Attachment {
/// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper
/// [`Error::Io`]: ../enum.Error.html#variant.Io
/// [`Message`]: struct.Message.html
+ #[cfg(feature = "methods")]
pub fn download(&self) -> Result<Vec<u8>> {
let hyper = HyperClient::new();
let mut response = try!(hyper.get(&self.url).send());
@@ -163,6 +176,7 @@ impl Attachment {
/// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper
/// [`Error::Io`]: ../enum.Error.html#variant.Io
/// [`Message`]: struct.Message.html
+ #[cfg(feature = "methods")]
pub fn download_to_directory<P: AsRef<Path>>(&self, path: P) -> Result<PathBuf> {
let bytes = try!(self.download());
@@ -196,6 +210,7 @@ impl Channel {
/// closest functionality is leaving it.
///
/// [`Group`]: struct.Group.html
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<()> {
match *self {
Channel::Group(ref group) => {
@@ -258,6 +273,7 @@ impl Embed {
/// This should only be useful in conjunction with [`Webhook::execute`].
///
/// [`Webhook::execute`]: struct.Webhook.html
+ #[cfg(feature = "methods")]
#[inline(always)]
pub fn fake<F>(f: F) -> Value where F: FnOnce(CreateEmbed) -> CreateEmbed {
f(CreateEmbed::default()).0.build()
@@ -270,6 +286,7 @@ impl Group {
///
/// **Note**: Groups have a limit of 10 recipients, including the current
/// user.
+ #[cfg(feature = "methods")]
pub fn add_recipient<U: Into<UserId>>(&self, user: U) -> Result<()> {
let user = user.into();
@@ -282,6 +299,7 @@ impl Group {
}
/// Broadcasts that the current user is typing in the group.
+ #[cfg(feature = "methods")]
pub fn broadcast_typing(&self) -> Result<()> {
http::broadcast_typing(self.channel_id.0)
}
@@ -301,6 +319,7 @@ impl Group {
///
/// [`ClientError::DeleteMessageDaysAmount`]: ../client/enum.ClientError.html#variant.DeleteMessageDaysAmount
/// [`Context::delete_messages`]: ../client/struct.Context.html#delete_messages
+ #[cfg(feature = "methods")]
pub fn delete_messages(&self, message_ids: &[MessageId]) -> Result<()> {
if message_ids.len() < 2 || message_ids.len() > 100 {
return Err(Error::Client(ClientError::BulkDeleteAmount));
@@ -324,6 +343,7 @@ impl Group {
}
/// Leaves the group.
+ #[cfg(feature = "methods")]
pub fn leave(&self) -> Result<Group> {
http::leave_group(self.channel_id.0)
}
@@ -352,6 +372,7 @@ impl Group {
}
/// Retrieves the list of messages that have been pinned in the group.
+ #[cfg(feature = "methods")]
pub fn pins(&self) -> Result<Vec<Message>> {
http::get_pins(self.channel_id.0)
}
@@ -360,6 +381,7 @@ impl Group {
/// the group, then nothing is done.
///
/// **Note**: This is only available to the group owner.
+ #[cfg(feature = "methods")]
pub fn remove_recipient<U: Into<UserId>>(&self, user: U) -> Result<()> {
let user = user.into();
@@ -378,6 +400,7 @@ impl Group {
/// **Note**: Requires the [Send Messages] permission.
///
/// [Send Messages]: permissions/constant.SEND_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn send_message(&self, content: &str) -> Result<Message> {
let map = ObjectBuilder::new()
.insert("content", content)
@@ -408,6 +431,7 @@ impl Message {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser
/// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<()> {
let req = permissions::MANAGE_MESSAGES;
let is_author = self.author.id != STATE.lock().unwrap().user.id;
@@ -435,6 +459,7 @@ impl Message {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`Reaction`]: struct.Reaction.html
/// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn delete_reactions(&self) -> Result<()> {
let req = permissions::MANAGE_MESSAGES;
@@ -462,6 +487,7 @@ impl Message {
///
/// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser
/// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong
+ #[cfg(feature = "methods")]
pub fn edit(&mut self, new_content: &str) -> Result<()> {
if let Some(length_over) = Message::overflow_length(new_content) {
return Err(Error::Client(ClientError::MessageTooLong(length_over)));
@@ -516,6 +542,7 @@ impl Message {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn pin(&self) -> Result<()> {
let req = permissions::MANAGE_MESSAGES;
@@ -539,6 +566,7 @@ impl Message {
/// [`Emoji`]: struct.Emoji.html
/// [Add Reactions]: permissions/constant.ADD_REACTIONS.html
/// [permissions]: permissions
+ #[cfg(feature = "methods")]
pub fn react<R: Into<ReactionType>>(&self, reaction_type: R) -> Result<()> {
let req = permissions::ADD_REACTIONS;
@@ -572,6 +600,7 @@ impl Message {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong
/// [Send Messages]: permissions/constant.SEND_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn reply(&self, content: &str) -> Result<Message> {
if let Some(length_over) = Message::overflow_length(content) {
return Err(Error::Client(ClientError::MessageTooLong(length_over)));
@@ -609,6 +638,7 @@ impl Message {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn unpin(&self) -> Result<()> {
let req = permissions::MANAGE_MESSAGES;
@@ -621,6 +651,7 @@ impl Message {
}
impl PermissionOverwrite {
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<PermissionOverwrite> {
let mut map = try!(into_map(value));
let id = try!(remove(&mut map, "id").and_then(decode_id));
@@ -641,6 +672,7 @@ impl PermissionOverwrite {
impl PrivateChannel {
/// Broadcasts that the current user is typing to the recipient.
+ #[cfg(feature = "methods")]
pub fn broadcast_typing(&self) -> Result<()> {
http::broadcast_typing(self.id.0)
}
@@ -672,6 +704,7 @@ impl PrivateChannel {
/// [`ClientError::InvalidUser`] if the current user is not a bot user.
///
/// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidOperationAsUser
+ #[cfg(feature = "methods")]
pub fn delete_messages(&self, message_ids: &[MessageId]) -> Result<()> {
if !STATE.lock().unwrap().user.bot {
return Err(Error::Client(ClientError::InvalidOperationAsUser));
@@ -691,12 +724,14 @@ impl PrivateChannel {
/// Deletes the channel. This does not delete the contents of the channel,
/// and is equivilant to closing a private channel on the client, which can
/// be re-opened.
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<Channel> {
http::delete_channel(self.id.0)
}
/// Retrieves the list of messages that have been pinned in the private
/// channel.
+ #[cfg(feature = "methods")]
pub fn pins(&self) -> Result<Vec<Message>> {
http::get_pins(self.id.0)
}
@@ -712,6 +747,7 @@ impl PrivateChannel {
/// over the limit.
///
/// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong
+ #[cfg(feature = "methods")]
pub fn send_message(&self, content: &str) -> Result<Message> {
if let Some(length_over) = Message::overflow_length(content) {
return Err(Error::Client(ClientError::MessageTooLong(length_over)));
@@ -749,10 +785,12 @@ impl PublicChannel {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Send Messages]: permissions/constants.SEND_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn broadcast_typing(&self) -> Result<()> {
http::broadcast_typing(self.id.0)
}
+ #[cfg(feature = "methods")]
pub fn create_invite<F>(&self, f: F) -> Result<RichInvite>
where F: FnOnce(CreateInvite) -> CreateInvite {
let req = permissions::CREATE_INVITE;
@@ -766,6 +804,7 @@ impl PublicChannel {
http::create_invite(self.id.0, map)
}
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<PublicChannel> {
let mut map = try!(into_map(value));
@@ -774,6 +813,7 @@ impl PublicChannel {
PublicChannel::decode_guild(Value::Object(map), id)
}
+ #[doc(hidden)]
pub fn decode_guild(value: Value, guild_id: GuildId) -> Result<PublicChannel> {
let mut map = try!(into_map(value));
missing!(map, PublicChannel {
@@ -792,6 +832,7 @@ impl PublicChannel {
}
/// Deletes this channel, returning the channel on a successful deletion.
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<Channel> {
let req = permissions::MANAGE_CHANNELS;
@@ -801,8 +842,9 @@ impl PublicChannel {
http::delete_channel(self.id.0)
}
- pub fn edit<F>(&mut self, f: F) -> Result<()>
+ #[cfg(feature = "methods")]
+ pub fn edit<F>(&mut self, f: F) -> Result<()>
where F: FnOnce(EditChannel) -> EditChannel {
let req = permissions::MANAGE_CHANNELS;
@@ -834,6 +876,7 @@ impl PublicChannel {
self.id.mention()
}
+ #[cfg(feature = "methods")]
pub fn pins(&self) -> Result<Vec<Message>> {
http::get_pins(self.id.0)
}
@@ -856,6 +899,7 @@ impl PublicChannel {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`ClientError::MessageTooLong`]: ../client/enum.ClientError.html#variant.MessageTooLong
/// [Send Messages]: permissions/constant.SEND_MESSAGES.html
+ #[cfg(feature = "methods")]
pub fn send_message(&self, content: &str) -> Result<Message> {
if let Some(length_over) = Message::overflow_length(content) {
return Err(Error::Client(ClientError::MessageTooLong(length_over)));
@@ -881,6 +925,7 @@ impl PublicChannel {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature = "methods")]
pub fn webhooks(&self) -> Result<Vec<Webhook>> {
http::get_channel_webhooks(self.id.0)
}
@@ -908,6 +953,7 @@ impl Reaction {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
/// [permissions]: permissions
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<()> {
let user = if self.user_id == STATE.lock().unwrap().user.id {
None
@@ -958,6 +1004,7 @@ impl Reaction {
/// [`User`]: struct.User.html
/// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html
/// [permissions]: permissions
+ #[cfg(feature = "methods")]
pub fn users<R, U>(&self,
reaction_type: R,
limit: Option<u8>,
@@ -1013,6 +1060,7 @@ impl ReactionType {
}
}
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<Self> {
let mut map = try!(into_map(value));
let name = try!(remove(&mut map, "name").and_then(into_string));
diff --git a/src/model/gateway.rs b/src/model/gateway.rs
index aa3d995..1a286af 100644
--- a/src/model/gateway.rs
+++ b/src/model/gateway.rs
@@ -734,6 +734,7 @@ impl Event {
}
impl Game {
+ #[cfg(feature="methods")]
pub fn playing(name: String) -> Game {
Game {
kind: GameType::Playing,
@@ -742,6 +743,7 @@ impl Game {
}
}
+ #[cfg(feature="methods")]
pub fn streaming(name: String, url: String) -> Game {
Game {
kind: GameType::Streaming,
@@ -750,6 +752,7 @@ impl Game {
}
}
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<Option<Game>> {
let mut map = try!(into_map(value));
@@ -771,6 +774,7 @@ impl Game {
}
impl Presence {
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<Presence> {
let mut value = try!(into_map(value));
let mut user_map = try!(remove(&mut value, "user").and_then(into_map));
diff --git a/src/model/guild.rs b/src/model/guild.rs
index 1ab9bb3..a350cae 100644
--- a/src/model/guild.rs
+++ b/src/model/guild.rs
@@ -1,6 +1,5 @@
-use serde_json::builder::ObjectBuilder;
use std::collections::HashMap;
-use std::{fmt, mem};
+use std::fmt;
use super::utils::{
decode_emojis,
decode_members,
@@ -14,11 +13,21 @@ use super::utils::{
warn_field
};
use super::*;
-use ::utils::builder::{EditGuild, EditMember, EditRole};
-use ::client::{STATE, http};
use ::internal::prelude::*;
use ::utils::decode_array;
+#[cfg(feature = "methods")]
+use serde_json::builder::ObjectBuilder;
+#[cfg(feature = "methods")]
+use std::mem;
+#[cfg(feature = "methods")]
+use ::utils::builder::{EditGuild, EditMember, EditRole};
+#[cfg(feature = "methods")]
+use ::client::http;
+
+#[cfg(feature = "state")]
+use ::client::STATE;
+
impl From<Guild> for GuildContainer {
fn from(guild: Guild) -> GuildContainer {
GuildContainer::Guild(guild)
@@ -41,6 +50,7 @@ impl Emoji {
/// Finds the [`Guild`] that owns the emoji by looking through the state.
///
/// [`Guild`]: struct.Guild.html
+ #[cfg(feature = "methods")]
pub fn find_guild_id(&self) -> Option<GuildId> {
STATE.lock()
.unwrap()
@@ -57,6 +67,7 @@ impl Emoji {
/// **Note**: Only user accounts may use this method.
///
/// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<()> {
match self.find_guild_id() {
Some(guild_id) => http::delete_emoji(guild_id.0, self.id.0),
@@ -71,6 +82,7 @@ impl Emoji {
/// **Note**: Only user accounts may use this method.
///
/// [Manage Emojis]: permissions/constant.MANAGE_EMOJIS.html
+ #[cfg(feature = "methods")]
pub fn edit(&mut self, name: &str) -> Result<()> {
match self.find_guild_id() {
Some(guild_id) => {
@@ -116,6 +128,7 @@ impl GuildInfo {
impl Guild {
/// Finds a role by Id within the guild.
+ #[cfg(feature = "methods")]
pub fn find_role<R: Into<RoleId>>(&self, role_id: R) -> Option<&Role> {
self.roles.get(&role_id.into())
}
@@ -127,6 +140,7 @@ impl Guild {
/// **Note**: Requires the [Change Nickname] permission.
///
/// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html
+ #[cfg(feature = "methods")]
#[inline]
pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> {
http::edit_nickname(self.id.0, new_nickname)
@@ -143,6 +157,7 @@ impl Guild {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature = "methods")]
#[inline]
pub fn webhooks(&self) -> Result<Vec<Webhook>> {
http::get_guild_webhooks(self.id.0)
@@ -150,6 +165,7 @@ impl Guild {
}
impl LiveGuild {
+ #[cfg(feature = "state")]
fn has_perms(&self, mut permissions: Permissions) -> Result<bool> {
let member = match self.get_member(STATE.lock().unwrap().user.id) {
Some(member) => member,
@@ -163,6 +179,11 @@ impl LiveGuild {
Ok(permissions.is_empty())
}
+ #[cfg(not(feature = "state"))]
+ fn has_perms(&self, mut permissions: Permissions) -> Result<bool> {
+ Ok(true)
+ }
+
/// Ban a [`User`] from the guild. All messages by the
/// user within the last given number of days given will be deleted. This
/// may be a range between `0` and `7`.
@@ -190,6 +211,7 @@ impl LiveGuild {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`User`]: struct.User.html
/// [Ban Members]: permissions/constant.BAN_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn ban<U: Into<UserId>>(&self, user: U, delete_message_days: u8)
-> Result<()> {
if delete_message_days > 7 {
@@ -217,6 +239,7 @@ impl LiveGuild {
/// [`Ban`]: struct.Ban.html
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Ban Members]: permissions/constant.BAN_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn bans(&self) -> Result<Vec<Ban>> {
let req = permissions::BAN_MEMBERS;
@@ -249,6 +272,7 @@ impl LiveGuild {
/// [`Channel`]: struct.Channel.html
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Channels]: permissions/constants.MANAGE_CHANNELS.html
+ #[cfg(feature = "methods")]
pub fn create_channel(&mut self, name: &str, kind: ChannelType)
-> Result<Channel> {
let req = permissions::MANAGE_CHANNELS;
@@ -280,6 +304,7 @@ impl LiveGuild {
/// [`Context::create_role`]: ../client/struct.Context.html#method.create_role
/// [`Role`]: struct.Role.html
/// [Manage Roles]: permissions/constants.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn create_role<F>(&self, f: F) -> Result<Role>
where F: FnOnce(EditRole) -> EditRole {
let req = permissions::MANAGE_ROLES;
@@ -352,6 +377,7 @@ impl LiveGuild {
/// guild owner.
///
/// [`ClientError::InvalidUser`]: ../client/enum.ClientError.html#variant.InvalidUser
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<Guild> {
if self.owner_id != STATE.lock().unwrap().user.id {
let req = permissions::MANAGE_GUILD;
@@ -376,6 +402,7 @@ impl LiveGuild {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`Context::edit_guild`]: ../client/struct.Context.html#method.edit_guild
/// [Manage Guild]: permissions/constants.MANAGE_GUILD.html
+ #[cfg(feature = "methods")]
pub fn edit<F>(&mut self, f: F) -> Result<()>
where F: FnOnce(EditGuild) -> EditGuild {
let req = permissions::MANAGE_GUILD;
@@ -421,6 +448,7 @@ impl LiveGuild {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Change Nickname]: permissions/constant.CHANGE_NICKNAME.html
+ #[cfg(feature = "methods")]
pub fn edit_nickname(&self, new_nickname: Option<&str>) -> Result<()> {
let req = permissions::CHANGE_NICKNAME;
@@ -450,6 +478,7 @@ impl LiveGuild {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Guild]: permissions/constant.MANAGE_GUILD.html
+ #[cfg(feature = "methods")]
pub fn get_invites(&self) -> Result<Vec<RichInvite>> {
let req = permissions::MANAGE_GUILD;
@@ -526,6 +555,7 @@ impl LiveGuild {
}
/// Leaves the guild.
+ #[cfg(feature = "methods")]
pub fn leave(&self) -> Result<Guild> {
http::leave_guild(self.id.0)
}
@@ -655,6 +685,7 @@ impl LiveGuild {
/// [`GuildPrune`]: struct.GuildPrune.html
/// [`Member`]: struct.Member.html
/// [Kick Members]: permissions/constant.KICK_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn prune_count(&self, days: u16) -> Result<GuildPrune> {
let req = permissions::KICK_MEMBERS;
@@ -684,6 +715,7 @@ impl LiveGuild {
/// [`GuildPrune`]: struct.GuildPrune.html
/// [`Member`]: struct.Member.html
/// [Kick Members]: permissions/constant.KICK_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn start_prune(&self, days: u16) -> Result<GuildPrune> {
let req = permissions::KICK_MEMBERS;
@@ -710,6 +742,7 @@ impl LiveGuild {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`User`]: struct.User.html
/// [Ban Members]: permissions/constant.BAN_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn unban<U: Into<UserId>>(&self, user: U) -> Result<()> {
let req = permissions::BAN_MEMBERS;
@@ -725,6 +758,7 @@ impl LiveGuild {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature = "methods")]
#[inline]
pub fn webhooks(&self) -> Result<Vec<Webhook>> {
http::get_guild_webhooks(self.id.0)
@@ -739,6 +773,7 @@ impl Member {
///
/// [`Role`]: struct.Role.html
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn add_role<R: Into<RoleId>>(&mut self, role_id: R) -> Result<()> {
self.add_roles(&[role_id.into()])
}
@@ -750,6 +785,7 @@ impl Member {
///
/// [`Role`]: struct.Role.html
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn add_roles(&mut self, role_ids: &[RoleId]) -> Result<()> {
let guild_id = try!(self.find_guild());
self.roles.extend_from_slice(role_ids);
@@ -772,6 +808,7 @@ impl Member {
/// **Note**: Requires the [Ban Members] role.
///
/// [Ban Members]: permissions/constant.BAN_MEMBERS.html
+ #[cfg(feature = "methods")]
pub fn ban(&self, delete_message_days: u8) -> Result<()> {
let guild_id = try!(self.find_guild());
@@ -795,6 +832,7 @@ impl Member {
///
/// [`Context::edit_member`]: ../client/struct.Context.html#method.edit_member
/// [`EditMember`]: ../builder/struct.EditMember.html
+ #[cfg(feature = "methods")]
pub fn edit<F>(&self, f: F) -> Result<()>
where F: FnOnce(EditMember) -> EditMember {
let guild_id = try!(self.find_guild());
@@ -806,6 +844,7 @@ impl Member {
/// Finds the Id of the [`Guild`] that the member is in.
///
/// [`Guild`]: struct.Guild.html
+ #[cfg(feature = "methods")]
pub fn find_guild(&self) -> Result<GuildId> {
STATE.lock()
.unwrap()
@@ -831,6 +870,7 @@ impl Member {
///
/// [`Role`]: struct.Role.html
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn remove_role<R: Into<RoleId>>(&mut self, role_id: R) -> Result<()> {
self.remove_roles(&[role_id.into()])
}
@@ -841,6 +881,7 @@ impl Member {
///
/// [`Role`]: struct.Role.html
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn remove_roles(&mut self, role_ids: &[RoleId]) -> Result<()> {
let guild_id = try!(self.find_guild());
self.roles.retain(|r| !role_ids.contains(r));
@@ -924,6 +965,7 @@ impl Role {
/// **Note** Requires the [Manage Roles] permission.
///
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
+ #[cfg(feature = "methods")]
pub fn delete(&self) -> Result<()> {
let guild_id = try!(self.find_guild());
@@ -938,6 +980,7 @@ impl Role {
/// that contains the role.
///
/// [`ClientError::GuildNotFound`]: ../client/enum.ClientError.html#variant.GuildNotFound
+ #[cfg(feature = "methods")]
pub fn find_guild(&self) -> Result<GuildId> {
STATE.lock()
.unwrap()
diff --git a/src/model/id.rs b/src/model/id.rs
index 0d9fb32..ff236e1 100644
--- a/src/model/id.rs
+++ b/src/model/id.rs
@@ -1,15 +1,20 @@
use super::*;
+
+#[cfg(feature = "methods")]
use ::client::{STATE, http};
+#[cfg(feature = "methods")]
use ::internal::prelude::*;
impl ChannelId {
/// Search the state for the channel with the Id.
+ #[cfg(feature="methods")]
pub fn find(&self) -> Option<Channel> {
STATE.lock().unwrap().find_channel(*self)
}
/// Search the state for the channel. If it can't be found, the channel is
/// requested over REST.
+ #[cfg(feature="methods")]
pub fn get(&self) -> Result<Channel> {
if let Some(channel) = STATE.lock().unwrap().find_channel(*self) {
return Ok(channel);
@@ -34,6 +39,7 @@ impl ChannelId {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature="methods")]
pub fn webhooks(&self) -> Result<Vec<Webhook>> {
http::get_channel_webhooks(self.0)
}
@@ -69,6 +75,7 @@ impl From<Emoji> for EmojiId {
impl GuildId {
/// Search the state for the guild.
+ #[cfg(feature="methods")]
pub fn find(&self) -> Option<LiveGuild> {
STATE.lock().unwrap().find_guild(*self).cloned()
}
@@ -77,6 +84,7 @@ impl GuildId {
///
/// Note that this will not be a complete guild, as REST does not send
/// all data with a guild retrieval.
+ #[cfg(feature="methods")]
pub fn get(&self) -> Result<Guild> {
http::get_guild(self.0)
}
@@ -96,6 +104,7 @@ impl GuildId {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature="methods")]
pub fn webhooks(&self) -> Result<Vec<Webhook>> {
http::get_guild_webhooks(self.0)
}
@@ -145,6 +154,7 @@ impl From<Role> for RoleId {
impl RoleId {
/// Search the state for the role.
+ #[cfg(feature="methods")]
pub fn find(&self) -> Option<Role> {
STATE.lock()
.unwrap()
@@ -206,6 +216,7 @@ impl WebhookId {
/// **Note**: Requires the [Manage Webhooks] permission.
///
/// [Manage Webhooks]: permissions/constant.MANAGE_WEBHOOKS.html
+ #[cfg(feature="methods")]
pub fn webhooks(&self) -> Result<Webhook> {
http::get_webhook(self.0)
}
diff --git a/src/model/invite.rs b/src/model/invite.rs
index 8fd55e7..c33647e 100644
--- a/src/model/invite.rs
+++ b/src/model/invite.rs
@@ -10,6 +10,7 @@ impl Invite {
/// banned. A ban is equivilant to an IP ban.
///
/// [`Guild`]: struct.Guild.html
+ #[cfg(feature="methods")]
pub fn accept(&self) -> Result<Invite> {
http::accept_invite(&self.code)
}
@@ -25,6 +26,7 @@ impl Invite {
///
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [Manage Guild]: permissions/constant.MANAGE_GUILD.html
+ #[cfg(feature="methods")]
pub fn delete(&self) -> Result<Invite> {
let req = permissions::MANAGE_GUILD;
@@ -43,6 +45,7 @@ impl RichInvite {
/// accepting an invite.
///
/// [`Invite::accept`]: struct.Invite.html#method.accept
+ #[cfg(feature="methods")]
pub fn accept(&self) -> Result<Invite> {
http::accept_invite(&self.code)
}
@@ -60,6 +63,7 @@ impl RichInvite {
/// [`ClientError::InvalidPermissions`]: ../client/enum.ClientError.html#variant.InvalidPermissions
/// [`Invite::delete`]: struct.Invite.html#method.delete
/// [Manage Guild]: permissions/constant.MANAGE_GUILD.html
+ #[cfg(feature="methods")]
pub fn delete(&self) -> Result<Invite> {
let req = permissions::MANAGE_GUILD;
diff --git a/src/model/misc.rs b/src/model/misc.rs
index 16cc7fe..3a17d96 100644
--- a/src/model/misc.rs
+++ b/src/model/misc.rs
@@ -89,6 +89,7 @@ impl fmt::Display for Mention {
}
impl IncidentStatus {
+ #[doc(hidden)]
pub fn decode(value: Value) -> Result<Self> {
Self::decode_str(value)
}
diff --git a/src/model/mod.rs b/src/model/mod.rs
index f21da09..f00dffb 100644
--- a/src/model/mod.rs
+++ b/src/model/mod.rs
@@ -7,21 +7,27 @@ mod channel;
mod gateway;
mod guild;
mod id;
-mod invite;
mod misc;
mod user;
mod voice;
+
+#[cfg(feature = "methods")]
+mod invite;
+#[cfg(feature = "methods")]
mod webhook;
pub use self::channel::*;
pub use self::gateway::*;
pub use self::guild::*;
pub use self::id::*;
-pub use self::invite::*;
pub use self::misc::*;
pub use self::permissions::Permissions;
pub use self::user::*;
pub use self::voice::*;
+
+#[cfg(feature = "methods")]
+pub use self::invite::*;
+#[cfg(feature = "methods")]
pub use self::webhook::*;
use self::utils::*;
diff --git a/src/model/permissions.rs b/src/model/permissions.rs
index 49a5069..c21e441 100644
--- a/src/model/permissions.rs
+++ b/src/model/permissions.rs
@@ -82,6 +82,7 @@ use ::internal::prelude::*;
/// [Speak]: constant.SPEAK.html
/// [Use External Emojis]: constant.USE_EXTERNAL_EMOJIS.html
/// [Use VAD]: constant.USE_VAD.html
+#[cfg(feature="extras")]
pub fn general() -> Permissions {
use self::*;
@@ -119,6 +120,7 @@ pub fn general() -> Permissions {
/// [Send Messages]: constant.SEND_MESSAGES.html
/// [Send TTS Messages]: constant.SEND_TTS_MESSAGES.html
/// [Use External Emojis]: constant.USE_EXTERNAL_EMOJIS.html
+#[cfg(feature="extras")]
pub fn text() -> Permissions {
use self::*;
@@ -140,6 +142,7 @@ pub fn text() -> Permissions {
/// [Connect]: constant.CONNECT.html
/// [Speak]: constant.SPEAK.html
/// [Use VAD]: constant.USE_VAD.html
+#[cfg(feature="extras")]
pub fn voice() -> Permissions {
use self::*;
diff --git a/src/model/user.rs b/src/model/user.rs
index f748d67..ce3d3a5 100644
--- a/src/model/user.rs
+++ b/src/model/user.rs
@@ -1,4 +1,3 @@
-use serde_json::builder::ObjectBuilder;
use std::fmt;
use super::utils::{into_map, into_string, remove, warn_field};
use super::{
@@ -6,15 +5,23 @@ use super::{
GuildContainer,
GuildId,
Mention,
- Message,
RoleId,
UserSettings,
User
};
-use ::client::{STATE, http};
use ::internal::prelude::*;
use ::utils::decode_array;
+#[cfg(feature = "methods")]
+use serde_json::builder::ObjectBuilder;
+#[cfg(feature = "methods")]
+use super::Message;
+#[cfg(feature = "methods")]
+use ::client::http;
+
+#[cfg(feature = "state")]
+use ::client::STATE;
+
impl User {
/// Returns the formatted URL of the user's icon, if one exists.
pub fn avatar_url(&self) -> Option<String> {
@@ -25,6 +32,7 @@ impl User {
/// This is an alias of [direct_message].
///
/// [direct_message]: #method.direct_message
+ #[cfg(feature="methods")]
pub fn dm(&self, content: &str) -> Result<Message> {
self.direct_message(content)
}
@@ -32,6 +40,7 @@ impl User {
/// Send a direct message to a user. This will create or retrieve the
/// PrivateChannel over REST if one is not already in the State, and then
/// send a message to it.
+ #[cfg(feature="methods")]
pub fn direct_message(&self, content: &str)
-> Result<Message> {
let private_channel_id = {
@@ -94,12 +103,16 @@ impl User {
match guild.into() {
GuildContainer::Guild(guild) => {
- guild.find_role(role_id).is_some()
+ guild.roles.get(&role_id).is_some()
},
GuildContainer::Id(guild_id) => {
- let state = STATE.lock().unwrap();
+ feature_state! {{
+ let state = STATE.lock().unwrap();
- state.find_role(guild_id, role_id).is_some()
+ state.find_role(guild_id, role_id).is_some()
+ } else {
+ true
+ }}
},
}
}
diff --git a/src/model/utils.rs b/src/model/utils.rs
index f85a30f..92dfbd9 100644
--- a/src/model/utils.rs
+++ b/src/model/utils.rs
@@ -1,5 +1,4 @@
use std::collections::{BTreeMap, HashMap};
-use super::permissions::{self, Permissions};
use super::{
Channel,
ChannelId,
@@ -15,10 +14,14 @@ use super::{
UserId,
VoiceState,
};
-use ::client::STATE;
use ::internal::prelude::*;
use ::utils::{decode_array, into_array};
+#[cfg(feature = "methods")]
+use super::permissions::{self, Permissions};
+#[cfg(feature = "methods")]
+use ::client::STATE;
+
#[macro_escape]
macro_rules! missing {
(@ $name:expr, $json:ident, $value:expr) => {
@@ -268,6 +271,7 @@ pub fn remove(map: &mut BTreeMap<String, Value>, key: &str) -> Result<Value> {
}
#[doc(hidden)]
+#[cfg(feature="methods")]
pub fn user_has_perms(channel_id: ChannelId,
mut permissions: Permissions)
-> Result<bool> {
diff --git a/src/model/webhook.rs b/src/model/webhook.rs
index 04f6d5d..f0d7b16 100644
--- a/src/model/webhook.rs
+++ b/src/model/webhook.rs
@@ -12,6 +12,7 @@ impl Webhook {
/// authentication is not required.
///
/// [`http::delete_webhook_with_token`]: ../client/http/fn.delete_webhook_with_token.html
+ #[cfg(feature="methods")]
pub fn delete(&self) -> Result<()> {
http::delete_webhook_with_token(self.id.0, &self.token)
}
@@ -62,6 +63,7 @@ impl Webhook {
///
/// [`http::edit_webhook`]: ../client/http/fn.edit_webhook.html
/// [`http::edit_webhook_with_token`]: ../client/http/fn.edit_webhook_with_token.html
+ #[cfg(feature="methods")]
pub fn edit(&mut self, name: Option<&str>, avatar: Option<&str>)
-> Result<()> {
if name.is_none() && avatar.is_none() {
@@ -141,6 +143,7 @@ impl Webhook {
/// .embeds(vec![embed]))
/// .expect("err executing");
/// ```
+ #[cfg(feature="methods")]
pub fn execute<F>(&self, f: F) -> Result<Message>
where F: FnOnce(ExecuteWebhook) -> ExecuteWebhook {
let map = f(ExecuteWebhook::default()).0.build();
@@ -155,6 +158,7 @@ impl Webhook {
/// authentication is not required.
///
/// [`http::get_webhook_with_token`]: ../client/http/fn.get_webhook_with_token.html
+ #[cfg(feature="methods")]
pub fn refresh(&mut self) -> Result<()> {
match http::get_webhook_with_token(self.id.0, &self.token) {
Ok(replacement) => {
diff --git a/src/utils/builder/edit_role.rs b/src/utils/builder/edit_role.rs
index d1e2c0e..f87d22e 100644
--- a/src/utils/builder/edit_role.rs
+++ b/src/utils/builder/edit_role.rs
@@ -93,12 +93,18 @@ impl Default for EditRole {
///
/// [general permissions set]: ../model/permissions/fn.general.html
fn default() -> EditRole {
- EditRole(ObjectBuilder::new()
+ let mut map = ObjectBuilder::new()
.insert("color", 10070709)
.insert("hoist", false)
.insert("mentionable", false)
- .insert("name", String::from("new role"))
- .insert("permissions", permissions::general().bits())
- .insert("position", 1))
+ .insert("name", "new role".to_owned());
+
+ feature_extras_enabled! {{
+ map = map.insert("permissions", permissions::general().bits());
+ }}
+
+ map = map.insert("position", 1);
+
+ EditRole(map)
}
}
diff --git a/src/utils/macros.rs b/src/utils/macros.rs
new file mode 100644
index 0000000..34cfaa4
--- /dev/null
+++ b/src/utils/macros.rs
@@ -0,0 +1,300 @@
+macro_rules! request {
+ ($route:expr, $method:ident($body:expr), $url:expr, $($rest:tt)*) => {{
+ let client = HyperClient::new();
+ try!(request($route, || client
+ .$method(&format!(api!($url), $($rest)*))
+ .body(&$body)))
+ }};
+ ($route:expr, $method:ident($body:expr), $url:expr) => {{
+ let client = HyperClient::new();
+ try!(request($route, || client
+ .$method(api!($url))
+ .body(&$body)))
+ }};
+ ($route:expr, $method:ident, $url:expr, $($rest:tt)*) => {{
+ let client = HyperClient::new();
+ try!(request($route, || client
+ .$method(&format!(api!($url), $($rest)*))))
+ }};
+ ($route:expr, $method:ident, $url:expr) => {{
+ let client = HyperClient::new();
+ try!(request($route, || client
+ .$method(api_concat!($url))))
+ }};
+}
+
+macro_rules! cdn_concat {
+ ($e:expr) => {
+ concat!("https://cdn.discordapp.com", $e)
+ }
+}
+macro_rules! api {
+ ($e:expr) => {
+ concat!("https://discordapp.com/api/v6", $e)
+ };
+ ($e:expr, $($rest:tt)*) => {
+ format!(api!($e), $($rest)*)
+ };
+}
+
+macro_rules! api_concat {
+ ($e:expr) => {
+ concat!("https://discordapp.com/api/v6", $e)
+ }
+}
+macro_rules! status_concat {
+ ($e:expr) => {
+ concat!("https://status.discordapp.com/api/v2", $e)
+ }
+}
+
+// Enable/disable check for extras
+macro_rules! feature_extras {
+ ($enabled:block) => {
+ {
+ feature_extras_enabled! {{
+ $enabled
+ }}
+ }
+ };
+ ($enabled:block $disabled:block) => {
+ {
+ feature_extras_enabled! {{
+ $enabled
+ }}
+
+ feature_extras_disabled! {{
+ $disabled
+ }}
+ }
+ };
+}
+
+#[cfg(feature = "extras")]
+macro_rules! feature_extras_enabled {
+ ($enabled:block) => {{
+ {
+ $enabled
+ }
+ }}
+}
+
+#[cfg(not(feature = "extras"))]
+macro_rules! feature_extras_enabled {
+ ($enabled:block) => {}
+}
+
+#[cfg(feature = "extras")]
+macro_rules! feature_extras_disabled {
+ ($disabled:block) => {}
+}
+
+#[cfg(not(feature = "extras"))]
+macro_rules! feature_extras_disabled {
+ ($disabled:block) => {
+ {
+ $disabled
+ }
+ }
+}
+
+// Enable/disable check for framework
+macro_rules! feature_framework {
+ ($enabled:block) => {
+ {
+ feature_framework_enabled! {{
+ $enabled
+ }}
+ }
+ };
+ ($enabled:block $disabled:block) => {
+ {
+ feature_framework_enabled! {{
+ $enabled
+ }}
+
+ feature_framework_disabled! {{
+ $disabled
+ }}
+ }
+ };
+}
+
+#[cfg(feature = "framework")]
+macro_rules! feature_framework_enabled {
+ ($enabled:block) => {
+ {
+ $enabled
+ }
+ }
+}
+
+#[cfg(not(feature = "framework"))]
+macro_rules! feature_framework_enabled {
+ ($enabled:block) => {}
+}
+
+#[cfg(feature = "framework")]
+macro_rules! feature_framework_disabled {
+ ($disabled:block) => {}
+}
+
+#[cfg(not(feature = "framework"))]
+macro_rules! feature_framework_disabled {
+ ($disabled:block) => {
+ {
+ $disabled
+ }
+ }
+}
+
+// Enable/disable check for methods
+macro_rules! feature_methods {
+ ($enabled:block) => {
+ {
+ feature_methods_enabled! {{
+ $enabled
+ }}
+ }
+ };
+ ($enabled:block $disabled:block) => {
+ {
+ feature_methods_enabled! {{
+ $enabled
+ }}
+
+ feature_methods_disabled! {{
+ $disabled
+ }}
+ }
+ };
+}
+
+#[cfg(feature = "methods")]
+macro_rules! feature_methods_enabled {
+ ($enabled:block) => {
+ {
+ $enabled
+ }
+ }
+}
+
+#[cfg(not(feature = "methods"))]
+macro_rules! feature_methods_enabled {
+ ($enabled:block) => {}
+}
+
+#[cfg(feature = "methods")]
+macro_rules! feature_methods_disabled {
+ ($disabled:block) => {}
+}
+
+#[cfg(not(feature = "methods"))]
+macro_rules! feature_methods_disabled {
+ ($disabled:block) => {
+ {
+ $disabled
+ }
+ }
+}
+
+// Enable/disable check for state
+#[cfg(feature = "state")]
+macro_rules! feature_state {
+ ($enabled:block) => {
+ {
+ feature_state_enabled! {{
+ $enabled
+ }}
+ }
+ };
+ ($enabled:block else $disabled:block) => {
+ {
+ feature_state_enabled! {{
+ $enabled
+ }}
+
+ feature_state_disabled! {{
+ $disabled
+ }}
+ }
+ };
+}
+
+#[cfg(feature = "state")]
+macro_rules! feature_state_enabled {
+ ($enabled:block) => {
+ {
+ $enabled
+ }
+ }
+}
+
+#[cfg(not(feature = "state"))]
+macro_rules! feature_state_enabled {
+ ($enabled:block) => {}
+}
+
+#[cfg(feature = "state")]
+macro_rules! feature_state_disabled {
+ ($disabled:block) => {}
+}
+
+#[cfg(not(feature = "state"))]
+macro_rules! feature_state_disabled {
+ ($disabled:block) => {
+ {
+ $disabled
+ }
+ }
+}
+
+// Enable/disable check for voice
+macro_rules! feature_voice {
+ ($enabled:block) => {
+ {
+ feature_voice_enabled! {{
+ $enabled
+ }}
+ }
+ };
+ ($enabled:block $disabled:block) => {
+ {
+ feature_voice_enabled! {{
+ $enabled
+ }}
+
+ feature_voice_disabled! {{
+ $disabled
+ }}
+ }
+ };
+}
+
+#[cfg(feature = "voice")]
+macro_rules! feature_voice_enabled {
+ ($enabled:block) => {
+ {
+ $enabled
+ }
+ }
+}
+
+#[cfg(not(feature = "voice"))]
+macro_rules! feature_voice_enabled {
+ ($enabled:block) => {}
+}
+
+#[cfg(feature = "voice")]
+macro_rules! feature_voice_disabled {
+ ($disabled:block) => {}
+}
+
+#[cfg(not(feature = "voice"))]
+macro_rules! feature_voice_disabled {
+ ($disabled:block) => {
+ {
+ $disabled
+ }
+ }
+}
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 28d18f1..ccf7787 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -1,8 +1,18 @@
//! A set of utilities to help with common use cases that are not required to
//! fully use the library.
+#[macro_use]
+pub mod macros;
+
pub mod builder;
+mod colour;
+
+#[cfg(feature = "extras")]
+mod message_builder;
+
+pub use self::colour::Colour;
+
use base64;
use std::ffi::OsStr;
use std::fs::File;
@@ -10,10 +20,7 @@ use std::io::Read;
use std::path::Path;
use ::internal::prelude::*;
-mod colour;
-mod message_builder;
-
-pub use self::colour::Colour;
+#[cfg(feature = "extras")]
pub use self::message_builder::MessageBuilder;
macro_rules! cdn_concat {
@@ -83,81 +90,6 @@ pub fn into_array(value: Value) -> Result<Vec<Value>> {
}
}
-macro_rules! request {
- ($route:expr, $method:ident($body:expr), $url:expr, $($rest:tt)*) => {{
- let client = HyperClient::new();
- try!(request($route, || client
- .$method(&format!(api!($url), $($rest)*))
- .body(&$body)))
- }};
- ($route:expr, $method:ident($body:expr), $url:expr) => {{
- let client = HyperClient::new();
- try!(request($route, || client
- .$method(api!($url))
- .body(&$body)))
- }};
- ($route:expr, $method:ident, $url:expr, $($rest:tt)*) => {{
- let client = HyperClient::new();
- try!(request($route, || client
- .$method(&format!(api!($url), $($rest)*))))
- }};
- ($route:expr, $method:ident, $url:expr) => {{
- let client = HyperClient::new();
- try!(request($route, || client
- .$method(api_concat!($url))))
- }};
-}
-
-// Enable/disable check for voice
-macro_rules! feature_voice {
- ($enabled:block) => {
- {
- feature_voice_enabled! {{
- $enabled
- }}
- }
- };
- ($enabled:block $disabled:block) => {
- {
- feature_voice_enabled! {{
- $enabled
- }}
-
- feature_voice_disabled! {{
- $disabled
- }}
- }
- };
-}
-
-#[cfg(feature="voice")]
-macro_rules! feature_voice_enabled {
- ($enabled:block) => {
- {
- $enabled
- }
- }
-}
-
-#[cfg(not(feature="voice"))]
-macro_rules! feature_voice_enabled {
- ($enabled:block) => {}
-}
-
-#[cfg(feature="voice")]
-macro_rules! feature_voice_disabled {
- ($disabled:block) => {}
-}
-
-#[cfg(not(feature="voice"))]
-macro_rules! feature_voice_disabled {
- ($disabled:block) => {
- {
- $disabled
- }
- }
-}
-
/// Retrieves the "code" part of an [invite][`RichInvite`] out of a URL.
///
/// # Examples