1#![cfg_attr(docsrs, feature(doc_auto_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;
20mod config;
21mod event;
22#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
23mod inflater;
24mod json;
25mod latency;
26mod message;
27mod ratelimiter;
28mod session;
29mod shard;
30mod stream;
31
32#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
33pub use self::inflater::Inflater;
34pub use self::{
35 channel::MessageSender,
36 command::Command,
37 config::{Config, ConfigBuilder},
38 event::EventTypeFlags,
39 json::parse,
40 latency::Latency,
41 message::Message,
42 ratelimiter::CommandRatelimiter,
43 session::Session,
44 shard::{Shard, ShardState},
45 stream::StreamExt,
46};
47pub use twilight_model::gateway::{CloseFrame, Intents, ShardId};
48
49#[doc(no_inline)]
50pub use twilight_gateway_queue as queue;
51#[doc(no_inline)]
52pub use twilight_model::gateway::event::{Event, EventType};
53
54#[cfg(feature = "twilight-http")]
55use self::error::{StartRecommendedError, StartRecommendedErrorType};
56#[cfg(feature = "twilight-http")]
57use twilight_http::Client;
58
59pub const API_VERSION: u8 = 10;
61
62#[track_caller]
75pub fn create_bucket<F, Q>(
76 bucket_id: u16,
77 concurrency: u16,
78 total: u32,
79 config: Config<Q>,
80 per_shard_config: F,
81) -> impl ExactSizeIterator<Item = Shard<Q>>
82where
83 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
84 Q: Clone,
85{
86 assert!(
87 u32::from(bucket_id) < total,
88 "bucket id must be less than the total"
89 );
90 assert!(
91 bucket_id < concurrency,
92 "bucket id must be less than concurrency"
93 );
94 assert!(
95 (u32::from(concurrency)) < total,
96 "concurrency must be less than the total"
97 );
98
99 create_iterator(
100 (u32::from(bucket_id)..total).step_by(concurrency.into()),
101 total,
102 config,
103 per_shard_config,
104 )
105}
106
107#[track_caller]
135pub fn create_iterator<F, Q>(
136 numbers: impl ExactSizeIterator<Item = u32>,
137 total: u32,
138 config: Config<Q>,
139 per_shard_config: F,
140) -> impl ExactSizeIterator<Item = Shard<Q>>
141where
142 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
143 Q: Clone,
144{
145 numbers.map(move |index| {
146 let id = ShardId::new(index, total);
147 let config = per_shard_config(id, ConfigBuilder::from(config.clone()));
148
149 Shard::with_config(id, config)
150 })
151}
152
153#[cfg(feature = "twilight-http")]
174pub async fn create_recommended<F, Q>(
175 client: &Client,
176 config: Config<Q>,
177 per_shard_config: F,
178) -> Result<impl ExactSizeIterator<Item = Shard<Q>>, StartRecommendedError>
179where
180 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
181 Q: Clone,
182{
183 let request = client.gateway().authed();
184 let response = request.await.map_err(|source| StartRecommendedError {
185 kind: StartRecommendedErrorType::Request,
186 source: Some(Box::new(source)),
187 })?;
188 let info = response
189 .model()
190 .await
191 .map_err(|source| StartRecommendedError {
192 kind: StartRecommendedErrorType::Deserializing,
193 source: Some(Box::new(source)),
194 })?;
195
196 Ok(create_iterator(
197 0..info.shards,
198 info.shards,
199 config,
200 per_shard_config,
201 ))
202}