Skip to content

transition Permissions from u64 to SmolBitSet#3446

Draft
fgardt wants to merge 238 commits intoserenity-rs:nextfrom
fgardt:push-krzvwpwyrmpz
Draft

transition Permissions from u64 to SmolBitSet#3446
fgardt wants to merge 238 commits intoserenity-rs:nextfrom
fgardt:push-krzvwpwyrmpz

Conversation

@fgardt
Copy link
Contributor

@fgardt fgardt commented Dec 3, 2025

The overdue integration of smolbitset to prepare for the future breakage when discord goes past 64 permissions.

Things compile but I've not tested it yet.

Documentation still needs to be updated and I'm a bit unsure about the associated constants on Permissions since those will not be possible to make (constant) for future permissions >= 63.
The Permission enum is a decent enough alternative I think but probably should also implement the usual bit ops and return Permissions.

GnomedDev and others added 30 commits October 6, 2025 16:24
…erenity-rs#2646)

This avoids having to allocate to store fixed length (replaced with normal
array) or fixed capacity (replaced with `ArrayVec`) collections as vectors for
the purposes of putting them through the `Request` plumbing.

Slight behavioral change - before, setting `params` to `Some(vec![])`
would still append a question mark to the end of the url. Now, we check
if the params array `is_empty` instead of `is_some`, so the question
mark won't be appended if the params list is empty.

