diff options
| author | Zeyla Hellyer <[email protected]> | 2017-05-23 10:15:26 -0700 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-05-23 10:15:26 -0700 |
| commit | 8c0aeacadb93d3b56fb98beb882eaef1f79cd652 (patch) | |
| tree | 7c1d26addbf15537c6f69a6ac9623276002b155a /src/client/mod.rs | |
| parent | Fix {Invite,RichInvite}::url tests (diff) | |
| download | serenity-8c0aeacadb93d3b56fb98beb882eaef1f79cd652.tar.xz serenity-8c0aeacadb93d3b56fb98beb882eaef1f79cd652.zip | |
Add more examples and improve some others
Add examples to some functions, and update some of the old examples to
use the `?` operator instead of unwrapping.
Diffstat (limited to 'src/client/mod.rs')
| -rw-r--r-- | src/client/mod.rs | 313 |
1 files changed, 312 insertions, 1 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs index 1ba555a..bdaa2aa 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -105,9 +105,61 @@ pub struct Client { /// In the meaning of a context, this data can be accessed through /// [`Context::data`]. /// + /// # Examples + /// + /// Create a `MessageEventCounter` to track the following events: + /// + /// - [`Event::MessageCreate`] + /// - [`Event::MessageDelete`] + /// - [`Event::MessageDeleteBulk`] + /// - [`Event::MessageUpdate`] + /// + /// ```rust,ignore + /// extern crate serenity; + /// extern crate typemap; + /// + /// use serenity::Client; + /// use std::collections::HashMap; + /// use std::env; + /// use typemap::Key; + /// + /// struct MessageEventCounter; + /// + /// impl Key for MessageEventCounter { + /// type Value = HashMap<String, u64>; + /// } + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN").unwrap()); + /// + /// { + /// let mut data = client.data.lock().unwrap(); + /// data.insert::<MessageEventCounter>(HashMap::default()); + /// } + /// + /// macro_rules! reg { + /// ($ctx:ident $name:expr) => { + /// { + /// let mut data = $ctx.data.lock().unwrap(); + /// let counter = data.get_mut::<MessageEventCounter>().unwrap(); + /// let entry = counter.entry($name).or_insert(0); + /// *entry += 1; + /// } + /// }; + /// } + /// + /// client.on_message(|ctx, _| reg!(ctx "MessageCreate")); + /// client.on_message_delete(|ctx, _| reg!(ctx "MessageDelete")); + /// client.on_message_delete_bulk(|ctx, _| reg!(ctx "MessageDeleteBulk")); + /// client.on_message_update(|ctx, _| reg!(ctx "MessageUpdate")); + /// ``` + /// /// Refer to [example 05] for an example on using the `data` field. /// /// [`Context::data`]: struct.Context.html#method.data + /// [`Event::MessageCreate`]: ../model/event/enum.Event.html#variant.MessageCreate + /// [`Event::MessageDelete`]: ../model/event/enum.Event.html#variant.MessageDelete + /// [`Event::MessageDeleteBulk`]: ../model/event/enum.Event.html#variant.MessageDeleteBulk + /// [`Event::MessageUpdate`]: ../model/event/enum.Event.html#variant.MessageUpdate /// [example 05]: https://github.com/zeyla/serenity/tree/master/examples/05_command_framework pub data: Arc<Mutex<ShareMap>>, /// A vector of all active shards that have received their [`Event::Ready`] @@ -137,6 +189,27 @@ impl Client { /// /// Discord has a requirement of prefixing bot tokens with `"Bot "`, which /// this function will automatically do for you if not already included. + /// + /// # Examples + /// + /// Create a Client, using a token from an environment variable: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let token = env::var("DISCORD_TOKEN")?; + /// let client = Client::login(&token); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` pub fn login(bot_token: &str) -> Self { let token = if bot_token.starts_with("Bot ") { bot_token.to_owned() @@ -154,6 +227,32 @@ impl Client { /// See the [framework module-level documentation][framework docs] for more /// information on usage. /// + /// # Examples + /// + /// Create a simple framework that responds to a `~ping` command: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// client.with_framework(|f| f + /// .configure(|c| c.prefix("~")) + /// .command("ping", |c| c.exec_str("Pong!"))); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// + /// Refer to the documentation for the `framework` module for more in-depth + /// information. + /// /// [`on_message`]: #method.on_message /// [framework docs]: ../framework/index.html #[cfg(feature="framework")] @@ -174,6 +273,30 @@ impl Client { /// Refer to the [Gateway documentation][gateway docs] for more information /// on effectively using sharding. /// + /// # Examples + /// + /// Starting a Client with only 1 shard, out of 1 total: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::client::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start() { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// /// [gateway docs]: gateway/index.html#sharding pub fn start(&mut self) -> Result<()> { self.start_connection(None, http::get_gateway()?.url) @@ -191,6 +314,30 @@ impl Client { /// Refer to the [Gateway documentation][gateway docs] for more information /// on effectively using sharding. /// + /// # Examples + /// + /// Start as many shards as needed using autosharding: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start_autosharded() { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// /// [gateway docs]: gateway/index.html#sharding pub fn start_autosharded(&mut self) -> Result<()> { let mut res = http::get_bot_gateway()?; @@ -216,6 +363,55 @@ impl Client { /// Refer to the [Gateway documentation][gateway docs] for more information /// on effectively using sharding. /// + /// # Examples + /// + /// Start shard 3 of 5: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start_shard(3, 5) { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// + /// Start shard 0 of 1 (you may also be interested in [`start`] or + /// [`start_autosharded`]): + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start_shard(0, 1) { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// + /// [`start`]: #method.start + /// [`start_autosharded`]: #method.start_autosharded /// [gateway docs]: gateway/index.html#sharding pub fn start_shard(&mut self, shard: u64, shards: u64) -> Result<()> { self.start_connection(Some([shard, shard, shards]), http::get_gateway()?.url) @@ -233,8 +429,32 @@ impl Client { /// Refer to the [Gateway documentation][gateway docs] for more information /// on effectively using sharding. /// + /// # Examples + /// + /// Start all of 8 shards: + /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start_shards(8) { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// /// [`start_shard`]: #method.start_shard - /// [`start_shard_range`]: #method.start_shards + /// [`start_shard_range`]: #method.start_shard_range /// [Gateway docs]: gateway/index.html#sharding pub fn start_shards(&mut self, total_shards: u64) -> Result<()> { self.start_connection(Some([0, total_shards - 1, total_shards]), http::get_gateway()?.url) @@ -267,6 +487,26 @@ impl Client { /// let _ = client.start_shard_range([4, 7], 10); /// ``` /// + /// ```rust,no_run + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let mut client = Client::login(&env::var("DISCORD_TOKEN")?); + /// + /// if let Err(why) = client.start_shard_range([4, 7], 10) { + /// println!("Err with client: {:?}", why); + /// } + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + /// /// [`start_shard`]: #method.start_shard /// [`start_shards`]: #method.start_shards /// [Gateway docs]: gateway/index.html#sharding @@ -276,6 +516,26 @@ impl Client { /// Attaches a handler for when a [`ChannelCreate`] is received. /// + /// # Examples + /// + /// If the channel is a guild channel, send `"first"` to the channel when + /// one is created: + /// + /// ```rust,no_run + /// # use serenity::Client; + /// # + /// # let mut client = Client::login(""); + /// use serenity::model::Channel; + /// + /// client.on_channel_create(|ctx, channel| { + /// if let Channel::Guild(ch) = channel { + /// if let Err(why) = ch.read().unwrap().say("first") { + /// println!("Err sending first message: {:?}", why); + /// } + /// } + /// }); + /// ``` + /// /// [`ChannelCreate`]: ../model/event/enum.Event.html#variant.ChannelCreate pub fn on_channel_create<F>(&mut self, handler: F) where F: Fn(Context, Channel) + Send + Sync + 'static { @@ -286,6 +546,34 @@ impl Client { /// Attaches a handler for when a [`ChannelDelete`] is received. /// + /// # Examples + /// + /// If the channel is a guild channel, send the name of the channel to the + /// guild's default channel. + /// + /// ```rust,no_run + /// # use serenity::Client; + /// # + /// # let mut client = Client::login(""); + /// use serenity::model::{Channel, ChannelId}; + /// + /// client.on_channel_delete(|ctx, channel| { + /// if let Channel::Guild(channel) = channel { + /// let (content, default_channel_id) = { + /// let reader = channel.read().unwrap(); + /// let content = format!("A channel named '{}' was deleted.", reader.name); + /// let id = ChannelId(reader.guild_id.0); + /// + /// (content, id) + /// }; + /// + /// if let Err(why) = default_channel_id.say(&content) { + /// println!("Err sending message to default channel: {:?}", why); + /// } + /// } + /// }); + /// ``` + /// /// [`ChannelDelete`]: ../model/event/enum.Event.html#variant.ChannelDelete pub fn on_channel_delete<F>(&mut self, handler: F) where F: Fn(Context, Channel) + Send + Sync + 'static { @@ -1127,6 +1415,29 @@ fn login(token: String) -> Client { /// - The second part of the token is at least 6 characters long; /// - The token does not contain any whitespace prior to or after the token. /// +/// # Examples +/// +/// Validate that a token is valid and that a number of invalid tokens are +/// actually invalid: +/// +/// ```rust,no_run +/// use serenity::client::validate_token; +/// +/// // ensure a valid token is in fact valid: +/// assert!(validate_token("Mjg4NzYwMjQxMzYzODc3ODg4.C_ikow.j3VupLBuE1QWZng3TMGH0z_UAwg").is_ok()); +/// +/// // "cat" isn't a valid token: +/// assert!(validate_token("cat").is_err()); +/// +/// // tokens must have three parts, separated by periods (this is still +/// // actually an invalid token): +/// assert!(validate_token("aaa.abcdefgh.bbb").is_ok()); +/// +/// // the second part must be _at least_ 6 characters long: +/// assert!(validate_token("a.abcdef.b").is_ok()); +/// assert!(validate_token("a.abcde.b").is_err()); +/// ``` +/// /// # Errors /// /// Returns a [`ClientError::InvalidToken`] when one of the above checks fail. |