diff options
| author | Ken Swenson <[email protected]> | 2018-11-25 14:13:40 -0800 |
|---|---|---|
| committer | Alex M. M <[email protected]> | 2018-11-25 23:13:40 +0100 |
| commit | 9a07cc05708e43f1f5777c353b41830bd414e5af (patch) | |
| tree | d6340432099c1daf960186be58d9449128c454bb | |
| parent | Fix links in `Event` (diff) | |
| download | serenity-9a07cc05708e43f1f5777c353b41830bd414e5af.tar.xz serenity-9a07cc05708e43f1f5777c353b41830bd414e5af.zip | |
Change all builders to mutably borrow (#443)
26 files changed, 326 insertions, 276 deletions
diff --git a/src/builder/create_embed.rs b/src/builder/create_embed.rs index 29a253c..17025a2 100644 --- a/src/builder/create_embed.rs +++ b/src/builder/create_embed.rs @@ -49,11 +49,15 @@ impl CreateEmbed { /// information. /// /// [`CreateEmbedAuthor`]: struct.CreateEmbedAuthor.html - pub fn author<F>(&mut self, f: F) - where F: FnOnce(CreateEmbedAuthor) -> CreateEmbedAuthor { - let map = utils::vecmap_to_json_map(f(CreateEmbedAuthor::default()).0); + pub fn author<F>(&mut self, f: F) -> &mut Self + where F: FnOnce(&mut CreateEmbedAuthor) -> &mut CreateEmbedAuthor { + let mut author = CreateEmbedAuthor::default(); + f(&mut author); + + let map = utils::vecmap_to_json_map(author.0); self.0.insert("author", Value::Object(map)); + self } /// Set the colour of the left-hand side of the embed. @@ -63,15 +67,17 @@ impl CreateEmbed { /// [`colour`]: #method.colour #[cfg(feature = "utils")] #[inline] - pub fn color<C: Into<Colour>>(&mut self, colour: C) { + pub fn color<C: Into<Colour>>(&mut self, colour: C) -> &mut Self { self.colour(colour); + self } /// Set the colour of the left-hand side of the embed. #[cfg(feature = "utils")] #[inline] - pub fn colour<C: Into<Colour>>(&mut self, colour: C) { + pub fn colour<C: Into<Colour>>(&mut self, colour: C) -> &mut Self { self._colour(colour.into()); + self } #[cfg(feature = "utils")] @@ -89,22 +95,25 @@ impl CreateEmbed { /// [`colour`]: #method.colour #[cfg(not(feature = "utils"))] #[inline] - pub fn color(self, colour: u32) { + pub fn color(&mut self, colour: u32) -> &mut Self { self.colour(colour); + self } /// Set the colour of the left-hand side of the embed. #[cfg(not(feature = "utils"))] - pub fn colour(&mut self, colour: u32) { + pub fn colour(&mut self, colour: u32) -> &mut Self { self.0.insert("color", Value::Number(Number::from(colour))); + self } /// Set the description of the embed. /// /// **Note**: This can't be longer than 2048 characters. #[inline] - pub fn description<D: Display>(&mut self, description: D) { - self._description(description.to_string()) + pub fn description<D: Display>(&mut self, description: D) -> &mut Self { + self._description(description.to_string()); + self } fn _description(&mut self, description: String) { @@ -120,9 +129,10 @@ impl CreateEmbed { /// **Note**: Maximum amount of characters you can put is 256 in a field /// name and 1024 in a field value. #[inline] - pub fn field<T, U>(&mut self, name: T, value: U, inline: bool) + pub fn field<T, U>(&mut self, name: T, value: U, inline: bool) -> &mut Self where T: Display, U: Display { self._field(&name.to_string(), &value.to_string(), inline); + self } fn _field(&mut self, name: &str, value: &str, inline: bool) { @@ -146,13 +156,14 @@ impl CreateEmbed { /// This is sugar to reduce the need of calling [`field`] manually multiple times. /// /// [`field`]: #method.field - pub fn fields<T, U, It>(&mut self, fields: It) + pub fn fields<T, U, It>(&mut self, fields: It) -> &mut Self where It: IntoIterator<Item=(T, U, bool)>, T: Display, U: Display { for field in fields { self.field(field.0.to_string(), field.1.to_string(), field.2); } + self } /// Set the footer of the embed. @@ -161,26 +172,31 @@ impl CreateEmbed { /// information. /// /// [`CreateEmbedFooter`]: struct.CreateEmbedFooter.html - pub fn footer<F>(&mut self, f: F) - where F: FnOnce(CreateEmbedFooter) -> CreateEmbedFooter { - let footer = f(CreateEmbedFooter::default()).0; + pub fn footer<F>(&mut self, f: F) -> &mut Self + where F: FnOnce(&mut CreateEmbedFooter) -> &mut CreateEmbedFooter { + let mut create_embed_footer = CreateEmbedFooter::default(); + f(&mut create_embed_footer); + let footer = create_embed_footer.0; let map = utils::vecmap_to_json_map(footer); self.0.insert("footer", Value::Object(map)); + self } - fn url_object(&mut self, name: &'static str, url: &str) { + fn url_object(&mut self, name: &'static str, url: &str) -> &mut Self { let obj = json!({ "url": url.to_string() }); self.0.insert(name, obj); + self } /// Set the image associated with the embed. This only supports HTTP(S). #[inline] - pub fn image<S: AsRef<str>>(&mut self, url: S) { + pub fn image<S: AsRef<str>>(&mut self, url: S) -> &mut Self { self._image(url.as_ref()); + self } fn _image(&mut self, url: &str) { @@ -189,8 +205,9 @@ impl CreateEmbed { /// Set the thumbnail of the embed. This only supports HTTP(S). #[inline] - pub fn thumbnail<S: AsRef<str>>(&mut self, url: S) { + pub fn thumbnail<S: AsRef<str>>(&mut self, url: S) -> &mut Self { self._thumbnail(url.as_ref()); + self } fn _thumbnail(&mut self, url: &str) { @@ -220,14 +237,11 @@ impl CreateEmbed { /// struct Handler; /// /// impl EventHandler for Handler { - /// fn message(&self, _: Context, msg: Message) { + /// fn message(&self, _: Context, mut msg: Message) { /// if msg.content == "~embed" { - /// let _ = msg.channel_id.send_message(|mut m| { - /// m.embed(|mut e| { - /// e.title("hello"); - /// e.timestamp("2004-06-08T16:04:23"); - /// - /// e + /// let _ = msg.channel_id.send_message(|m| { + /// m.embed(|e| { + /// e.title("hello").timestamp("2004-06-08T16:04:23") /// }); /// /// m @@ -268,13 +282,10 @@ impl CreateEmbed { /// if let Some(channel) = channel_search { /// let user = member.user.read(); /// - /// let _ = channel.read().send_message(|mut m| { - /// m.embed(|mut e| { - /// e.author(|mut a| { - /// a.icon_url(&user.face()); - /// a.name(&user.name); - /// - /// a + /// let _ = channel.write().send_message(|m| { + /// m.embed(|e| { + /// e.author(|a| { + /// a.icon_url(&user.face()).name(&user.name) /// }); /// e.title("Member Join"); /// @@ -283,9 +294,7 @@ impl CreateEmbed { /// } /// /// e - /// }); - /// - /// m + /// }) /// }); /// } /// } @@ -297,8 +306,9 @@ impl CreateEmbed { /// client.start().unwrap(); /// ``` #[inline] - pub fn timestamp<T: Into<Timestamp>>(&mut self, timestamp: T) { + pub fn timestamp<T: Into<Timestamp>>(&mut self, timestamp: T) -> &mut Self { self._timestamp(timestamp.into()); + self } fn _timestamp(&mut self, timestamp: Timestamp) { @@ -307,8 +317,9 @@ impl CreateEmbed { /// Set the title of the embed. #[inline] - pub fn title<D: Display>(&mut self, title: D) { + pub fn title<D: Display>(&mut self, title: D) -> &mut Self { self._title(title.to_string()); + self } fn _title(&mut self, title: String) { @@ -317,8 +328,9 @@ impl CreateEmbed { /// Set the URL to direct to when clicking on the title. #[inline] - pub fn url<S: AsRef<str>>(&mut self, url: S) { + pub fn url<S: AsRef<str>>(&mut self, url: S) -> &mut Self { self._url(url.as_ref()); + self } fn _url(&mut self, url: &str) { @@ -334,8 +346,9 @@ impl CreateEmbed { /// /// [`image`]: #method.image #[inline] - pub fn attachment<S: AsRef<str>>(&mut self, filename: S) { + pub fn attachment<S: AsRef<str>>(&mut self, filename: S) -> &mut Self { self._attachment(filename.as_ref()); + self } fn _attachment(&mut self, filename: &str) { @@ -362,7 +375,7 @@ impl From<Embed> for CreateEmbed { b.colour(embed.colour); if let Some(author) = embed.author { - b.author(move |mut a| { + b.author(move |a| { a.name(&author.name); if let Some(icon_url) = author.icon_url { @@ -406,7 +419,7 @@ impl From<Embed> for CreateEmbed { } if let Some(footer) = embed.footer { - b.footer(move |mut f| { + b.footer(move |f| { f.text(&footer.text); if let Some(icon_url) = footer.icon_url { @@ -434,19 +447,24 @@ pub struct CreateEmbedAuthor(pub VecMap<&'static str, Value>); impl CreateEmbedAuthor { /// Set the URL of the author's icon. - pub fn icon_url(&mut self, icon_url: &str) { + pub fn icon_url(&mut self, icon_url: &str) -> &mut Self { self.0.insert("icon_url", Value::String(icon_url.to_string())); + self } /// Set the author's name. - pub fn name(&mut self, name: &str) { + pub fn name(&mut self, name: &str) -> &mut Self { self.0.insert("name", Value::String(name.to_string())); + self } /// Set the author's URL. - pub fn url(&mut self, url: &str) { + pub fn url(&mut self, url: &str) -> &mut Self { self.0.insert("url", Value::String(url.to_string())); + self } + + pub fn build(&mut self) {} } /// A builder to create a fake [`Embed`] object's footer, for use with the @@ -461,13 +479,15 @@ pub struct CreateEmbedFooter(pub VecMap<&'static str, Value>); impl CreateEmbedFooter { /// Set the icon URL's value. This only supports HTTP(S). - pub fn icon_url(&mut self, icon_url: &str) { + pub fn icon_url(&mut self, icon_url: &str) -> &mut Self { self.0.insert("icon_url", Value::String(icon_url.to_string())); + self } /// Set the footer's text. - pub fn text<D: Display>(&mut self, text: D) { + pub fn text<D: Display>(&mut self, text: D) -> &mut Self { self.0.insert("text", Value::String(text.to_string())); + self } } diff --git a/src/builder/create_invite.rs b/src/builder/create_invite.rs index 0b487b3..3eabcb6 100644 --- a/src/builder/create_invite.rs +++ b/src/builder/create_invite.rs @@ -33,11 +33,8 @@ use utils::VecMap; /// /// let reader = channel.read(); /// -/// let creation = reader.create_invite(|mut i| { -/// i.max_age(3600); -/// i.max_uses(10); -/// -/// i +/// let creation = reader.create_invite(|i| { +/// i.max_age(3600).max_uses(10) /// }); /// /// let invite = match creation { @@ -91,10 +88,8 @@ impl CreateInvite { /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap(); /// # let channel = channel.read(); /// # - /// let invite = channel.create_invite(|mut i| { - /// i.max_age(3600); - /// - /// i + /// let invite = channel.create_invite(|i| { + /// i.max_age(3600) /// })?; /// # Ok(()) /// # } @@ -103,8 +98,9 @@ impl CreateInvite { /// # try_main().unwrap(); /// # } /// ``` - pub fn max_age(&mut self, max_age: u64) { + pub fn max_age(&mut self, max_age: u64) -> &mut Self { self.0.insert("max_age", Value::Number(Number::from(max_age))); + self } /// The number of uses that the invite will be valid for. @@ -126,10 +122,8 @@ impl CreateInvite { /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap(); /// # let channel = channel.read(); /// # - /// let invite = channel.create_invite(|mut i| { - /// i.max_uses(5); - /// - /// i + /// let invite = channel.create_invite(|i| { + /// i.max_uses(5) /// })?; /// # Ok(()) /// # } @@ -138,8 +132,9 @@ impl CreateInvite { /// # try_main().unwrap(); /// # } /// ``` - pub fn max_uses(&mut self, max_uses: u64) { + pub fn max_uses(&mut self, max_uses: u64) -> &mut Self { self.0.insert("max_uses", Value::Number(Number::from(max_uses))); + self } /// Whether an invite grants a temporary membership. @@ -159,10 +154,8 @@ impl CreateInvite { /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap(); /// # let channel = channel.read(); /// # - /// let invite = channel.create_invite(|mut i| { - /// i.temporary(true); - /// - /// i + /// let invite = channel.create_invite(|i| { + /// i.temporary(true) /// })?; /// # Ok(()) /// # } @@ -171,8 +164,9 @@ impl CreateInvite { /// # try_main().unwrap(); /// # } /// ``` - pub fn temporary(&mut self, temporary: bool) { + pub fn temporary(&mut self, temporary: bool) -> &mut Self { self.0.insert("temporary", Value::Bool(temporary)); + self } /// Whether or not to try to reuse a similar invite. @@ -192,10 +186,8 @@ impl CreateInvite { /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap(); /// # let channel = channel.read(); /// # - /// let invite = channel.create_invite(|mut i| { - /// i.unique(true); - /// - /// i + /// let invite = channel.create_invite(|i| { + /// i.unique(true) /// })?; /// # Ok(()) /// # } @@ -204,8 +196,9 @@ impl CreateInvite { /// # try_main().unwrap(); /// # } /// ``` - pub fn unique(&mut self, unique: bool) { + pub fn unique(&mut self, unique: bool) -> &mut Self { self.0.insert("unique", Value::Bool(unique)); + self } } diff --git a/src/builder/create_message.rs b/src/builder/create_message.rs index aa1a23c..16c183b 100644 --- a/src/builder/create_message.rs +++ b/src/builder/create_message.rs @@ -27,7 +27,7 @@ use utils::{self, VecMap}; /// /// let channel_id = ChannelId(7); /// -/// let _ = channel_id.send_message(|mut m| { +/// let _ = channel_id.send_message(|m| { /// m.content("test"); /// m.tts(true); /// @@ -55,8 +55,9 @@ impl<'a> CreateMessage<'a> { /// /// **Note**: Message contents must be under 2000 unicode code points. #[inline] - pub fn content<D: Display>(&mut self, content: D) { + pub fn content<D: Display>(&mut self, content: D) -> &mut Self { self._content(content.to_string()); + self } fn _content(&mut self, content: String) { @@ -64,11 +65,15 @@ impl<'a> CreateMessage<'a> { } /// Set an embed for the message. - pub fn embed<F: FnOnce(CreateEmbed) -> CreateEmbed>(&mut self, f: F) { - let map = utils::vecmap_to_json_map(f(CreateEmbed::default()).0); + pub fn embed<F>(&mut self, f: F) -> &mut Self + where F: FnOnce(&mut CreateEmbed) -> &mut CreateEmbed { + let mut embed = CreateEmbed::default(); + f(&mut embed); + let map = utils::vecmap_to_json_map(embed.0); let embed = Value::Object(map); self.0.insert("embed", embed); + self } /// Set whether the message is text-to-speech. @@ -76,14 +81,16 @@ impl<'a> CreateMessage<'a> { /// Think carefully before setting this to `true`. /// /// Defaults to `false`. - pub fn tts(&mut self, tts: bool) { + pub fn tts(&mut self, tts: bool) -> &mut Self { self.0.insert("tts", Value::Bool(tts)); + self } /// Adds a list of reactions to create after the message's sent. #[inline] - pub fn reactions<R: Into<ReactionType>, It: IntoIterator<Item=R>>(&mut self, reactions: It) { + pub fn reactions<R: Into<ReactionType>, It: IntoIterator<Item=R>>(&mut self, reactions: It) -> &mut Self { self._reactions(reactions.into_iter().map(Into::into).collect()); + self } fn _reactions(&mut self, reactions: Vec<ReactionType>) { @@ -91,21 +98,24 @@ impl<'a> CreateMessage<'a> { } /// Appends a file to the message. - pub fn add_file<T: Into<AttachmentType<'a>>>(&mut self, file: T) { + pub fn add_file<T: Into<AttachmentType<'a>>>(&mut self, file: T) -> &mut Self { self.2.push(file.into()); + self } /// Appends a list of files to the message. - pub fn add_files<T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T>>(&mut self, files: It) { + pub fn add_files<T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T>>(&mut self, files: It) -> &mut Self { self.2.extend(files.into_iter().map(|f| f.into())); + self } /// Sets a list of files to include in the message. /// /// Calling this multiple times will overwrite the file list. /// To append files, call `add_file` or `add_files` instead. - pub fn files<T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T>>(&mut self, files: It) { + pub fn files<T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T>>(&mut self, files: It) -> &mut Self { self.2 = files.into_iter().map(|f| f.into()).collect(); + self } } diff --git a/src/builder/edit_channel.rs b/src/builder/edit_channel.rs index 4728abb..1e82916 100644 --- a/src/builder/edit_channel.rs +++ b/src/builder/edit_channel.rs @@ -28,20 +28,23 @@ impl EditChannel { /// This is for [voice] channels only. /// /// [voice]: ../model/channel/enum.ChannelType.html#variant.Voice - pub fn bitrate(&mut self, bitrate: u64) { + pub fn bitrate(&mut self, bitrate: u64) -> &mut Self { self.0.insert("bitrate", Value::Number(Number::from(bitrate))); + self } /// The name of the channel. /// /// Must be between 2 and 100 characters long. - pub fn name(&mut self, name: &str) { + pub fn name(&mut self, name: &str) -> &mut Self { self.0.insert("name", Value::String(name.to_string())); + self } /// The position of the channel in the channel list. - pub fn position(&mut self, position: u64) { + pub fn position(&mut self, position: u64) -> &mut Self { self.0.insert("position", Value::Number(Number::from(position))); + self } /// The topic of the channel. Can be empty. @@ -51,8 +54,9 @@ impl EditChannel { /// This is for [text] channels only. /// /// [text]: ../model/channel/enum.ChannelType.html#variant.Text - pub fn topic(&mut self, topic: &str) { + pub fn topic(&mut self, topic: &str) -> &mut Self { self.0.insert("topic", Value::String(topic.to_string())); + self } /// The number of users that may be in the channel simultaneously. @@ -60,8 +64,9 @@ impl EditChannel { /// This is for [voice] channels only. /// /// [voice]: ../model/channel/enum.ChannelType.html#variant.Voice - pub fn user_limit(&mut self, user_limit: u64) { + pub fn user_limit(&mut self, user_limit: u64) -> &mut Self { self.0.insert("user_limit", Value::Number(Number::from(user_limit))); + self } /// The parent category of the channel. @@ -71,8 +76,9 @@ impl EditChannel { /// [text]: ../model/channel/enum.ChannelType.html#variant.Text /// [voice]: ../model/channel/enum.ChannelType.html#variant.Voice #[inline] - pub fn category<C: Into<Option<ChannelId>>>(&mut self, category: C) { + pub fn category<C: Into<Option<ChannelId>>>(&mut self, category: C) -> &mut Self { self._category(category.into()); + self } fn _category(&mut self, category: Option<ChannelId>) { @@ -86,7 +92,7 @@ impl EditChannel { /// /// **Info**: Only values from 0 to 120 are valid. #[inline] - pub fn slow_mode_rate(mut self, seconds: u64) -> Self { + pub fn slow_mode_rate(&mut self, seconds: u64) -> &mut Self { self.0.insert("rate_limit_per_user", Value::Number(Number::from(seconds))); self diff --git a/src/builder/edit_guild.rs b/src/builder/edit_guild.rs index 13ec226..a5b9a2b 100644 --- a/src/builder/edit_guild.rs +++ b/src/builder/edit_guild.rs @@ -24,8 +24,9 @@ impl EditGuild { /// /// [`afk_timeout`]: #method.afk_timeout #[inline] - pub fn afk_channel<C: Into<ChannelId>>(&mut self, channel: Option<C>) { + pub fn afk_channel<C: Into<ChannelId>>(&mut self, channel: Option<C>) -> &mut Self { self._afk_channel(channel.map(Into::into)); + self } fn _afk_channel(&mut self, channel: Option<ChannelId>) { @@ -42,11 +43,12 @@ impl EditGuild { /// configured via [`afk_channel`] - after being AFK. /// /// [`afk_channel`]: #method.afk_channel - pub fn afk_timeout(&mut self, timeout: u64) { + pub fn afk_timeout(&mut self, timeout: u64) -> &mut Self { self.0.insert( "afk_timeout", Value::Number(Number::from(timeout)), ); + self } /// Set the icon of the guild. Pass `None` to remove the icon. @@ -69,9 +71,7 @@ impl EditGuild { /// let base64_icon = utils::read_image("./guild_icon.png")?; /// /// guild.edit(|mut g| { - /// g.icon(Some(&base64_icon)); - /// - /// g + /// g.icon(Some(&base64_icon)) /// })?; /// # Ok(()) /// # } @@ -82,26 +82,29 @@ impl EditGuild { /// ``` /// /// [`utils::read_image`]: ../utils/fn.read_image.html - pub fn icon(&mut self, icon: Option<&str>) { + pub fn icon(&mut self, icon: Option<&str>) -> &mut Self { self.0.insert( "icon", icon.map_or_else(|| Value::Null, |x| Value::String(x.to_string())), ); + self } /// Set the name of the guild. /// /// **Note**: Must be between (and including) 2-100 chracters. - pub fn name(&mut self, name: &str) { + pub fn name(&mut self, name: &str) -> &mut Self { self.0.insert("name", Value::String(name.to_string())); + self } /// Transfers the ownership of the guild to another user by Id. /// /// **Note**: The current user must be the owner of the guild. #[inline] - pub fn owner<U: Into<UserId>>(&mut self, user_id: U) { + pub fn owner<U: Into<UserId>>(&mut self, user_id: U) -> &mut Self { self._owner(user_id.into()); + self } fn _owner(&mut self, user_id: UserId) { @@ -125,10 +128,8 @@ impl EditGuild { /// /// // assuming a `guild` has already been bound /// - /// guild.edit(|mut g| { - /// g.region(Region::UsWest); - /// - /// g + /// guild.edit(|g| { + /// g.region(Region::UsWest) /// })?; /// # Ok(()) /// # } @@ -139,8 +140,9 @@ impl EditGuild { /// ``` /// /// [`Region::UsWest`]: ../model/guild/enum.Region.html#variant.UsWest - pub fn region(&mut self, region: Region) { + pub fn region(&mut self, region: Region) -> &mut Self { self.0.insert("region", Value::String(region.name().to_string())); + self } /// Set the splash image of the guild on the invitation page. @@ -149,9 +151,10 @@ impl EditGuild { /// You can check this through a guild's [`features`] list. /// /// [`features`]: ../model/guild/struct.Guild.html#structfield.features - pub fn splash(&mut self, splash: Option<&str>) { + pub fn splash(&mut self, splash: Option<&str>) -> &mut Self { let splash = splash.map_or(Value::Null, |x| Value::String(x.to_string())); self.0.insert("splash", splash); + self } /// Set the verification level of the guild. This can restrict what a @@ -170,10 +173,8 @@ impl EditGuild { /// /// // assuming a `guild` has already been bound /// - /// let edit = guild.edit(|mut g| { - /// g.verification_level(VerificationLevel::High); - /// - /// g + /// let edit = guild.edit(|g| { + /// g.verification_level(VerificationLevel::High) /// }); /// /// if let Err(why) = edit { @@ -183,10 +184,8 @@ impl EditGuild { /// // additionally, you may pass in just an integer of the verification /// // level /// - /// let edit = guild.edit(|mut g| { - /// g.verification_level(3); - /// - /// g + /// let edit = guild.edit(|g| { + /// g.verification_level(3) /// }); /// /// if let Err(why) = edit { @@ -197,9 +196,10 @@ impl EditGuild { /// [`VerificationLevel`]: ../model/guild/enum.VerificationLevel.html /// [`VerificationLevel::High`]: ../model/guild/enum.VerificationLevel.html#variant.High #[inline] - pub fn verification_level<V>(&mut self, verification_level: V) + pub fn verification_level<V>(&mut self, verification_level: V) -> &mut Self where V: Into<VerificationLevel> { self._verification_level(verification_level.into()); + self } fn _verification_level(&mut self, verification_level: VerificationLevel) { diff --git a/src/builder/edit_member.rs b/src/builder/edit_member.rs index 2b6674b..42d8e9f 100644 --- a/src/builder/edit_member.rs +++ b/src/builder/edit_member.rs @@ -16,8 +16,9 @@ impl EditMember { /// Requires the [Deafen Members] permission. /// /// [Deafen Members]: ../model/permissions/struct.Permissions.html#associatedconstant.DEAFEN_MEMBERS - pub fn deafen(&mut self, deafen: bool) { + pub fn deafen(&mut self, deafen: bool) -> &mut Self { self.0.insert("deaf", Value::Bool(deafen)); + self } /// Whether to mute the member. @@ -25,8 +26,9 @@ impl EditMember { /// Requires the [Mute Members] permission. /// /// [Mute Members]: ../model/permissions/struct.Permissions.html#associatedconstant.MUTE_MEMBERS - pub fn mute(&mut self, mute: bool) { + pub fn mute(&mut self, mute: bool) -> &mut Self { self.0.insert("mute", Value::Bool(mute)); + self } /// Changes the member's nickname. Pass an empty string to reset the @@ -35,8 +37,9 @@ impl EditMember { /// Requires the [Manage Nicknames] permission. /// /// [Manage Nicknames]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_NICKNAMES - pub fn nickname(&mut self, nickname: &str) { + pub fn nickname(&mut self, nickname: &str) -> &mut Self { self.0.insert("nick", Value::String(nickname.to_string())); + self } /// Set the list of roles that the member should have. @@ -44,13 +47,14 @@ impl EditMember { /// Requires the [Manage Roles] permission to modify. /// /// [Manage Roles]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES - pub fn roles<T: AsRef<RoleId>, It: IntoIterator<Item=T>>(&mut self, roles: It) { + pub fn roles<T: AsRef<RoleId>, It: IntoIterator<Item=T>>(&mut self, roles: It) -> &mut Self { let role_ids = roles .into_iter() .map(|x| Value::Number(Number::from(x.as_ref().0))) .collect(); self._roles(role_ids); + self } fn _roles(&mut self, roles: Vec<Value>) { diff --git a/src/builder/edit_message.rs b/src/builder/edit_message.rs index 74d7123..ba6d14c 100644 --- a/src/builder/edit_message.rs +++ b/src/builder/edit_message.rs @@ -14,10 +14,8 @@ use utils::{self, VecMap}; /// # /// # let mut message = ChannelId(7).message(MessageId(8)).unwrap(); /// # -/// let _ = message.edit(|mut m| { -/// m.content("hello"); -/// -/// m +/// let _ = message.edit(|m| { +/// m.content("hello") /// }); /// ``` /// @@ -30,8 +28,9 @@ impl EditMessage { /// /// **Note**: Message contents must be under 2000 unicode code points. #[inline] - pub fn content<D: Display>(&mut self, content: D) { - self._content(content.to_string()) + pub fn content<D: Display>(&mut self, content: D) -> &mut Self { + self._content(content.to_string()); + self } fn _content(&mut self, content: String) { @@ -39,10 +38,14 @@ impl EditMessage { } /// Set an embed for the message. - pub fn embed<F: FnOnce(CreateEmbed) -> CreateEmbed>(&mut self, f: F) { - let map = utils::vecmap_to_json_map(f(CreateEmbed::default()).0); + pub fn embed<F>(&mut self, f: F) -> &mut Self + where F: FnOnce(&mut CreateEmbed) -> &mut CreateEmbed { + let mut create_embed = CreateEmbed::default(); + f(&mut create_embed); + let map = utils::vecmap_to_json_map(create_embed.0); let embed = Value::Object(map); self.0.insert("embed", embed); + self } } diff --git a/src/builder/edit_profile.rs b/src/builder/edit_profile.rs index 2efe77c..e51160a 100644 --- a/src/builder/edit_profile.rs +++ b/src/builder/edit_profile.rs @@ -35,9 +35,7 @@ impl EditProfile { /// .expect("Failed to read image"); /// /// let _ = context.edit_profile(|mut profile| { - /// profile.avatar(Some(&base64)); - /// - /// profile + /// profile.avatar(Some(&base64)) /// }); /// # } /// } @@ -48,10 +46,11 @@ impl EditProfile { /// ``` /// /// [`utils::read_image`]: ../utils/fn.read_image.html - pub fn avatar(&mut self, avatar: Option<&str>) { + pub fn avatar(&mut self, avatar: Option<&str>) -> &mut Self { let avatar = avatar.map_or(Value::Null, |x| Value::String(x.to_string())); self.0.insert("avatar", avatar); + self } /// Modifies the current user's email address. @@ -64,9 +63,8 @@ impl EditProfile { /// **Note**: This can only be used by user accounts. /// /// [provided]: #method.password - pub fn email(mut self, email: &str) -> Self { + pub fn email(&mut self, email: &str) -> &mut Self { self.0.insert("email", Value::String(email.to_string())); - self } @@ -76,8 +74,9 @@ impl EditProfile { /// [provided]. /// /// [provided]: #method.password - pub fn new_password(&mut self, new_password: &str) { + pub fn new_password(&mut self, new_password: &str) -> &mut Self { self.0.insert("new_password", Value::String(new_password.to_string())); + self } /// Used for providing the current password as verification when @@ -85,8 +84,9 @@ impl EditProfile { /// /// [modifying the password]: #method.new_password /// [modifying the associated email address]: #method.email - pub fn password(&mut self, password: &str) { + pub fn password(&mut self, password: &str) -> &mut Self { self.0.insert("password", Value::String(password.to_string())); + self } /// Modifies the current user's username. @@ -95,7 +95,8 @@ impl EditProfile { /// and current discriminator, a new unique discriminator will be assigned. /// If there are no available discriminators with the requested username, /// an error will occur. - pub fn username(&mut self, username: &str) { + pub fn username(&mut self, username: &str) -> &mut Self { self.0.insert("username", Value::String(username.to_string())); + self } } diff --git a/src/builder/edit_role.rs b/src/builder/edit_role.rs index c23f010..96f12fe 100644 --- a/src/builder/edit_role.rs +++ b/src/builder/edit_role.rs @@ -28,12 +28,8 @@ use utils::VecMap; /// # /// // assuming a `channel_id` and `guild_id` has been bound /// -/// let role = guild_id.create_role(|mut r| { -/// r.hoist(true); -/// r.mentionable(true); -/// r.name("a test role"); -/// -/// r +/// let role = guild_id.create_role(|r| { +/// r.hoist(true).mentionable(true).name("a test role") /// }); /// ``` /// @@ -75,37 +71,43 @@ impl EditRole { } /// Sets the colour of the role. - pub fn colour(&mut self, colour: u64) { + pub fn colour(&mut self, colour: u64) -> &mut Self { self.0.insert("color", Value::Number(Number::from(colour))); + self } /// Whether or not to hoist the role above lower-positioned role in the user /// list. - pub fn hoist(&mut self, hoist: bool) { + pub fn hoist(&mut self, hoist: bool) -> &mut Self { self.0.insert("hoist", Value::Bool(hoist)); + self } /// Whether or not to make the role mentionable, notifying its users. - pub fn mentionable(&mut self, mentionable: bool) { + pub fn mentionable(&mut self, mentionable: bool) -> &mut Self { self.0.insert("mentionable", Value::Bool(mentionable)); + self } /// The name of the role to set. - pub fn name(&mut self, name: &str) { + pub fn name(&mut self, name: &str) -> &mut Self { self.0.insert("name", Value::String(name.to_string())); + self } /// The set of permissions to assign the role. - pub fn permissions(&mut self, permissions: Permissions) { + pub fn permissions(&mut self, permissions: Permissions) -> &mut Self { self.0.insert( "permissions", Value::Number(Number::from(permissions.bits())), ); + self } /// The position to assign the role in the role list. This correlates to the /// role's position in the user list. - pub fn position(&mut self, position: u8) { + pub fn position(&mut self, position: u8) -> &mut Self { self.0.insert("position", Value::Number(Number::from(position))); + self } } diff --git a/src/builder/execute_webhook.rs b/src/builder/execute_webhook.rs index 821c125..b326564 100644 --- a/src/builder/execute_webhook.rs +++ b/src/builder/execute_webhook.rs @@ -26,29 +26,21 @@ use utils::VecMap; /// let webhook = http::get_webhook_with_token(id, token) /// .expect("valid webhook"); /// -/// let website = Embed::fake(|mut e| { -/// e.title("The Rust Language Website"); -/// e.description("Rust is a systems programming language."); -/// e.colour(Colour::from_rgb(222, 165, 132)); -/// -/// e +/// let website = Embed::fake(|e| { +/// e.title("The Rust Language Website") +/// .description("Rust is a systems programming language.") +/// .colour(Colour::from_rgb(222, 165, 132)) /// }); /// -/// let resources = Embed::fake(|mut e| { -/// e.title("Rust Resources"); -/// e.description("A few resources to help with learning Rust"); -/// e.colour(0xDEA584); -/// e.field("The Rust Book", "A comprehensive resource for Rust.", false); -/// e.field("Rust by Example", "A collection of Rust examples", false); -/// -/// e +/// let resources = Embed::fake(|e| { +/// e.title("Rust Resources") +/// .description("A few resources to help with learning Rust") +/// .colour(0xDEA584).field("The Rust Book", "A comprehensive resource for Rust.", false) +/// .field("Rust by Example", "A collection of Rust examples", false) /// }); /// -/// let _ = webhook.execute(false, |mut w| { -/// w.content("Here's some information on Rust:"); -/// w.embeds(vec![website, resources]); -/// -/// w +/// let _ = webhook.execute(false, |w| { +/// w.content("Here's some information on Rust:").embeds(vec![website, resources]) /// }); /// ``` /// @@ -72,15 +64,13 @@ impl ExecuteWebhook { /// # /// let avatar_url = "https://i.imgur.com/KTs6whd.jpg"; /// - /// let _ = webhook.execute(false, |mut w| { - /// w.avatar_url(avatar_url); - /// w.content("Here's a webhook"); - /// - /// w + /// let _ = webhook.execute(false, |w| { + /// w.avatar_url(avatar_url).content("Here's a webhook") /// }); /// ``` - pub fn avatar_url(&mut self, avatar_url: &str) { + pub fn avatar_url(&mut self, avatar_url: &str) -> &mut Self { self.0.insert("avatar_url", Value::String(avatar_url.to_string())); + self } /// Set the content of the message. @@ -97,10 +87,8 @@ impl ExecuteWebhook { /// # /// # let webhook = rest::get_webhook_with_token(0, "").unwrap(); /// # - /// let execution = webhook.execute(false, |mut w| { - /// w.content("foo"); - /// - /// w + /// let execution = webhook.execute(false, |w| { + /// w.content("foo") /// }); /// /// if let Err(why) = execution { @@ -109,8 +97,9 @@ impl ExecuteWebhook { /// ``` /// /// [`embeds`]: #method.embeds - pub fn content(&mut self, content: &str) { + pub fn content(&mut self, content: &str) -> &mut Self { self.0.insert("content", Value::String(content.to_string())); + self } /// Set the embeds associated with the message. @@ -126,8 +115,9 @@ impl ExecuteWebhook { /// [`Embed::fake`]: ../model/channel/struct.Embed.html#method.fake /// [`Webhook::execute`]: ../model/webhook/struct.Webhook.html#method.execute /// [struct-level documentation]: #examples - pub fn embeds(&mut self, embeds: Vec<Value>) { + pub fn embeds(&mut self, embeds: Vec<Value>) -> &mut Self { self.0.insert("embeds", Value::Array(embeds)); + self } /// Whether the message is a text-to-speech message. @@ -141,19 +131,17 @@ impl ExecuteWebhook { /// # /// # let webhook = rest::get_webhook_with_token(0, "").unwrap(); /// # - /// let execution = webhook.execute(false, |mut w| { - /// w.content("hello"); - /// w.tts(true); - /// - /// w + /// let execution = webhook.execute(false, |w| { + /// w.content("hello").tts(true) /// }); /// /// if let Err(why) = execution { /// println!("Err sending webhook: {:?}", why); /// } /// ``` - pub fn tts(&mut self, tts: bool) { + pub fn tts(&mut self, tts: bool) -> &mut Self { self.0.insert("tts", Value::Bool(tts)); + self } /// Override the default username of the webhook. @@ -167,19 +155,17 @@ impl ExecuteWebhook { /// # /// # let webhook = rest::get_webhook_with_token(0, "").unwrap(); /// # - /// let execution = webhook.execute(false, |mut w| { - /// w.content("hello"); - /// w.username("hakase"); - /// - /// w + /// let execution = webhook.execute(false, |w| { + /// w.content("hello").username("hakase") /// }); /// /// if let Err(why) = execution { /// println!("Err sending webhook: {:?}", why); /// } /// ``` - pub fn username(&mut self, username: &str) { + pub fn username(&mut self, username: &str) -> &mut Self { self.0.insert("username", Value::String(username.to_string())); + self } } diff --git a/src/builder/get_messages.rs b/src/builder/get_messages.rs index 644dc44..0b809d6 100644 --- a/src/builder/get_messages.rs +++ b/src/builder/get_messages.rs @@ -34,11 +34,8 @@ use utils::VecMap; /// // you can then pass it into a function which retrieves messages: /// let channel_id = ChannelId(81384788765712384); /// -/// let _messages = channel_id.messages(|mut retriever| { -/// retriever.after(MessageId(158339864557912064)); -/// retriever.limit(25); -/// -/// retriever +/// let _messages = channel_id.messages(|retriever| { +/// retriever.after(MessageId(158339864557912064)).limit(25) /// })?; /// # Ok(()) /// # } @@ -56,8 +53,9 @@ impl GetMessages { /// Indicates to retrieve the messages after a specific message, given by /// its Id. #[inline] - pub fn after<M: Into<MessageId>>(&mut self, message_id: M) { + pub fn after<M: Into<MessageId>>(&mut self, message_id: M) -> &mut Self { self._after(message_id.into()); + self } fn _after(&mut self, message_id: MessageId) { @@ -67,8 +65,9 @@ impl GetMessages { /// Indicates to retrieve the messages _around_ a specific message in either /// direction (before+after) the given message. #[inline] - pub fn around<M: Into<MessageId>>(&mut self, message_id: M) { + pub fn around<M: Into<MessageId>>(&mut self, message_id: M) -> &mut Self { self._around(message_id.into()); + self } fn _around(&mut self, message_id: MessageId) { @@ -78,8 +77,9 @@ impl GetMessages { /// Indicates to retrieve the messages before a specific message, given by /// its Id. #[inline] - pub fn before<M: Into<MessageId>>(&mut self, message_id: M) { + pub fn before<M: Into<MessageId>>(&mut self, message_id: M) -> &mut Self { self._before(message_id.into()); + self } fn _before(&mut self, message_id: MessageId) { @@ -93,8 +93,9 @@ impl GetMessages { /// **Note**: This field is capped to 100 messages due to a Discord /// limitation. If an amount larger than 100 is supplied, it will be /// reduced. - pub fn limit(&mut self, limit: u64) { + pub fn limit(&mut self, limit: u64) -> &mut Self { self.0.insert("limit", if limit > 100 { 100 } else { limit }); + self } /// This is a function that is here for completeness. You do not need to diff --git a/src/client/context.rs b/src/client/context.rs index 9ca4f55..04fe642 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -88,7 +88,8 @@ impl Context { /// ``` #[cfg(feature = "builder")] #[deprecated(since = "0.5.6", note = "Use the http module instead.")] - pub fn edit_profile<F: FnOnce(EditProfile) -> EditProfile>(&self, f: F) -> Result<CurrentUser> { + pub fn edit_profile<F>(&self, f: F) -> Result<CurrentUser> + where F: FnOnce(&mut EditProfile) -> &mut EditProfile { let mut map = VecMap::with_capacity(2); feature_cache! { @@ -111,7 +112,10 @@ impl Context { } } - let edited = vecmap_to_json_map(f(EditProfile(map)).0); + let mut edit_profile = EditProfile(map); + f(&mut edit_profile); + + let edited = vecmap_to_json_map(edit_profile.0); http::edit_profile(&edited) } diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs index d84e375..78fedf8 100644 --- a/src/framework/standard/help_commands.rs +++ b/src/framework/standard/help_commands.rs @@ -624,8 +624,8 @@ fn send_grouped_commands_embed( groups: &[GroupCommandsPair], colour: Colour, ) -> Result<Message, Error> { - channel_id.send_message(|mut m| { - m.embed(|mut embed| { + channel_id.send_message(|m| { + m.embed(|embed| { embed.colour(colour); embed.description(help_description); @@ -658,8 +658,8 @@ fn send_single_command_embed( command: &Command, colour: Colour, ) -> Result<Message, Error> { - channel_id.send_message(|mut m| { - m.embed(|mut embed| { + channel_id.send_message(|m| { + m.embed(|embed| { embed.title(&command.name); embed.colour(colour); @@ -703,8 +703,8 @@ fn send_suggestion_embed( ) -> Result<Message, Error> { let text = format!("{}", help_description.replace("{}", &suggestions.join("`, `"))); - channel_id.send_message(|mut m| { - m.embed(|mut e| { + channel_id.send_message(|m| { + m.embed(|e| { e.colour(colour); e.description(text); e @@ -715,8 +715,8 @@ fn send_suggestion_embed( /// Sends an embed explaining fetching commands failed. fn send_error_embed(channel_id: ChannelId, input: &str, colour: Colour) -> Result<Message, Error> { - channel_id.send_message(|mut m| { - m.embed(|mut e| { + channel_id.send_message(|m| { + m.embed(|e| { e.colour(colour); e.description(input); e diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs index 9c813d6..e0d280d 100644 --- a/src/framework/standard/mod.rs +++ b/src/framework/standard/mod.rs @@ -400,7 +400,7 @@ impl StandardFramework { /// }) /// .command("ping", |c| c /// .bucket("basic") - /// .exec(|_, msg, _| { + /// .exec(|_, mut msg, _| { /// msg.channel_id.say("pong!")?; /// /// Ok(()) @@ -670,7 +670,7 @@ impl StandardFramework { /// # /// use serenity::framework::StandardFramework; /// - /// client.with_framework(StandardFramework::new().on("ping", |_, msg, _| { + /// client.with_framework(StandardFramework::new().on("ping", |_, mut msg, _| { /// msg.channel_id.say("pong!")?; /// /// Ok(()) @@ -1285,7 +1285,7 @@ impl Framework for StandardFramework { // `Message`, else we can avoid it. if let &Some(ref message_without_command) = &self.message_without_command { let mut context_unrecognised = context.clone(); - let message_unrecognised = message.clone(); + let mut message_unrecognised = message.clone(); let unrecognised_command = unrecognised_command.clone(); threadpool.execute(move || { diff --git a/src/model/channel/attachment.rs b/src/model/channel/attachment.rs index 1ba256f..4fd6305 100644 --- a/src/model/channel/attachment.rs +++ b/src/model/channel/attachment.rs @@ -53,7 +53,7 @@ impl Attachment { /// struct Handler; /// /// impl EventHandler for Handler { - /// fn message(&self, _: Context, message: Message) { + /// fn message(&self, _: Context, mut message: Message) { /// for attachment in message.attachments { /// let content = match attachment.download() { /// Ok(content) => content, diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs index 66798fa..7314594 100644 --- a/src/model/channel/channel_id.rs +++ b/src/model/channel/channel_id.rs @@ -355,8 +355,10 @@ impl ChannelId { /// [`Channel::messages`]: ../channel/enum.Channel.html#method.messages /// [Read Message History]: ../permissions/struct.Permissions.html#associatedconstant.READ_MESSAGE_HISTORY pub fn messages<F>(&self, f: F) -> Result<Vec<Message>> - where F: FnOnce(GetMessages) -> GetMessages { - let mut map = f(GetMessages::default()).0; + where F: FnOnce(&mut GetMessages) -> &mut GetMessages { + let mut get_messages = GetMessages::default(); + f(&mut get_messages); + let mut map = get_messages.0; let mut query = format!("?limit={}", map.remove(&"limit").unwrap_or(50)); if let Some(after) = map.remove(&"after") { @@ -481,11 +483,10 @@ impl ChannelId { /// [`ChannelId`]: struct.ChannelId.html /// [`ModelError::MessageTooLong`]: ../error/enum.Error.html#variant.MessageTooLong #[inline] - pub fn say<D: ::std::fmt::Display>(&self, content: D) -> Result<Message> { - self.send_message(|mut m| { - m.content(content); - - m + pub fn say<D>(&self, content: D) -> Result<Message> + where D: ::std::fmt::Display { + self.send_message(|m| { + m.content(content) }) } @@ -510,10 +511,8 @@ impl ChannelId { /// /// let paths = vec!["/path/to/file.jpg", "path/to/file2.jpg"]; /// - /// let _ = channel_id.send_files(paths, |mut m| { - /// m.content("a file"); - /// - /// m + /// let _ = channel_id.send_files(paths, |m| { + /// m.content("a file") /// }); /// ``` /// @@ -530,10 +529,8 @@ impl ChannelId { /// /// let files = vec![(&f1, "my_file.jpg"), (&f2, "my_file2.jpg")]; /// - /// let _ = channel_id.send_files(files, |mut m| { - /// m.content("a file"); - /// - /// m + /// let _ = channel_id.send_files(files, |m| { + /// m.content("a file") /// }); /// ``` /// @@ -554,9 +551,12 @@ impl ChannelId { /// [Attach Files]: ../permissions/struct.Permissions.html#associatedconstant.ATTACH_FILES /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[cfg(feature = "utils")] - pub fn send_files<'a, F, T, It: IntoIterator<Item=T>>(&self, files: It, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage, T: Into<AttachmentType<'a>> { - let mut msg = f(CreateMessage::default()); + pub fn send_files<'a, F, T, It>(&self, files: It, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b>, + T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T> { + let mut create_message = CreateMessage::default(); + let msg = f(&mut create_message); + if let Some(content) = msg.0.get(&"content") { if let Value::String(ref content) = *content { @@ -570,7 +570,7 @@ impl ChannelId { msg.0.insert("payload_json", json!({ "embed": e })); } - let map = utils::vecmap_to_json_map(msg.0); + let map = utils::vecmap_to_json_map(msg.0.clone()); http::send_files(self.0, files, map) } @@ -595,8 +595,9 @@ impl ChannelId { /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[cfg(feature = "utils")] pub fn send_message<F>(&self, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage { - let mut msg = f(CreateMessage::default()); + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { + let mut create_message = CreateMessage::default(); + let msg = f(&mut create_message); if !msg.2.is_empty() { if let Some(e) = msg.0.remove(&"embed") { @@ -604,7 +605,7 @@ impl ChannelId { } } - let map = utils::vecmap_to_json_map(msg.0); + let map = utils::vecmap_to_json_map(msg.0.clone()); Message::check_content_length(&map)?; Message::check_embed_length(&map)?; @@ -612,10 +613,10 @@ impl ChannelId { let message = if msg.2.is_empty() { http::send_message(self.0, &Value::Object(map))? } else { - http::send_files(self.0, msg.2, map)? + http::send_files(self.0, msg.2.clone(), map)? }; - if let Some(reactions) = msg.1 { + if let Some(reactions) = msg.1.clone() { for reaction in reactions { self.create_reaction(message.id, reaction)?; } diff --git a/src/model/channel/embed.rs b/src/model/channel/embed.rs index 8b2a98c..8ce7696 100644 --- a/src/model/channel/embed.rs +++ b/src/model/channel/embed.rs @@ -84,18 +84,18 @@ impl Embed { /// ```rust,no_run /// use serenity::model::channel::Embed; /// - /// let embed = Embed::fake(|mut e| { - /// e.title("Embed title"); - /// e.description("Making a basic embed"); - /// e.field("A field", "Has some content.", false); - /// - /// e + /// let embed = Embed::fake(|e| { + /// e.title("Embed title") + /// .description("Making a basic embed") + /// .field("A field", "Has some content.", false) /// }); /// ``` #[inline] pub fn fake<F>(f: F) -> Value - where F: FnOnce(CreateEmbed) -> CreateEmbed { - let map = utils::vecmap_to_json_map(f(CreateEmbed::default()).0); + where F: FnOnce(&mut CreateEmbed) -> &mut CreateEmbed { + let mut create_embed = CreateEmbed::default(); + f(&mut create_embed); + let map = utils::vecmap_to_json_map(create_embed.0); Value::Object(map) } diff --git a/src/model/channel/group.rs b/src/model/channel/group.rs index e6946df..5607f3c 100644 --- a/src/model/channel/group.rs +++ b/src/model/channel/group.rs @@ -200,7 +200,7 @@ impl Group { /// [Read Message History]: ../permissions/struct.Permissions.html#associatedconstant.READ_MESSAGE_HISTORY #[inline] pub fn messages<F>(&self, f: F) -> Result<Vec<Message>> - where F: FnOnce(GetMessages) -> GetMessages { + where F: FnOnce(&mut GetMessages) -> &mut GetMessages { self.channel_id.messages(f) } @@ -307,7 +307,7 @@ impl Group { /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[inline] pub fn send_files<'a, F, T, It: IntoIterator<Item=T>>(&self, files: It, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage, T: Into<AttachmentType<'a>> { + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b>, T: Into<AttachmentType<'a>> { self.channel_id.send_files(files, f) } @@ -321,7 +321,8 @@ impl Group { /// [`CreateMessage`]: ../../builder/struct.CreateMessage.html /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[inline] - pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { + pub fn send_message<F>(&self, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { self.channel_id.send_message(f) } diff --git a/src/model/channel/guild_channel.rs b/src/model/channel/guild_channel.rs index 046ca7c..e667efa 100644 --- a/src/model/channel/guild_channel.rs +++ b/src/model/channel/guild_channel.rs @@ -120,7 +120,7 @@ impl GuildChannel { /// ``` #[cfg(feature = "utils")] pub fn create_invite<F>(&self, f: F) -> Result<RichInvite> - where F: FnOnce(CreateInvite) -> CreateInvite { + where F: FnOnce(&mut CreateInvite) -> &mut CreateInvite { #[cfg(feature = "cache")] { let req = Permissions::CREATE_INVITE; @@ -129,8 +129,10 @@ impl GuildChannel { return Err(Error::Model(ModelError::InvalidPermissions(req))); } } + let mut invite = CreateInvite::default(); + f(&mut invite); - let map = serenity_utils::vecmap_to_json_map(f(CreateInvite::default()).0); + let map = serenity_utils::vecmap_to_json_map(invite.0); http::create_invite(self.id.0, &map) } @@ -419,7 +421,7 @@ impl GuildChannel { /// [Read Message History]: ../permissions/struct.Permissions.html#associatedconstant.READ_MESSAGE_HISTORY #[inline] pub fn messages<F>(&self, f: F) -> Result<Vec<Message>> - where F: FnOnce(GetMessages) -> GetMessages { + where F: FnOnce(&mut GetMessages) -> &mut GetMessages { self.id.messages(f) } @@ -473,7 +475,7 @@ impl GuildChannel { /// struct Handler; /// /// impl EventHandler for Handler { - /// fn message(&self, _: Context, msg: Message) { + /// fn message(&self, _: Context, mut msg: Message) { /// let channel = match CACHE.read().guild_channel(msg.channel_id) { /// Some(channel) => channel, /// None => return, @@ -601,8 +603,9 @@ impl GuildChannel { /// [Attach Files]: ../permissions/struct.Permissions.html#associatedconstant.ATTACH_FILES /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[inline] - pub fn send_files<'a, F, T, It: IntoIterator<Item=T>>(&self, files: It, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage, T: Into<AttachmentType<'a>> { + pub fn send_files<'a, F, T, It>(&self, files: It, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b>, + T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T> { self.id.send_files(files, f) } @@ -625,7 +628,8 @@ impl GuildChannel { /// [`ModelError::MessageTooLong`]: ../error/enum.Error.html#variant.MessageTooLong /// [`Message`]: struct.Message.html /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES - pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { + pub fn send_message<F>(&self, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { #[cfg(feature = "cache")] { let req = Permissions::SEND_MESSAGES; diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index 7a50b1f..0439c15 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -215,7 +215,7 @@ impl Message { /// [`EditMessage`]: ../../builder/struct.EditMessage.html /// [`the limit`]: ../../builder/struct.EditMessage.html#method.content pub fn edit<F>(&mut self, f: F) -> Result<()> - where F: FnOnce(EditMessage) -> EditMessage { + where F: FnOnce(&mut EditMessage) -> &mut EditMessage { #[cfg(feature = "cache")] { if self.author.id != CACHE.read().user.id { @@ -230,10 +230,16 @@ impl Message { } if let Some(embed) = self.embeds.get(0) { - builder.embed(|_| CreateEmbed::from(embed.clone())); + let mut embed = CreateEmbed::from(embed.clone()); + builder.embed( |e| { + *e = embed; + e + }); } - let map = serenity_utils::vecmap_to_json_map(f(builder).0); + f(&mut builder); + + let map = serenity_utils::vecmap_to_json_map(builder.0); match http::edit_message(self.channel_id.0, self.id.0, &Value::Object(map)) { Ok(edited) => { diff --git a/src/model/channel/private_channel.rs b/src/model/channel/private_channel.rs index 4d602c9..30defca 100644 --- a/src/model/channel/private_channel.rs +++ b/src/model/channel/private_channel.rs @@ -175,7 +175,7 @@ impl PrivateChannel { /// [Read Message History]: ../permissions/struct.Permissions.html#associatedconstant.READ_MESSAGE_HISTORY #[inline] pub fn messages<F>(&self, f: F) -> Result<Vec<Message>> - where F: FnOnce(GetMessages) -> GetMessages { + where F: FnOnce(&mut GetMessages) -> &mut GetMessages { self.id.messages(f) } @@ -249,8 +249,9 @@ impl PrivateChannel { /// [Attach Files]: ../permissions/struct.Permissions.html#associatedconstant.ATTACH_FILES /// [Send Messages]: ../permissions/struct.Permissions.html#associatedconstant.SEND_MESSAGES #[inline] - pub fn send_files<'a, F, T, It: IntoIterator<Item=T>>(&self, files: It, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage, T: Into<AttachmentType<'a>> { + pub fn send_files<'a, F, T, It>(&self, files: It, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b>, + T: Into<AttachmentType<'a>>, It: IntoIterator<Item=T> { self.id.send_files(files, f) } @@ -269,7 +270,8 @@ impl PrivateChannel { /// [`CreateMessage`]: ../../builder/struct.CreateMessage.html /// [`Message`]: struct.Message.html #[inline] - pub fn send_message<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { + pub fn send_message<F>(&self, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { self.id.send_message(f) } diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs index abb3262..a7872f5 100644 --- a/src/model/guild/guild_id.rs +++ b/src/model/guild/guild_id.rs @@ -191,8 +191,11 @@ impl GuildId { /// [`Guild::create_role`]: ../guild/struct.Guild.html#method.create_role /// [Manage Roles]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES #[inline] - pub fn create_role<F: FnOnce(EditRole) -> EditRole>(&self, f: F) -> Result<Role> { - let map = utils::vecmap_to_json_map(f(EditRole::default()).0); + pub fn create_role<F>(&self, f: F) -> Result<Role> + where F: FnOnce(&mut EditRole) -> &mut EditRole { + let mut edit_role = EditRole::default(); + f(&mut edit_role); + let map = utils::vecmap_to_json_map(edit_role.0); let role = http::create_role(self.0, &map)?; @@ -272,8 +275,11 @@ impl GuildId { /// [`Guild::edit`]: ../guild/struct.Guild.html#method.edit /// [Manage Guild]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_GUILD #[inline] - pub fn edit<F: FnOnce(EditGuild) -> EditGuild>(&mut self, f: F) -> Result<PartialGuild> { - let map = utils::vecmap_to_json_map(f(EditGuild::default()).0); + pub fn edit<F>(&mut self, f: F) -> Result<PartialGuild> + where F: FnOnce(&mut EditGuild) -> &mut EditGuild{ + let mut edit_guild = EditGuild::default(); + f(&mut edit_guild); + let map = utils::vecmap_to_json_map(edit_guild.0); http::edit_guild(self.0, &map) } diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index ada70da..3f1baad 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -418,7 +418,7 @@ impl Guild { /// [`Role`]: struct.Role.html /// [Manage Roles]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES pub fn create_role<F>(&self, f: F) -> Result<Role> - where F: FnOnce(EditRole) -> EditRole { + where F: FnOnce(&mut EditRole) -> &mut EditRole { #[cfg(feature = "cache")] { let req = Permissions::MANAGE_ROLES; @@ -520,7 +520,7 @@ impl Guild { /// [`ModelError::InvalidPermissions`]: ../error/enum.Error.html#variant.InvalidPermissions /// [Manage Guild]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_GUILD pub fn edit<F>(&mut self, f: F) -> Result<()> - where F: FnOnce(EditGuild) -> EditGuild { + where F: FnOnce(&mut EditGuild) -> &mut EditGuild { #[cfg(feature = "cache")] { let req = Permissions::MANAGE_GUILD; diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs index 38066e4..38f4d53 100644 --- a/src/model/guild/partial_guild.rs +++ b/src/model/guild/partial_guild.rs @@ -155,7 +155,8 @@ impl PartialGuild { /// [`Guild::create_role`]: struct.Guild.html#method.create_role /// [Manage Roles]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES #[inline] - pub fn create_role<F: FnOnce(EditRole) -> EditRole>(&self, f: F) -> Result<Role> { + pub fn create_role<F>(&self, f: F) -> Result<Role> + where F: FnOnce(&mut EditRole) -> &mut EditRole { self.id.create_role(f) } @@ -209,7 +210,7 @@ impl PartialGuild { /// /// [Manage Guild]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_GUILD pub fn edit<F>(&mut self, f: F) -> Result<()> - where F: FnOnce(EditGuild) -> EditGuild { + where F: FnOnce(&mut EditGuild) -> &mut EditGuild { match self.id.edit(f) { Ok(guild) => { self.afk_channel_id = guild.afk_channel_id; diff --git a/src/model/user.rs b/src/model/user.rs index d0a02df..5676fd1 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -438,10 +438,8 @@ impl User { /// url, /// ); /// - /// let dm = msg.author.direct_message(|mut m| { - /// m.content(&help); - /// - /// m + /// let dm = msg.author.direct_message(|m| { + /// m.content(&help) /// }); /// /// match dm { @@ -486,7 +484,7 @@ impl User { #[allow(let_and_return)] #[cfg(feature = "builder")] pub fn direct_message<F>(&self, f: F) -> Result<Message> - where F: FnOnce(CreateMessage) -> CreateMessage { + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { if self.bot { return Err(Error::Model(ModelError::MessagingBot)); } @@ -547,7 +545,8 @@ impl User { /// [direct_message]: #method.direct_message #[cfg(feature = "builder")] #[inline] - pub fn dm<F: FnOnce(CreateMessage) -> CreateMessage>(&self, f: F) -> Result<Message> { + pub fn dm<F>(&self, f: F) -> Result<Message> + where for <'b> F: FnOnce(&'b mut CreateMessage<'b>) -> &'b mut CreateMessage<'b> { self.direct_message(f) } diff --git a/src/model/webhook.rs b/src/model/webhook.rs index 5f0c294..b87bef8 100644 --- a/src/model/webhook.rs +++ b/src/model/webhook.rs @@ -199,11 +199,11 @@ impl Webhook { /// }); /// ``` #[inline] - pub fn execute<F: FnOnce(ExecuteWebhook) -> ExecuteWebhook>(&self, - wait: bool, - f: F) - -> Result<Option<Message>> { - let map = utils::vecmap_to_json_map(f(ExecuteWebhook::default()).0); + pub fn execute<F>(&self, wait: bool, f: F) -> Result<Option<Message>> + where F: FnOnce(&mut ExecuteWebhook) -> &mut ExecuteWebhook { + let mut execute_webhook = ExecuteWebhook::default(); + f(&mut execute_webhook); + let map = utils::vecmap_to_json_map(execute_webhook.0); http::execute_webhook(self.id.0, &self.token, wait, &map) } |