1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3#![warn(
4 clippy::missing_const_for_fn,
5 clippy::missing_docs_in_private_items,
6 clippy::pedantic,
7 missing_docs,
8 unsafe_code
9)]
10#![allow(
11 clippy::module_name_repetitions,
12 clippy::must_use_candidate,
13 clippy::unnecessary_wraps
14)]
15
16pub mod error;
17
18mod channel;
19mod command;
20#[cfg(any(feature = "zlib", feature = "zstd"))]
21mod compression;
22mod config;
23mod event;
24mod json;
25mod latency;
26mod message;
27mod ratelimiter;
28mod session;
29mod shard;
30mod stream;
31
32pub use self::{
33 channel::MessageSender,
34 command::Command,
35 config::{Config, ConfigBuilder},
36 event::EventTypeFlags,
37 json::parse,
38 latency::Latency,
39 message::Message,
40 ratelimiter::CommandRatelimiter,
41 session::Session,
42 shard::{Shard, ShardState},
43 stream::StreamExt,
44};
45pub use twilight_model::gateway::{CloseFrame, Intents, ShardId};
46
47#[doc(no_inline)]
48pub use twilight_gateway_queue as queue;
49#[doc(no_inline)]
50pub use twilight_model::gateway::event::{Event, EventType};
51
52#[allow(deprecated)]
53#[cfg(feature = "twilight-http")]
54use self::error::{StartRecommendedError, StartRecommendedErrorType};
55#[cfg(feature = "twilight-http")]
56use twilight_http::Client;
57
58pub const API_VERSION: u8 = 10;
60
61#[track_caller]
105pub fn bucket(
106 bucket_id: u16,
107 buckets: u16,
108 shards: u32,
109) -> impl DoubleEndedIterator<Item = ShardId> + ExactSizeIterator {
110 let bucket_id = u32::from(bucket_id);
111 let buckets = u32::from(buckets);
112 assert!(bucket_id < buckets, "bucket_id must be less than buckets");
113
114 let (q, r) = (shards / buckets, shards % buckets);
115
116 let len = q + u32::from(bucket_id < r);
117 let start = bucket_id * q + r.min(bucket_id);
118
119 (start..start + len).map(move |id| ShardId::new(id, shards))
120}
121
122#[deprecated(
135 since = "0.17.2",
136 note = "creates non-consecutive shards; use `bucket` instead"
137)]
138#[track_caller]
139pub fn create_bucket<F, Q>(
140 bucket_id: u16,
141 concurrency: u16,
142 total: u32,
143 config: Config<Q>,
144 per_shard_config: F,
145) -> impl ExactSizeIterator<Item = Shard<Q>>
146where
147 F: FnMut(ShardId, ConfigBuilder<Q>) -> Config<Q>,
148 Q: Clone,
149{
150 assert!(
151 u32::from(bucket_id) < total,
152 "bucket id must be less than the total"
153 );
154 assert!(
155 bucket_id < concurrency,
156 "bucket id must be less than concurrency"
157 );
158 assert!(
159 (u32::from(concurrency)) < total,
160 "concurrency must be less than the total"
161 );
162
163 #[allow(deprecated)]
164 create_iterator(
165 (u32::from(bucket_id)..total).step_by(concurrency.into()),
166 total,
167 config,
168 per_shard_config,
169 )
170}
171
172#[deprecated(since = "0.17.2", note = "use `bucket` instead")]
200#[track_caller]
201pub fn create_iterator<F, Q>(
202 numbers: impl ExactSizeIterator<Item = u32>,
203 total: u32,
204 config: Config<Q>,
205 mut per_shard_config: F,
206) -> impl ExactSizeIterator<Item = Shard<Q>>
207where
208 F: FnMut(ShardId, ConfigBuilder<Q>) -> Config<Q>,
209 Q: Clone,
210{
211 numbers.map(move |index| {
212 let id = ShardId::new(index, total);
213 let config = per_shard_config(id, ConfigBuilder::from(config.clone()));
214
215 Shard::with_config(id, config)
216 })
217}
218
219#[allow(deprecated)]
240#[cfg(feature = "twilight-http")]
241#[deprecated(
242 since = "0.17.2",
243 note = "fetch the recommended shard count via `client.gateway().authed()` instead (from `twilight_http::Client`)"
244)]
245pub async fn create_recommended<F, Q>(
246 client: &Client,
247 config: Config<Q>,
248 per_shard_config: F,
249) -> Result<impl ExactSizeIterator<Item = Shard<Q>> + use<F, Q>, StartRecommendedError>
250where
251 F: FnMut(ShardId, ConfigBuilder<Q>) -> Config<Q>,
252 Q: Clone,
253{
254 let request = client.gateway().authed();
255 let response = request.await.map_err(|source| StartRecommendedError {
256 kind: StartRecommendedErrorType::Request,
257 source: Some(Box::new(source)),
258 })?;
259 let info = response
260 .model()
261 .await
262 .map_err(|source| StartRecommendedError {
263 kind: StartRecommendedErrorType::Deserializing,
264 source: Some(Box::new(source)),
265 })?;
266
267 #[allow(deprecated)]
268 Ok(create_iterator(
269 0..info.shards,
270 info.shards,
271 config,
272 per_shard_config,
273 ))
274}