Version 0.16 - 2024-??-??
❗ This is a pre-release version |
---|
Version 0.16 of the Twilight ecosystem brings a lot of internal changes and refactors, the latest versions of all dependencies and catches up with new API features added by Discord. It also contains a couple of bugfixes.
Feature name changes
The native
feature in all crates that had one was renamed to native-tls
to
avoid potential misconceptions about its purpose. Similarly, the trust-dns
feature exposed in HTTP was renamed to hickory
to account for the project's
rebranding.
Generic in-memory cache
Our in-memory cache implementation is now generic, meaning you can now write custom cached representations of all the models. There are a couple of trait bounds that need to be met for the models, however. The new cache-optimization example demonstrates how to write your own cache models and implement the traits. These changes will let you drop fields that you don't need to store for your bot to function and save on memory.
Since InMemoryCache
is now a generic type, existing code will have to be
updated to instead use DefaultInMemoryCache
, which is a drop-in replacement
for the old type.
Gateway queue rewrite
The gateway queue crate was rewritten from scratch. The Queue
trait no
longer returns an opaque future type, instead it makes use of channels now.
The three separate queue implementations were merged into one, the
InMemoryQueue
. It is recommended to fetch the data for instantiating one
from the Discord API via Client::gateway
to avoid getting ratelimited.
The old NoOpQueue
can be replicated by setting max_concurrency
to 0.
Gateway refactors
The gateway crate has seen several changes as well. Alongside the gateway
queue rewrite, the Queue
on the shards is now stored as a generic to avoid
an allocation. It defaults to an InMemoryQueue
.
A major pitfall with twilight's gateway pre-0.16 was that Shard::next_event
and Shard::next_message
were not cancellation-safe. This has been addressed
by implementing Stream
for the shard and updating the internals to be
cancellation-safe. futures_util::StreamExt::next
now serves as the
replacement for Shard::next_message
, while
twilight_gateway::StreamExt::next_event
replaces Shard::next_event
.
Additionally, the Config
struct now no longer stores the
EventTypeFlags
, those have to be passed to
twilight_gateway::StreamExt::next_event
now.
The Shard::command
, Shard::send
and Shard::close
methods now also
queue their action into a channel, like MessageSender
, and are therefore no
longer async and now infallible.
The create_range
method was renamed to create_iterator
and takes an
iterator over shard IDs instead of ranges. The create_*
methods were also
moved to the top of the crate.
We also reworked the error types. ProcessError
was removed entirely, while
SendError
was renamed to ChannelError
. ReceiveMessageErrorType
now
only has four variants.
The ConnectionStatus
enum was renamed to ShardState
and its
Connected
variant to Active
. The close code is no longer stored and a
few methods were removed. Analogously, the method to retrieve it was renamed to
Shard::state
.
In order to protect against future API changes, the parse
method no longer
errors upon encountering unknown events.
Putting it all together, the basic example of iterating over all events for a single shard now looks like this:
Twilight 0.15
let intents = Intents::GUILDS | Intents::GUILD_MODERATION;
let mut shard = Shard::new(ShardId::ONE, env::var("DISCORD_TOKEN")?, intents);
loop {
let event = match shard.next_event().await {
Ok(event) => event,
Err(source) => {
tracing::warn!(?source, "error receiving event");
if source.is_fatal() {
break;
}
continue;
}
};
println!("Event: {event:?}");
}
Twilight 0.16
use twilight_gateway::StreamExt;
let intents = Intents::GUILDS | Intents::GUILD_MODERATION;
let mut shard = Shard::new(ShardId::ONE, env::var("DISCORD_TOKEN")?, intents);
while let Some(item) = shard.next_event(EventTypeFlags::all()).await {
let Ok(event) = item else {
tracing::warn!(source = ?item.unwrap_err(), "error receiving event");
continue;
};
println!("Event: {event:?}");
}
HTTP errors
The HTTP request builders now return their errors upon finalization instead of
each stage of the building process. The validation errors previously
encountered in the builder are now returned as Validation
errors.
Twilight 0.15
let response = client.create_message(channel_id)
.content("I am a message!")?
.embeds(&embeds)?
.tts(true)
.await?;
Twilight 0.16
let response = client.create_message(channel_id)
.content("I am a message!")
.embeds(&embeds)
.tts(true)
.await?;
Select menu support
Twilight now supports all select menu types. This involves multiple breaking
changes to the SelectMenu
struct, since not all types of select menus
contain all fields. Most notably, the type of the select menu can be checked
via the kind
field, which is a SelectMenuType
.
Support for select menu default values was added via
SelectMenu::default_values
.
Smaller Discord API catchups
Twilight now supports super reactions via the burst_colors
, count_details
and me_burst
fields on Reaction
.
Auto moderation rule creation now supports setting regex patterns and allow
list. See CreateAutoModerationRule::with_keyword
for the new validation
errors returned.
Channel creation and updating now supports specifying a default thread timeout
via CreateGuildChannel::default_thread_rate_limit_per_user
and
UpdateChannel::default_thread_rate_limit_per_user
respectively.
The guild onboarding flow can now be modified via the
UpgradeGuildOnboarding
request.
Creating a stage instance now allows specifying a guild scheduled event via
CreateStageInstance::guild_scheduled_event_id
.
The current user application can now be edited with the
UpdateCurrentUserApplication
request and missing fields were added to the
Application
struct.
The Member::joined_at
field is now marked as optional.
The GuildMedia
channel type was added.
The unused UserProfile
struct was removed from twilight-model, it served
no purpose.
Ratelimiter http dependency removal
The HTTP ratelimiter now no longer exposes a dependency on http.
Method::to_http
was changed to Method::name
and now returns a string.
Ecosystem dependency upgrades
The HTTP crate was updated to make use of hyper's latest 1.x version. Gateway, HTTP and Lavalink now use rustls 0.22, up from 0.20. The bitflags crate was updated to 2.x, which changes the methods available on all types generated by it.
Switch to tokio-websockets and fastrand
The lavalink and gateway crates were rewritten internally to switch to the tokio-websockets library, away from tokio-tungstenite. This change should nearly double throughput and efficiency and tightens down on dependency count. We also changed the RNG used by our crates to fastrand.
Deprecated API removal
All APIs deprecated since 0.14.x were removed.
Removal of support for undocumented gateway events
Support for the undocumented GIFT_CODE_UPDATE
and PRESENCES_REPLACE
events
was removed.