aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-29 23:33:59 -0800
committerAustin Hellyer <[email protected]>2016-11-29 23:33:59 -0800
commitefad058f596c9df717774cb2e9dafc0035a8df9c (patch)
treeef54b7d65841fb63609a2b5135727922f2d8f81a
parentClean up the codebase (diff)
downloadserenity-efad058f596c9df717774cb2e9dafc0035a8df9c.tar.xz
serenity-efad058f596c9df717774cb2e9dafc0035a8df9c.zip
Add documentation for examples
The examples include a README located in `examples/README.md`, which contains instructions for running these examples. They act as a simple form of tutorial to the library, without getting into too many details.
-rw-r--r--README.md74
-rw-r--r--examples/01_basic_ping_bot/src/main.rs31
-rw-r--r--examples/02_transparent_guild_sharding/src/main.rs11
-rw-r--r--examples/03_struct_utilities/Cargo.toml1
-rw-r--r--examples/03_struct_utilities/src/main.rs16
-rw-r--r--examples/04_message_builder/src/main.rs13
-rw-r--r--examples/05_user_login/src/main.rs12
-rw-r--r--examples/06_command_framework/Cargo.toml1
-rw-r--r--examples/06_command_framework/src/main.rs85
-rw-r--r--examples/07_voice/Cargo.toml1
-rw-r--r--examples/07_voice/src/main.rs2
-rw-r--r--examples/README.md28
-rw-r--r--src/ext/cache/mod.rs6
-rw-r--r--src/lib.rs62
14 files changed, 298 insertions, 45 deletions
diff --git a/README.md b/README.md
index 967ab4c..44c7beb 100644
--- a/README.md
+++ b/README.md
@@ -18,28 +18,70 @@ when a [`Event::MessageCreate`] is received. Each handler is given a
[`Context`], giving information about the event. See the
[client's module-level documentation].
-The [`Connection`] is transparently handled by the library, removing
+The [`Shard`] is transparently handled by the library, removing
unnecessary complexity. Sharded connections are automatically handled for
-you. See the [Connection's documentation][`Connection`] for more
-information.
+you. See the [gateway's documentation][gateway docs] for more information.
-A [`State`] is also provided for you. This will be updated automatically for
+A [`Cache`] is also provided for you. This will be updated automatically for
you as data is received from the Discord API via events. When calling a
-method on a [`Context`], the state will first be searched for relevant data
+method on a [`Context`], the cache will first be searched for relevant data
to avoid unnecessary HTTP requests to the Discord API. For more information,
-see the [state's module-level documentation][state docs].
+see the [cache's module-level documentation][cache docs].
Note that - although this documentation will try to be as up-to-date and
accurate as possible - Discord hosts [official documentation][discord docs]. If
you need to be sure that some information piece is accurate, refer to their
docs.
+# Features
+
+Features can be enabled or disabled by configuring the library through
+Cargo.toml:
+
+```toml
+[dependencies.serenity]
+git = "https://github.com/zeyla/serenity.rs.git"
+default-features = false
+features = ["pick", "your", "feature", "names", "here"]
+```
+
+The following is a full list of features:
+
+- **cache**: The cache will store information about guilds, channels, users, and
+other data, to avoid performing REST requests. If you are low on RAM, do not
+enable this;
+- **framework**: Enables the framework, which is a utility to allow simple
+command parsing, before/after command execution, prefix setting, and more;
+- **methods**: Enables compilation of extra methods on struct implementations,
+such as `Message::delete()`, `Message::reply()`, `Guild::edit()`, and more.
+Without this enabled, requests will need to go through the [`Context`] or
+[`rest`] module, which are slightly less efficient from a development
+standpoint, and do not automatically perform permission checking;
+- **voice**: Enables compilation of voice support, so that voice channels can be
+connected to and audio can be sent/received.
+
# Dependencies
Serenity requires the following dependencies:
- openssl
+### Voice
+
+The following dependencies all require the **voice** feature to be enabled in
+your Cargo.toml:
+
+- libsodium (Arch: `community/libsodium`)
+- opus (Arch: `extra/opus`)
+
+Voice+ffmpeg:
+
+- ffmpeg (Arch: `extra/ffmpeg`)
+
+Voice+youtube-dl:
+
+- youtube-dl (Arch: `community/youtube-dl`)
+
# Example Bot
A basic ping-pong bot looks like:
@@ -59,20 +101,28 @@ fn main() {
let _ = message.reply("Pong!");
}));
- // start listening for events by starting a connection
+ // start listening for events by starting a single shard
let _ = client.start();
}
```
+### Full Examples
+
+Full examples, detailing and explaining usage of the basic functionality of the
+library, can be found in the [`examples`] directory.
+
+[`Cache`]: https://serenity.zey.moe/serenity/ext/cache/struct.Cache.html
[`Client::login_bot`]: https://serenity.zey.moe/serenity/client/struct.Client.html#method.login_bot
[`Client::login_user`]: https://serenity.zey.moe/serenity/client/struct.Client.html#method.login_user
[`Client::on_message`]: https://serenity.zey.moe/serenity/client/struct.Client.html#method.on_message
-[`validate_token`]: https://serenity.zey.moe/serenity/client/fn.validate_token.html
-[`Connection`]: https://serenity.zey.moe/serenity/client/struct.Connection.html
+[`Shard`]: https://serenity.zey.moe/serenity/client/gateway/struct.Shard.html
[`Context`]: https://serenity.zey.moe/serenity/client/struct.Context.html
[`Event`]: https://serenity.zey.moe/serenity/model/enum.Event.html
-[`Event::MessageCreate`]: https://serenity.zey.moe/serenity/model/enum.Event.html#MessageCreate.v
-[`State`]: https://serenity.zey.moe/serenity/ext/state/struct.State.html
+[`Event::MessageCreate`]: https://serenity.zey.moe/serenity/model/enum.Event.html#variant.MessageCreate
+[`examples`]: https://github.com/zeyla/serenity.rs/blob/master/examples
+[`rest`]: https://serenity.zey.moe/serenity/client/rest/index.html
+[`validate_token`]: https://serenity.zey.moe/serenity/client/fn.validate_token.html
+[cache docs]: https://serenity.zey.moe/serenity/ext/cache/index.html
[ci]: https://travis-ci.org/zeyla/serenity.rs
[ci-badge]: https://travis-ci.org/zeyla/serenity.rs.svg?branch=master
[contribs]: https://img.shields.io/github/contributors/zeyla/serenity.rs.svg
@@ -84,6 +134,6 @@ fn main() {
[docs]: https://serenity.zey.moe/
[docs-badge]: https://img.shields.io/badge/docs-online-5023dd.svg
[examples]: https://github.com/zeyla/serenity.rs/tree/master/examples
+[gateway docs]: https://serenity.zey.moe/serenity/client/gateway/index.html
[license]: https://opensource.org/licenses/ISC
[license-badge]: https://img.shields.io/badge/license-ISC-blue.svg
-[state docs]: https://serenity.zey.moe/serenity/ext/state/index.html
diff --git a/examples/01_basic_ping_bot/src/main.rs b/examples/01_basic_ping_bot/src/main.rs
index 8db4614..e00263b 100644
--- a/examples/01_basic_ping_bot/src/main.rs
+++ b/examples/01_basic_ping_bot/src/main.rs
@@ -7,17 +7,44 @@ fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN")
.expect("Expected a token in the environment");
+
+ // Create a new instance of the Client, logging in as a bot. This will
+ // automatically prepend your bot token with "Bot ", which is a requirement
+ // by Discord for bot users.
let mut client = Client::login_bot(&token);
+ // Set a handler for the `on_message` event - so that whenever a new message
+ // is received - the closure (or function) passed will be called.
+ //
+ // Event handlers are dispatched through multi-threading, and so multiple
+ // of a single event can be dispatched simultaneously.
client.on_message(|context, message| {
if message.content == "!ping" {
- let _ = context.say("Pong!");
+ // Sending a message can fail, due to a network error, an
+ // authentication error, or lack of permissions to post in the
+ // channel, so log to stdout when some error happens, with a
+ // description of it.
+ if let Err(why) = context.say("Pong!") {
+ println!("Error sending message: {:?}", why);
+ }
}
});
+ // Set a handler to be called on the `on_ready` event. This is called when a
+ // shard is booted, and a READY payload is sent by Discord. This payload
+ // contains data like the current user's guild Ids, current user data,
+ // relationships, and more.
+ //
+ // In this case, just print what the current user's username is.
client.on_ready(|_context, ready| {
println!("{} is connected!", ready.user.name);
});
- let _ = client.start();
+ // Finally, start a single shard, and start listening to events.
+ //
+ // Shards will automatically attempt to reconnect, and will perform
+ // exponential backoff until it reconnects.
+ if let Err(why) = client.start() {
+ println!("Client error: {:?}", why);
+ }
}
diff --git a/examples/02_transparent_guild_sharding/src/main.rs b/examples/02_transparent_guild_sharding/src/main.rs
index 19b61d0..1e3446f 100644
--- a/examples/02_transparent_guild_sharding/src/main.rs
+++ b/examples/02_transparent_guild_sharding/src/main.rs
@@ -29,6 +29,9 @@ fn main() {
client.on_message(|context, message| {
if message.content == "!ping" {
+ // The current shard needs to be unlocked so it can be read from, as
+ // multiple threads may otherwise attempt to read from or mutate it
+ // concurrently.
{
let shard = context.shard.lock().unwrap();
@@ -37,7 +40,9 @@ fn main() {
}
}
- let _ = context.say("Pong!");
+ if let Err(why) = context.say("Pong!") {
+ println!("Error sending message: {:?}", why);
+ }
}
});
@@ -51,5 +56,7 @@ fn main() {
//
// This means if you have 5 shards, your total shard count will be 5, while
// each shard will be assigned numbers 0 through 4.
- let _ = client.start_shards(2);
+ if let Err(why) = client.start_shards(2) {
+ println!("Client error: {:?}", why);
+ }
}
diff --git a/examples/03_struct_utilities/Cargo.toml b/examples/03_struct_utilities/Cargo.toml
index 8dc013c..2153419 100644
--- a/examples/03_struct_utilities/Cargo.toml
+++ b/examples/03_struct_utilities/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["my name <[email protected]>"]
[dependencies]
serenity = { git = "https://github.com/zeyla/serenity.rs.git" }
+features = ["methods"]
diff --git a/examples/03_struct_utilities/src/main.rs b/examples/03_struct_utilities/src/main.rs
index 6bf436d..8334b71 100644
--- a/examples/03_struct_utilities/src/main.rs
+++ b/examples/03_struct_utilities/src/main.rs
@@ -21,7 +21,17 @@ fn main() {
client.on_message(|_context, message| {
if message.content == "!messageme" {
- let _ = message.author.dm("Hello!");
+ // If the `methods` feature is enabled, then model structs will
+ // have a lot of useful methods implemented, to avoid using an
+ // often otherwise bulky Context, or even much lower-level `rest`
+ // method.
+ //
+ // In this case, you can direct message a User directly by simply
+ // calling a method on its instance, with the content of the
+ // message.
+ if let Err(why) = message.author.dm("Hello!") {
+ println!("Error when direct messaging user: {:?}", why);
+ }
}
});
@@ -29,5 +39,7 @@ fn main() {
println!("{} is connected!", ready.user.name);
});
- let _ = client.start();
+ if let Err(why) = client.start() {
+ println!("Client error: {:?}", why);
+ }
}
diff --git a/examples/04_message_builder/src/main.rs b/examples/04_message_builder/src/main.rs
index 41f390b..2712fe6 100644
--- a/examples/04_message_builder/src/main.rs
+++ b/examples/04_message_builder/src/main.rs
@@ -21,15 +21,20 @@ fn main() {
},
};
+ // The message builder allows for creating a message by mentioning
+ // users dynamically, pushing "safe" versions of content (such as
+ // bolding normalized content), displaying emojis, and more.
let response = MessageBuilder::new()
.push("User ")
- .mention(message.author)
+ .push_bold_safe(&message.author.name)
.push(" used the 'ping' command in the ")
.mention(channel)
.push(" channel")
.build();
- let _ = context.say(&response);
+ if let Err(why) = context.say(&response) {
+ println!("Error sending message: {:?}", why);
+ }
}
});
@@ -37,5 +42,7 @@ fn main() {
println!("{} is connected!", ready.user.name);
});
- let _ = client.start();
+ if let Err(why) = client.start() {
+ println!("Client error: {:?}", why);
+ }
}
diff --git a/examples/05_user_login/src/main.rs b/examples/05_user_login/src/main.rs
index bbc9303..0328042 100644
--- a/examples/05_user_login/src/main.rs
+++ b/examples/05_user_login/src/main.rs
@@ -7,11 +7,21 @@ fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN")
.expect("Expected a token in the environment");
+
+ // Logging in is essentially equivilant to logging in as a user.
+ //
+ // The primary difference is that by using `login_user`, the "Bot " string
+ // is not prefixed to the token.
+ //
+ // Additionally, the Client will now know that you are a user, and will
+ // disallow you from performing bot-only commands.
let mut client = Client::login_user(&token);
client.on_ready(|_context, ready| {
println!("{} is connected!", ready.user.name);
});
- println!("{:?}", client.start());
+ if let Err(why) = client.start() {
+ println!("Client error: {:?}", why);
+ }
}
diff --git a/examples/06_command_framework/Cargo.toml b/examples/06_command_framework/Cargo.toml
index fa93475..26cfca9 100644
--- a/examples/06_command_framework/Cargo.toml
+++ b/examples/06_command_framework/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["my name <[email protected]>"]
[dependencies]
serenity = { git = "https://github.com/zeyla/serenity.rs.git" }
+features = ["framework", "methods"]
diff --git a/examples/06_command_framework/src/main.rs b/examples/06_command_framework/src/main.rs
index 95d832c..b399dff 100644
--- a/examples/06_command_framework/src/main.rs
+++ b/examples/06_command_framework/src/main.rs
@@ -30,18 +30,34 @@ fn main() {
// "~about"
// "~emoji cat"
// "~emoji dog"
+ // "~multiply"
// "~ping"
- // "~some complex command"
+ // "~some long command"
client.with_framework(|f| f
+ // Configures the client, allowing for options to mutate how the
+ // framework functions.
+ //
+ // Refer to the documentation for
+ // `serenity::ext::framework::Configuration` for all available
+ // configurations.
.configure(|c| c
.allow_whitespace(true)
.on_mention(true)
.prefix("~"))
+ // Set a function to be called prior to each command execution. This
+ // provides the context of the command, the message that was received,
+ // and the full name of the command that will be called.
+ //
+ // You can not use this to determine whether a command should be
+ // executed. Instead, `set_check` is provided to give you this
+ // functionality.
.before(|_context, message, command_name| {
println!("Got command '{}' by user '{}'",
command_name,
message.author.name);
})
+ // Very similar to `before`, except this will be called directly _after_
+ // command execution.
.after(|_context, _message, command_name| {
println!("Processed command '{}'", command_name)
})
@@ -50,39 +66,82 @@ fn main() {
.on("emoji cat", cat_command)
.on("emoji dog", dog_command)
.on("multiply", multiply)
- .on("some complex command", some_complex_command)
- // Commands can be in closure-form as well
+ .on("some long command", some_long_command)
+ // Commands can be in closure-form as well.
+ //
+ // This is not recommended though, as any closure larger than a couple
+ // lines will look ugly.
.on("about", |context, _message, _args| drop(context.say("A test bot"))));
- let _ = client.start();
+ if let Err(why) = client.start() {
+ println!("Client error: {:?}", why);
+ }
}
+// Commands can be created via the `command!` macro, to avoid manually typing
+// type annotations.
+//
+// This may bring more features available for commands in the future. See the
+// "multiply" command below for some of the power that the `command!` macro can
+// bring.
command!(cat_command(context, _msg, _arg) {
- let _ = context.say(":cat:");
+ if let Err(why) = context.say(":cat:") {
+ println!("Eror sending message: {:?}", why);
+ }
});
fn dog_command(context: &Context, _msg: &Message, _args: Vec<String>) {
- let _ = context.say(":dog:");
+ if let Err(why) = context.say(":dog:") {
+ println!("Error sending message: {:?}", why);
+ }
}
-// `Message::reply` is only compiled if the `methods` feature flag is enabled.
fn ping_command(_context: &Context, message: &Message, _args: Vec<String>) {
- let _ = message.reply("Pong!");
+ if let Err(why) = message.reply("Pong!") {
+ println!("Error sending reply: {:?}", why);
+ }
}
+// A function which acts as a "check", to determine whether to call a command.
+//
+// In this case, this command checks to ensure you are the owner of the message
+// in order for the command to be executed. If the check fails, the command is
+// not called.
fn owner_check(_context: &Context, message: &Message) -> bool {
// Replace 7 with your ID
message.author.id == 7
}
-fn some_complex_command(context: &Context, _msg: &Message, args: Vec<String>) {
- let _ = context.say(&format!("Arguments: {:?}", args));
+fn some_long_command(context: &Context, _msg: &Message, args: Vec<String>) {
+ if let Err(why) = context.say(&format!("Arguments: {:?}", args)) {
+ println!("Error sending message: {:?}", why);
+ }
}
+// Using the `command!` macro, commands can be created with a certain type of
+// "dynamic" type checking. This is a method of requiring that the arguments
+// given match the required type, and maps those arguments to the specified
+// bindings.
+//
+// For example, the following will be correctly parsed by the macro:
+//
+// `~multiply 3.7 4.3`
+//
+// However, the following will not, as the second argument can not be an f64:
+//
+// `~multiply 3.7 four`
+//
+// Since the argument can't be converted, the command returns early.
+//
+// Additionally, if not enough arguments are given (e.g. `~multiply 3`), then
+// the command will return early. If additional arguments are provided, they
+// will be ignored.
+//
+// Argument type overloading is currently not supported.
command!(multiply(context, _message, args, first: f64, second: f64) {
let res = first * second;
- let _ = context.say(&res.to_string());
-
- println!("{:?}", args);
+ if let Err(why) = context.say(&res.to_string()) {
+ println!("Err sending product of {} and {}: {:?}", first, second, why);
+ }
});
diff --git a/examples/07_voice/Cargo.toml b/examples/07_voice/Cargo.toml
index d17a835..20c32bc 100644
--- a/examples/07_voice/Cargo.toml
+++ b/examples/07_voice/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["my name <[email protected]>"]
[dependencies]
serenity = { git = "https://github.com/zeyla/serenity.rs.git" }
+features = ["cache", "framework", "methods", "voice"]
diff --git a/examples/07_voice/src/main.rs b/examples/07_voice/src/main.rs
index fe02245..3870f9c 100644
--- a/examples/07_voice/src/main.rs
+++ b/examples/07_voice/src/main.rs
@@ -4,7 +4,7 @@
//! ```toml
//! [dependencies.serenity]
//! version = "*"
-//! features = ["cache", "methods", "voice"]
+//! features = ["cache", "framework", "methods", "voice"]
//! ```
extern crate serenity;
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..04b7b89
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,28 @@
+# Serenity Examples
+
+The examples listed in each directory demonstrate different use cases of the
+library, and increasingly show more advanced or in-depth code.
+
+All examples have documentation for new concepts, and try to explain any new
+concepts. Examples should be completed in order, so as not to miss any
+documentation.
+
+### Running Examples
+
+To run an example, you have the option of either:
+
+1. cloning this repository, `cd`ing into the example's directory, and then
+running `cargo run` to run the example; or
+2. copying the contents of the example into your local binary project
+(created via `cargo new test-project --bin`) and ensuring that the contents of
+the `Cargo.toml` file contains that of the example's `[dependencies]` section,
+and _then_ executing `cargo run`.
+
+Note that all examples - by default - require an environment token of
+`DISCORD_TOKEN` to be set. If you don't like environment tokens, you can
+hardcode your token in.
+
+### Questions
+
+If you have any questions, feel free to submit an issue with what can be
+clarified.
diff --git a/src/ext/cache/mod.rs b/src/ext/cache/mod.rs
index 2272178..2778d6b 100644
--- a/src/ext/cache/mod.rs
+++ b/src/ext/cache/mod.rs
@@ -2,7 +2,7 @@
//! data from the event is possible.
//!
//! This acts as a hot cache, to avoid making requests over the REST API through
-//! the [`http`] module where possible. All fields are public, and do not have
+//! the [`rest`] module where possible. All fields are public, and do not have
//! getters, to allow you more flexibility with the stored data. However, this
//! allows data to be "corrupted", and _may or may not_ cause misfunctions
//! within the library. Mutate data at your own discretion.
@@ -22,7 +22,7 @@
//! This allows you to save a step, by only needing to perform the
//! [`Context::get_channel`] call and not need to first search through the cache
//! - and if not found - _then_ perform an HTTP request through the Context or
-//! [`http`] module.
+//! [`rest`] module.
//!
//! Additionally, note that some information received through events can _not_
//! be retrieved through the REST API. This is information such as [`Role`]s in
@@ -74,7 +74,7 @@
//! [`Role`]: ../../model/struct.Role.html
//! [`Shard`]: ../../client/gateway/struct.Shard.html
//! [`client::CACHE`]: ../../client/struct.CACHE.html
-//! [`http`]: ../../client/http/index.html
+//! [`rest`]: ../../client/rest/index.html
use std::collections::hash_map::Entry;
use std::collections::HashMap;
diff --git a/src/lib.rs b/src/lib.rs
index 761ef86..8afb89f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,10 +14,9 @@
//! [`Context`], giving information about the event. See the
//! [client's module-level documentation].
//!
-//! The [`Connection`] is transparently handled by the library, removing
+//! The [`Shard`] is transparently handled by the library, removing
//! unnecessary complexity. Sharded connections are automatically handled for
-//! you. See the [Connection's documentation][`Connection`] for more
-//! information.
+//! you. See the [gateway's documentation][gateway docs] for more information.
//!
//! A [`Cache`] is also provided for you. This will be updated automatically for
//! you as data is received from the Discord API via events. When calling a
@@ -30,12 +29,56 @@
//! need to be sure that some information piece is sanctioned by Discord, refer
//! to their own documentation.
//!
+//! # Features
+//!
+//! Features can be enabled or disabled by configuring the library through
+//! Cargo.toml:
+//!
+//! ```toml
+//! [dependencies.serenity]
+//! git = "https://github.com/zeyla/serenity.rs.git"
+//! default-features = false
+//! features = ["pick", "your", "feature", "names", "here"]
+//! ```
+//!
+//! The following is a full list of features:
+//!
+//! - **cache**: The cache will store information about guilds, channels, users,
+//! and other data, to avoid performing REST requests. If you are low on RAM, do
+//! not enable this;
+//! - **framework**: Enables the framework, which is a utility to allow simple
+//! command parsing, before/after command execution, prefix setting, and more;
+//! - **methods**: Enables compilation of extra methods on struct
+//! implementations, such as `Message::delete()`, `Message::reply()`,
+//! `Guild::edit()`, and more. Without this enabled, requests will need to go
+//! through the [`Context`] or [`rest`] module, which are slightly less
+//! efficient from a development standpoint, and do not automatically perform
+//! permission checking;
+//! - **voice**: Enables compilation of voice support, so that voice channels
+//! can be connected to and audio can be sent/received.
+//!
//! # Dependencies
//!
//! Serenity requires the following dependencies:
//!
//! - openssl
//!
+//! ### Voice
+//!
+//! The following dependencies all require the **voice** feature to be enabled
+//! in your Cargo.toml:
+//!
+//! - libsodium (Arch: `community/libsodium`)
+//! - opus (Arch: `extra/opus`)
+//!
+//! Voice+ffmpeg:
+//!
+//! - ffmpeg (Arch: `extra/ffmpeg`)
+//!
+//! Voice+youtube-dl:
+//!
+//! - youtube-dl (Arch: `community/youtube-dl`)
+//!
//! # Example Bot
//!
//! A basic ping-pong bot looks like:
@@ -56,24 +99,31 @@
//! let _ = message.reply("Pong!");
//! }));
//!
-//! // start listening for events by starting a connection
+//! // start listening for events by starting a single shard
//! let _ = client.start();
//! }
//! ```
+//! ### Full Examples
+//!
+//! Full examples, detailing and explaining usage of the basic functionality of the
+//! library, can be found in the [`examples`] directory.
//!
//! [`Cache`]: ext/cache/struct.Cache.html
//! [`Client::login_bot`]: client/struct.Client.html#method.login_bot
//! [`Client::login_user`]: client/struct.Client.html#method.login_user
//! [`Client::on_message`]: client/struct.Client.html#method.on_message
-//! [`Connection`]: client/struct.Connection.html
//! [`Context`]: client/struct.Context.html
//! [`Event`]: model/event/enum.Event.html
//! [`Event::MessageCreate`]: model/event/enum.Event.html#variant.MessageCreate
+//! [`Shard`]: client/struct.Shard.html
+//! [`examples`]: https://github.com/zeyla/serenity.rs.git/blob/master/examples
+//! [`rest`]: client/rest/index.html
+//! [`validate_token`]: client/fn.validate_token.html
//! [cache docs]: ext/cache/index.html
//! [client's module-level documentation]: client/index.html
//! [docs]: https://discordapp.com/developers/docs/intro
//! [examples]: https://github.com/zeyla/serenity.rs/tree/master/examples
-//! [`validate_token`]: client/fn.validate_token.html
+//! [gateway docs]: client/gateway/index.html
#![allow(doc_markdown, inline_always, unknown_lints)]
#![doc(html_logo_url = "https://docs.austinhellyer.me/serenity.rs/docs_header.png")]
#![warn(enum_glob_use, if_not_else)]