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#[cfg(feature = "twilight-http")]
53use self::error::{StartRecommendedError, StartRecommendedErrorType};
54#[cfg(feature = "twilight-http")]
55use twilight_http::Client;
56
57pub const API_VERSION: u8 = 10;
59
60#[track_caller]
73pub fn create_bucket<F, Q>(
74 bucket_id: u16,
75 concurrency: u16,
76 total: u32,
77 config: Config<Q>,
78 per_shard_config: F,
79) -> impl ExactSizeIterator<Item = Shard<Q>>
80where
81 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
82 Q: Clone,
83{
84 assert!(
85 u32::from(bucket_id) < total,
86 "bucket id must be less than the total"
87 );
88 assert!(
89 bucket_id < concurrency,
90 "bucket id must be less than concurrency"
91 );
92 assert!(
93 (u32::from(concurrency)) < total,
94 "concurrency must be less than the total"
95 );
96
97 create_iterator(
98 (u32::from(bucket_id)..total).step_by(concurrency.into()),
99 total,
100 config,
101 per_shard_config,
102 )
103}
104
105#[track_caller]
133pub fn create_iterator<F, Q>(
134 numbers: impl ExactSizeIterator<Item = u32>,
135 total: u32,
136 config: Config<Q>,
137 per_shard_config: F,
138) -> impl ExactSizeIterator<Item = Shard<Q>>
139where
140 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
141 Q: Clone,
142{
143 numbers.map(move |index| {
144 let id = ShardId::new(index, total);
145 let config = per_shard_config(id, ConfigBuilder::from(config.clone()));
146
147 Shard::with_config(id, config)
148 })
149}
150
151#[cfg(feature = "twilight-http")]
172pub async fn create_recommended<F, Q>(
173 client: &Client,
174 config: Config<Q>,
175 per_shard_config: F,
176) -> Result<impl ExactSizeIterator<Item = Shard<Q>> + use<F, Q>, StartRecommendedError>
177where
178 F: Fn(ShardId, ConfigBuilder<Q>) -> Config<Q>,
179 Q: Clone,
180{
181 let request = client.gateway().authed();
182 let response = request.await.map_err(|source| StartRecommendedError {
183 kind: StartRecommendedErrorType::Request,
184 source: Some(Box::new(source)),
185 })?;
186 let info = response
187 .model()
188 .await
189 .map_err(|source| StartRecommendedError {
190 kind: StartRecommendedErrorType::Deserializing,
191 source: Some(Box::new(source)),
192 })?;
193
194 Ok(create_iterator(
195 0..info.shards,
196 info.shards,
197 config,
198 per_shard_config,
199 ))
200}