diff options
| author | Austin Hellyer <[email protected]> | 2016-11-15 09:34:45 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-15 09:34:45 -0800 |
| commit | 08721763df212cd46b4226d535da00fad9dc10e7 (patch) | |
| tree | bbf65b7542d2b3f26f1f9cf2c2c90b3813e83524 /src | |
| parent | Feature-gate voice example (diff) | |
| download | serenity-08721763df212cd46b4226d535da00fad9dc10e7.tar.xz serenity-08721763df212cd46b4226d535da00fad9dc10e7.zip | |
Add a message builder for Context::send_message
Add a message builder to `send_message`. Often only one field - i.e.
`content` - needs to be specified, and the rest can be ignored.
This is a preliminary patch to add rich embed support to messages.
This message builder is used via:
```rust
// assuming in a context with a `channel_id` bound
context.send_message(channel_id, |m| m
.content("TTS ping!")
.tts(true));
```
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/context.rs | 29 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 2 | ||||
| -rw-r--r-- | src/utils/builder/create_message.rs | 71 | ||||
| -rw-r--r-- | src/utils/builder/mod.rs | 2 |
4 files changed, 89 insertions, 15 deletions
diff --git a/src/client/context.rs b/src/client/context.rs index f4ddd5e..0507bc3 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -7,6 +7,7 @@ use super::{STATE, http}; use super::login_type::LoginType; use ::utils::builder::{ CreateInvite, + CreateMessage, EditChannel, EditGuild, EditMember, @@ -453,7 +454,7 @@ impl Context { /// [`User::dm`]: ../model/struct.User.html#method.dm pub fn dm<C: Into<ChannelId>>(&self, target_id: C, content: &str) -> Result<Message> { - self.send_message(target_id.into(), content, "", false) + self.send_message(target_id.into(), |m| m.content(content)) } pub fn edit_channel<C, F>(&self, channel_id: C, f: F) @@ -838,9 +839,9 @@ impl Context { /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong /// [`ClientError::NoChannelId`]: ../enum.ClientError.html#NoChannelId /// [`Message`]: ../model/struct.Message.html - pub fn say(&self, text: &str) -> Result<Message> { + pub fn say(&self, content: &str) -> Result<Message> { if let Some(channel_id) = self.channel_id { - self.send_message(channel_id, text, "", false) + self.send_message(channel_id, |m| m.content(content)) } else { Err(Error::Client(ClientError::NoChannelId)) } @@ -896,19 +897,19 @@ impl Context { /// /// [`Channel`]: ../model/enum.Channel.html /// [`ClientError::MessageTooLong`]: enum.ClientError.html#variant.MessageTooLong - pub fn send_message<C>(&self, channel_id: C, content: &str, nonce: &str, tts: bool) - -> Result<Message> where C: Into<ChannelId> { - if let Some(length_over) = Message::overflow_length(content) { - return Err(Error::Client(ClientError::MessageTooLong(length_over))); + pub fn send_message<C, F>(&self, channel_id: C, f: F) -> Result<Message> + where C: Into<ChannelId>, F: FnOnce(CreateMessage) -> CreateMessage { + let map = f(CreateMessage::default()).0; + + if let Some(ref content) = map.get(&"content".to_owned()) { + if let &&Value::String(ref content) = content { + if let Some(length_over) = Message::overflow_length(&content) { + return Err(Error::Client(ClientError::MessageTooLong(length_over))); + } + } } - let map = ObjectBuilder::new() - .insert("content", content) - .insert("nonce", nonce) - .insert("tts", tts) - .build(); - - http::send_message(channel_id.into().0, map) + http::send_message(channel_id.into().0, Value::Object(map)) } pub fn set_game(&self, game: Option<Game>) { diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 985f03e..6295bc9 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -1,5 +1,5 @@ use std::sync::{Arc, Mutex}; -use std::{mem, thread}; +use std::thread; use super::event_store::EventStore; use super::login_type::LoginType; use super::{STATE, Connection, Context}; diff --git a/src/utils/builder/create_message.rs b/src/utils/builder/create_message.rs new file mode 100644 index 0000000..dc601a4 --- /dev/null +++ b/src/utils/builder/create_message.rs @@ -0,0 +1,71 @@ +use serde_json::Value; +use std::collections::BTreeMap; +use std::default::Default; + +/// A builder to specify the contents of an [`http::create_message`] request, +/// primarily meant for use through [`Context::send_message`]. +/// +/// `content` is the only required field. +/// +/// Note that if you only need to send the content of a message, without +/// specifying other fields, then [`Context::say`] may be a more preferable +/// option. +/// +/// # Examples +/// +/// Sending a message with a content of `test` and applying text-to-speech: +/// +/// ```rust,ignore +/// // assuming you are in a context +/// context.send_message(message.channel_id, |m| +/// .content("test") +/// .tts(true)); +/// ``` +/// +/// [`Context::say`]: ../../client/struct.Context.html#method.say +/// [`Context::send_message`]: ../../client/struct.Context.html#method.send_message +/// [`http::create_message`]: ../../client/http/fn.create_message.html +pub struct CreateMessage(pub BTreeMap<String, Value>); + +impl CreateMessage { + /// Set the content of the message. + /// + /// **Note**: Message contents must be under 2000 unicode code points. + pub fn content(mut self, content: &str) -> Self { + self.0.insert("content".to_owned(), Value::String(content.to_owned())); + + CreateMessage(self.0) + } + + /// Set the nonce. This is used for validation of a sent message. You most + /// likely don't need to worry about this. + /// + /// Defaults to empty. + pub fn nonce(mut self, nonce: &str) -> Self { + self.0.insert("nonce".to_owned(), Value::String(nonce.to_owned())); + + CreateMessage(self.0) + } + + /// Set whether the message is text-to-speech. + /// + /// Think carefully before setting this to `true`. + /// + /// Defaults to `false`. + pub fn tts(mut self, tts: bool) -> Self { + self.0.insert("tts".to_owned(), Value::Bool(tts)); + + CreateMessage(self.0) + } +} + +impl Default for CreateMessage { + /// Creates a map for sending a [`Message`], setting `tts` to `false` by + /// default. + fn default() -> CreateMessage { + let mut map = BTreeMap::default(); + map.insert("tts".to_owned(), Value::Bool(false)); + + CreateMessage(map) + } +} diff --git a/src/utils/builder/mod.rs b/src/utils/builder/mod.rs index cd830fa..91ad940 100644 --- a/src/utils/builder/mod.rs +++ b/src/utils/builder/mod.rs @@ -7,6 +7,7 @@ mod create_embed; mod create_invite; +mod create_message; mod edit_channel; mod edit_guild; mod edit_member; @@ -17,6 +18,7 @@ mod get_messages; pub use self::create_embed::CreateEmbed; pub use self::create_invite::CreateInvite; +pub use self::create_message::CreateMessage; pub use self::edit_channel::EditChannel; pub use self::edit_guild::EditGuild; pub use self::edit_member::EditMember; |