diff options
| author | Austin Hellyer <[email protected]> | 2016-11-10 20:25:32 -0700 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-12-29 11:55:10 -0800 |
| commit | 0359f512a8aada5ae0371049eb7c66ecd8d68d84 (patch) | |
| tree | f88dd9b362a2d349d0cdcd13b0859c4cc3329f46 /src/model | |
| parent | Rework some event handles (diff) | |
| download | serenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.tar.xz serenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.zip | |
Add guild and channel search
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/channel.rs | 117 | ||||
| -rw-r--r-- | src/model/guild.rs | 158 | ||||
| -rw-r--r-- | src/model/mod.rs | 24 | ||||
| -rw-r--r-- | src/model/utils.rs | 30 |
4 files changed, 321 insertions, 8 deletions
diff --git a/src/model/channel.rs b/src/model/channel.rs index c56ebbe..097587e 100644 --- a/src/model/channel.rs +++ b/src/model/channel.rs @@ -27,14 +27,14 @@ use std::path::{Path, PathBuf}; #[cfg(all(feature="cache", feature="methods"))] use super::utils; -#[cfg(feature="methods")] -use ::utils::builder::{CreateEmbed, CreateInvite, EditChannel}; #[cfg(all(feature="cache", feature="methods"))] use ::client::CACHE; #[cfg(all(feature="methods"))] use ::client::rest; #[cfg(all(feature="cache", feature="methods"))] use ::ext::cache::ChannelRef; +#[cfg(feature = "methods")] +use ::utils::builder::{CreateEmbed, CreateInvite, EditChannel, Search}; impl Attachment { /// If this attachment is an image, then a tuple of the width and height @@ -243,6 +243,41 @@ impl Channel { Channel::Private(ref channel) => channel.id, } } + + /// Performs a search request to the API for the inner channel's + /// [`Message`]s. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + let id = match *self { + Channel::Group(ref group) => group.channel_id.0, + Channel::Guild(ref channel) => channel.id.0, + Channel::Private(ref channel) => channel.id.0, + }; + + rest::search_channel_messages(id, f(Search::default()).0) + } } impl fmt::Display for Channel { @@ -400,6 +435,28 @@ impl Group { rest::remove_group_recipient(self.channel_id.0, user.0) } + /// Performs a search request to the API for the group's channel's + /// [`Message`]s. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + rest::search_channel_messages(self.channel_id.0, f(Search::default()).0) + } + /// Sends a message to the group with the given content. /// /// Note that an @everyone mention will not be applied. @@ -822,6 +879,34 @@ impl PrivateChannel { rest::get_pins(self.id.0) } + /// Performs a search request to the API for the channel's [`Message`]s. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + rest::search_channel_messages(self.id.0, f(Search::default()).0) + } + /// Sends a message to the channel with the given content. /// /// **Note**: This will only work when a [`Message`] is received. @@ -1004,6 +1089,34 @@ impl GuildChannel { rest::get_pins(self.id.0) } + /// Performs a search request for the channel's [`Message`]s. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + rest::search_channel_messages(self.id.0, f(Search::default()).0) + } + /// Sends a message to the channel with the given content. /// /// **Note**: This will only work when a [`Message`] is received. diff --git a/src/model/guild.rs b/src/model/guild.rs index ec492d3..763c610 100644 --- a/src/model/guild.rs +++ b/src/model/guild.rs @@ -20,10 +20,8 @@ use ::utils::decode_array; use serde_json::builder::ObjectBuilder; #[cfg(all(feature="cache", feature = "methods"))] use std::mem; -#[cfg(feature = "methods")] -use ::utils::builder::{EditGuild, EditRole}; #[cfg(all(feature="cache", feature="methods"))] -use ::utils::builder::EditMember; +use ::utils::builder::{EditGuild, EditMember, EditRole, Search}; #[cfg(feature = "methods")] use ::client::rest; @@ -179,6 +177,83 @@ impl PartialGuild { format!(cdn!("/splashes/{}/{}.jpg"), self.id, icon)) } + /// Performs a search request to the API for the guild's [`Message`]s. + /// + /// This will search all of the guild's [`Channel`]s at once, that you have + /// the [Read Message History] permission to. Use [`search_channels`] to + /// specify a list of [channel][`GuildChannel`]s to search, where all other + /// channels will be excluded. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Channel`]: enum.Channel.html + /// [`GuildChannel`]: struct.GuildChannel.html + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + /// [`search_channels`]: #method.search_channels + /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + rest::search_guild_messages(self.id.0, &[], f(Search::default()).0) + } + + /// Performs a search request to the API for the guild's [`Message`]s in + /// given channels. + /// + /// This will search all of the messages in the guild's provided + /// [`Channel`]s by Id that you have the [Read Message History] permission + /// to. Use [`search`] to search all of a guild's [channel][`GuildChannel`]s + /// at once. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Channel`]: enum.Channel.html + /// [`GuildChannel`]: struct.GuildChannel.html + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + /// [`search`]: #method.search + /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html + #[cfg(feature = "methods")] + pub fn search_channels<F>(&self, channel_ids: &[ChannelId], f: F) + -> Result<SearchResult> where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + let ids = channel_ids.iter().map(|x| x.0).collect::<Vec<u64>>(); + + rest::search_guild_messages(self.id.0, &ids, f(Search::default()).0) + } + /// Retrieves the guild's webhooks. /// /// **Note**: Requires the [Manage Webhooks] permission. @@ -756,6 +831,83 @@ impl Guild { format!(cdn!("/splashes/{}/{}.jpg"), self.id, icon)) } + /// Performs a search request to the API for the guild's [`Message`]s. + /// + /// This will search all of the guild's [`Channel`]s at once, that you have + /// the [Read Message History] permission to. Use [`search_channels`] to + /// specify a list of [channel][`GuildChannel`]s to search, where all other + /// channels will be excluded. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Channel`]: enum.Channel.html + /// [`GuildChannel`]: struct.GuildChannel.html + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + /// [`search_channels`]: #method.search_channels + /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html + #[cfg(feature = "methods")] + pub fn search<F>(&self, f: F) -> Result<SearchResult> + where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + rest::search_guild_messages(self.id.0, &[], f(Search::default()).0) + } + + /// Performs a search request to the API for the guild's [`Message`]s in + /// given channels. + /// + /// This will search all of the messages in the guild's provided + /// [`Channel`]s by Id that you have the [Read Message History] permission + /// to. Use [`search`] to search all of a guild's [channel][`GuildChannel`]s + /// at once. + /// + /// Refer to the documentation for the [`Search`] builder for examples and + /// more information. + /// + /// **Note**: Bot users can not search. + /// + /// # Errors + /// + /// If the `cache` is enabled, returns a + /// [`ClientError::InvalidOperationAsBot`] if the current user is a bot. + /// + /// [`ClientError::InvalidOperationAsBot`]: ../client/enum.ClientError.html#variant.InvalidOperationAsBot + /// [`Channel`]: enum.Channel.html + /// [`GuildChannel`]: struct.GuildChannel.html + /// [`Message`]: struct.Message.html + /// [`Search`]: ../utils/builder/struct.Search.html + /// [`search`]: #method.search + /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html + #[cfg(feature = "methods")] + pub fn search_channels<F>(&self, channel_ids: &[ChannelId], f: F) + -> Result<SearchResult> where F: FnOnce(Search) -> Search { + #[cfg(feature="cache")] + { + if CACHE.read().unwrap().user.bot { + return Err(Error::Client(ClientError::InvalidOperationAsBot)); + } + } + + let ids = channel_ids.iter().map(|x| x.0).collect::<Vec<u64>>(); + + rest::search_guild_messages(self.id.0, &ids, f(Search::default()).0) + } + /// Starts a prune of [`Member`]s. /// /// See the documentation on [`GuildPrune`] for more information. diff --git a/src/model/mod.rs b/src/model/mod.rs index 70fdd75..5aad290 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -128,7 +128,7 @@ id! { } /// A container for any channel. -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] pub enum Channel { /// A group. A group comprises of only one channel. Group(Group), @@ -159,7 +159,7 @@ pub enum GuildContainer { /// This is for use with methods such as `Context::create_permission`. /// /// [`Context::create_permission`]: ../client/ -#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PermissionOverwriteType { /// A member which is having its permission overwrites edited. Member(UserId), @@ -168,7 +168,7 @@ pub enum PermissionOverwriteType { } /// A guild which may or may not currently be available. -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] pub enum PossibleGuild<T> { /// An indicator that a guild is currently unavailable for at least one of /// a variety of reasons. @@ -176,3 +176,21 @@ pub enum PossibleGuild<T> { /// An indicator that a guild is currently available. Online(T), } + +#[derive(Copy, Clone, Debug)] +pub enum SearchTarget { + Channel(ChannelId), + Guild(GuildId), +} + +impl From<ChannelId> for SearchTarget { + fn from(channel_id: ChannelId) -> SearchTarget { + SearchTarget::Channel(channel_id) + } +} + +impl From<GuildId> for SearchTarget { + fn from(guild_id: GuildId) -> SearchTarget { + SearchTarget::Guild(guild_id) + } +} diff --git a/src/model/utils.rs b/src/model/utils.rs index 897eb62..e499fd2 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -5,6 +5,7 @@ use super::{ Emoji, EmojiId, Member, + Message, Presence, ReadState, Relationship, @@ -173,6 +174,35 @@ pub fn decode_roles(value: Value) -> Result<HashMap<RoleId, Role>> { Ok(roles) } +pub fn decode_search_results(value: Value) -> Result<Vec<Vec<Message>>> { + let array = match value { + Value::Array(v) => v, + value => return Err(Error::Decode("Expected message set array", value)), + }; + + let mut sets: Vec<Vec<Message>> = vec![]; + + for arr in array { + let arr = match arr { + Value::Array(v) => v, + value => return Err(Error::Decode("Expected message set array", value)), + }; + + let mut messages: Vec<Message> = vec![]; + + for item in arr { + messages.push(match item { + Value::Object(v) => try!(Message::decode(Value::Object(v))), + value => return Err(Error::Decode("Expected search message", value)), + }); + } + + sets.push(messages); + } + + Ok(sets) +} + pub fn decode_shards(value: Value) -> Result<[u64; 2]> { let array = into_array(value)?; |