aboutsummaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-10 20:25:32 -0700
committerAustin Hellyer <[email protected]>2016-12-29 11:55:10 -0800
commit0359f512a8aada5ae0371049eb7c66ecd8d68d84 (patch)
treef88dd9b362a2d349d0cdcd13b0859c4cc3329f46 /src/model
parentRework some event handles (diff)
downloadserenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.tar.xz
serenity-0359f512a8aada5ae0371049eb7c66ecd8d68d84.zip
Add guild and channel search
Diffstat (limited to 'src/model')
-rw-r--r--src/model/channel.rs117
-rw-r--r--src/model/guild.rs158
-rw-r--r--src/model/mod.rs24
-rw-r--r--src/model/utils.rs30
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)?;