1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//! Serenity is a Rust library for the Discord API.
//!
//! View the [examples] on how to make and structure a bot.
//!
//! Serenity supports bot user authentication via the use of [`Client::new`].
//!
//! Once logged in, you may add handlers to your client to dispatch [`Event`]s,
//! such as [`Client::on_message`]. This will cause your handler to be called
//! 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 [`Shard`] is transparently handled by the library, removing
//! unnecessary complexity. Sharded connections are automatically handled for
//! 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
//! 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 [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][docs]. If you
//! need to be sure that some information piece is sanctioned by Discord, refer
//! to their own documentation.
//!
//! # Example Bot
//!
//! A basic ping-pong bot looks like:
//!
//! ```rust,no_run
//! #[macro_use] extern crate serenity;
//!
//! # #[cfg(all(feature = "client", feature = "standard_framework"))]
//! # mod inner {
//! #
//! use serenity::client::{Client, EventHandler};
//! use serenity::framework::standard::StandardFramework;
//! use std::env;
//!
//! struct Handler;
//!
//! impl EventHandler for Handler {}
//!
//! pub fn main() {
//!     // Login with a bot token from the environment
//!     let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("token"), Handler)
//!         .expect("Error creating client");
//!
//!     client.with_framework(StandardFramework::new()
//!         .configure(|c| c.prefix("~")) // set the bot's prefix to "~"
//!         .cmd("ping", ping));
//!
//!     // start listening for events by starting a single shard
//!     if let Err(why) = client.start() {
//!         println!("An error occurred while running the client: {:?}", why);
//!     }
//! }
//!
//! command!(ping(_context, message) {
//!     let _ = message.reply("Pong!");
//! });
//! #
//! # }
//! #
//! # #[cfg(all(feature = "client", feature = "standard_framework"))]
//! # fn main() { inner::main() }
//! # #[cfg(not(all(feature = "client", feature = "standard_framework")))]
//! # fn main() {}
//! ```
//!
//! ### Full Examples
//!
//! Full examples, detailing and explaining usage of the basic functionality of the
//! library, can be found in the [`examples`] directory.
//!
//! # Installation
//!
//! Add the following to your `Cargo.toml` file:
//!
//! ```toml
//! [dependencies]
//! serenity = "0.5"
//! ```
//!
//! and to the top of your `main.rs`:
//!
//! ```rs
//! #[macro_use] extern crate serenity;
//! ```
//!
//! [`Cache`]: cache/struct.Cache.html
//! [`Client::new`]: client/struct.Client.html#method.new
//! [`Client::on_message`]: client/struct.Client.html#method.on_message
//! [`Context`]: client/struct.Context.html
//! [`Event`]: model/event/enum.Event.html
//! [`Event::MessageCreate`]: model/event/enum.Event.html#variant.MessageCreate
//! [`Shard`]: gateway/struct.Shard.html
//! [`examples`]: https://github.com/serenity-rs/serenity/blob/master/examples
//! [cache docs]: cache/index.html
//! [client's module-level documentation]: client/index.html
//! [docs]: https://discordapp.com/developers/docs/intro
//! [examples]: https://github.com/serenity-rs/serenity/tree/master/examples
//! [gateway docs]: gateway/index.html
#![doc(html_root_url = "https://docs.rs/serenity/*")]
#![allow(unknown_lints)]
#![allow(doc_markdown, inline_always)]
#![warn(enum_glob_use, if_not_else)]

#[macro_use]
extern crate bitflags;
#[allow(unused_imports)]
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[allow(unused_imports)]
#[macro_use]
extern crate serde_json;

#[cfg(feature = "lazy_static")]
#[macro_use]
extern crate lazy_static;

extern crate chrono;
extern crate parking_lot;
extern crate serde;

#[cfg(feature = "base64")]
extern crate base64;
#[cfg(feature = "byteorder")]
extern crate byteorder;
#[cfg(feature = "flate2")]
extern crate flate2;
#[cfg(feature = "hyper")]
extern crate hyper;
#[cfg(feature = "hyper-native-tls")]
extern crate hyper_native_tls;
#[cfg(feature = "multipart")]
extern crate multipart;
#[cfg(feature = "native-tls")]
extern crate native_tls;
#[cfg(feature = "opus")]
extern crate opus;
#[cfg(feature = "sodiumoxide")]
extern crate sodiumoxide;
#[cfg(feature = "threadpool")]
extern crate threadpool;
#[cfg(feature = "typemap")]
extern crate typemap;
#[cfg(feature = "evzht9h3nznqzwl")]
extern crate evzht9h3nznqzwl as websocket;

#[allow(unused_imports)]
#[cfg(test)]
#[macro_use]
extern crate matches;

#[macro_use]
mod internal;

pub mod constants;
pub mod model;
pub mod prelude;

#[cfg(feature = "builder")]
pub mod builder;
#[cfg(feature = "cache")]
pub mod cache;
#[cfg(feature = "client")]
pub mod client;
#[cfg(feature = "framework")]
pub mod framework;
#[cfg(feature = "gateway")]
pub mod gateway;
#[cfg(feature = "http")]
pub mod http;
#[cfg(feature = "utils")]
pub mod utils;
#[cfg(feature = "voice")]
pub mod voice;

mod error;

pub use error::{Error, Result};

#[cfg(feature = "client")]
pub use client::Client;

#[cfg(feature = "cache")]
use cache::Cache;
#[cfg(feature = "cache")]
use parking_lot::RwLock;

#[cfg(feature = "cache")]
lazy_static! {
    /// A mutable and lazily-initialized static binding. It can be accessed
    /// across any function and in any context.
    ///
    /// This [`Cache`] instance is updated for every event received, so you do
    /// not need to maintain your own cache.
    ///
    /// See the [cache module documentation] for more details.
    ///
    /// The Cache itself is wrapped within an `RwLock`, which allows for
    /// multiple readers or at most one writer at a time across threads. This
    /// means that you may have multiple commands reading from the Cache
    /// concurrently.
    ///
    /// # Examples
    ///
    /// Retrieve the [current user][`CurrentUser`]'s Id, by opening a Read
    /// guard:
    ///
    /// ```rust,ignore
    /// use serenity::CACHE;
    ///
    /// println!("{}", CACHE.read().user.id);
    /// ```
    ///
    /// Update the cache's settings to enable caching of channels' messages:
    ///
    /// ```rust
    /// use serenity::CACHE;
    ///
    /// // Cache up to the 10 most recent messages per channel.
    /// CACHE.write().settings_mut().max_messages(10);
    /// ```
    ///
    /// [`CurrentUser`]: model/user/struct.CurrentUser.html
    /// [`Cache`]: cache/struct.Cache.html
    /// [cache module documentation]: cache/index.html
    pub static ref CACHE: RwLock<Cache> = RwLock::new(Cache::default());
}