Co-authored-by: Michael Krasnitski <42564254+mkrasnitski@users.noreply.github.com>
These are unnecessary. Accepting `impl Into<Arc<T>>` allows passing either `T` or `Arc<T>`.
This trades a heap allocation for messages sent along with thread
creation for `Message`'s inline size dropping from 1176 bytes to 760
bytes,
…l models (serenity-rs#2656)

This shrinks type sizes by a lot; however, it makes the user experience slightly
different:

- `FixedString` must be converted to String with `.into()` or `.into_string()`
  before it can be pushed to, but dereferences to `&str` as is.
- `FixedArray` must be converted to `Vec` with `.into()` or `.into_vec()`
  before it can be pushed to, but dereferences to `&[T]` as is.

The crate of these types is currently a Git dependency, but this is fine for
the `next` branch. It needs some basic testing, which Serenity is perfect for,
before a release will be made to crates.io.
…enity-rs#2668)

This commit:

- switches from `u64` to `i64` in `CreateCommandOption::min_int_value` and
`CreateCommandOption::max_int_value` to accommodate negative integers in
Discord's integer range (between -2^53 and 2^53). Values outside this
range will cause Discord's API to return an error.
- switches from `i32` to `i64` in `CreateCommandOption::add_int_choice` and
`CreateCommandOption::add_int_choice_localized` to accommodate Discord's
complete integer range (between -2^53 and 2^53). Values outside this
range will cause Discord's API to return an error.
This cache was just duplicating information already present in `Guild::members`
and therefore should be removed.

This saves around 700 MBs for my bot (pre-`FixedString`).

This has to refactor `utils::content_safe` to always take a `Guild` instead
of`Cache`, but in practice it was mostly pulling from the guild cache anyway
and this means it is more likely to respect nicknames and other information,
while losing the ability to clean mentions from DMs, which do not matter.
`Embed::fields` previously had to stay as a `Vec` due to `CreateEmbed` wrapping
around it, but by implementing `Serialize` manually we can overwrite the
`Embed::fields` with a normal `Vec`, for a small performance hit on
serialization while saving some space for all stored `Embed`s.
Simply missed these when finding and replacing.
This uses the `bool_to_bitflags` macro to remove boolean (and optional boolean)
fields from structs and pack them into a bitflags invocation, so a struct with
many bools will only use one or two bytes, instead of a byte per bool as is.

This requires using getters and setters for the boolean fields, which changes
user experience and is hard to document, which is a significant downside, but
is such a nice change and will just become more and more efficient as time goes
on.
…rs#2681)

This swaps fields that store `Option<Int>` for `Option<NonMaxInt>` where the
maximum value would be ludicrous. Since `nonmax` uses `NonZero` internally,
this gives us niche optimisations, so model sizes can drop some more.

I have had to include a workaround for [serenity-rs#17] in `optional_string` by making my
own `TryFrom<u64>`, so that should be removable once that issue is fixed.

[serenity-rs#17]: LPGhatguy/nonmax#17
A couple of clippy bugs have been fixed and I have shrunk model
sizes enough to make `clippy::large_enum_variant` go away.
A discord bot library should not be using the tools reserved for low
level OS interaction/data structure libraries.
Discord seems to internally default Ids to 0, which is a bug whenever
exposed, but this makes ID parsing more resilient. I also took the
liberty to remove the `From<NonZero*>` implementations, to prevent future
headaches, as it was impossible to not break public API as we exposed
`NonZero` in `*Id::parse`.
…nity-rs#2694)

This,
1. shrinks the size of Request, when copied around, as it doesn't have
to store the max capacity at all times
2. shrinks llvm-lines (compile time metric) for my bot in debug from
`1,153,519` to `1,131,480` as no monomorphisation has to be performed
for `MAX_PARAMS`.
Follow-up to serenity-rs#2694.

When `Request::params` was made into an ArrayVec, the `Option` around it
was removed in order to avoid having to add a turbofish on `None` to
specify the value of `MAX_PARAMS`. Also, `Request::new` also needed to
be changed so that the value of `MAX_PARAMS` could be inferred. Now that
the field is a slice again, we can wrap it in `Option` again (at no cost
to size, thanks to niche opts).

We ensure we never store the redundant `Some(&[])` by checking for an
empty slice and storing `None` instead. This way, we ensure we never
read an empty slice out of the `Some` variant.
The instrument macros generate 2% of Serenity's release mode llvm-lines,
and are proc-macros so hurt compile time in that way, so this limits
them to opt-in. This commit also fixes the issues that the instrument macro
was hiding, such as results that didn't ever error and missing
documentation.
This signature is hard to use as `None` cannot infer the type of the
generic. I also replaced `Option<u8>` with `Option<NonMaxU8>` as it's
more efficient and will make the user think of the maximum value.
…nity-rs#2698)

This removes inefficient `IntoIterator` generics and instead takes what is
actually required. I also reworked `reorder_channels` to allow for keeping the
generic, as it actually does only just need iterator semantics.
Previously, someone assumed that `Ratelimiter` was going to be cloned, so
put a ton of `Arc`s everywhere. This was unneeded, and before dashmap,
so the buckets were also stored massively inefficiently. This fixes all
that.

I had to shuffle around the `Ratelimit` methods a little bit to return
their sleep time instead of sleeping themselves, so I didn't have to
hold a dashmap lock over an `.await`.
This removes multiple error variants and overall cleans up the codebase
by moving overflow checks into two `ModelError` variants.
Shrinks `size_of::<Error>` from 136 bytes to 64 bytes, while removing unused
variants. This will improve performance for any method returning
`Result<T>` where `T` is less than the size of `Error` as both `Result`'s
`Ok` and `Err` have to be allocated stack space.
The compiler knows best as inlining is quite complicated. This should
help with compile times, significantly.
mkrasnitski and others added 27 commits October 7, 2025 12:37
Rust 1.88 stabilizes let chains and clippy will lint places they can be
used.
…nity-rs#3384)

This fixes an issue introduced in [commit][cmt] when trying to rewrite with new
1.88 let-chains.

[cmt]: serenity-rs@ffaf185
`SecretString` claims it zeroizes its content on last drop. This isn't
currently the case and implementing that is around an `Arc<str>` is impractical
-- requiring unsafe or further indirection -- and likely wouldn't be useful in
reality.

This commit instead adjusts its documentation to simply state it does not
reveal the content in its `Debug` output.
Since `Channel` is non-exhaustive, then it's not easily possible for users to
match against both the `Guild` and `GuildThread` variants to extract the id of
the guild which contains said channel. This helper method allows this use-case.
This improves the ergonomics of the CI workflows and cuts down on CI
runtime by adding a new `check` job for feature flags which only need to
be tested using `cargo check` rather than `cargo test`. I removed the
dedicated `nightly` job by including it in the `test` job.

Also added `temp_cache` to the list of features to check; for some
reason it wasn't included in CI before.
…ity-rs#3412)

Back in September 2024, Discord added [Soundboard][soundboard] APIs that allow
a bot to create a new sound by uploading raw mp3 or ogg data.

This data is specified as part of the JSON rather than a multipart upload (an
odd decision IMO); however, that means that the semantics of `ImageData` are
wrong as it makes too many assumptions about its contents. In particular, we
assume that the base64 data will always be an image, and the
`CreateAttachment::encode` method always assigns the `image/png` mimetype.

This commit removes these assumptions by renaming the struct to simply
`DataUri`, and now requiring the user to specify the mimetype when calling
`CreateAttachment::encode`.

[soundboard]: https://discord.com/developers/docs/resources/soundboard#soundboard-resource
…matting the link (serenity-rs#3415)

Users can still convert it to a `String` using `ToString::to_string`, but if they happen to pass it to a formatting macro such as `format!`, they will avoid a heap allocation that would have otherwise occurred for the link, which is the motivation for this change.
The documentation for the `ReactionRemoveEmoji` event was identical to that of
`ReactionRemoveAll`. This commit tweaks it to match its function more closely.
@github-actions github-actions bot added model Related to the `model` module. builder Related to the `builder` module. labels Dec 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builder Related to the `builder` module. model Related to the `model` module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.