Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make icon and unicode_emoji nullable in addition to optional #2539

Merged
merged 1 commit into from
Sep 18, 2023

Conversation

Sergiovan
Copy link
Contributor

With this PR it is now possible to properly clear a role's icon/unicode_emoji.

The problem

In both serenity/current and serenity/next all EditRole fields are skipped when they are None. This does not work for EditRole::icon and EditRole::unicode_emoji because the field being undefined is different from the field being null at the API1: if the field is undefined it will be kept unchanged, and if it is null it will be cleared.

The existing code then doesn't actually clear the icon/unicode_emoji when setting the other, but simply keeps it unchanged.

The solution

With a double Option it is possible to distinguish undefined from null from a set value. This is the canonical solution using serde (the example shows de-serialization but it works the same in reverse).

Then, None is "keep field unchanged", Some(None) is "clear this field" and Some(Some(value) is "set this field to this value"

API breaks

  • EditRole::unicode_emoji() takes a Option<String> instead of impl Into<String>.
  • EditRole::icon() takes a Option<&CreateAttachment> instead of &CreateAttachment

Verified

  • EditRole::icon(Some(...)) sets the icon and clears the Unicode emoji.
  • EditRole::icon(None) clears both icon and Unicode emoji.
  • EditRole::unicode_emoji(Some(...)) sets the Unicode emoji and clears the icon.
  • EditRole::unicode_emoji(None) clears both Unicode emoji and icon.
  • cargo +nightly fmt --all and cargo test --all pass.

Other stuff

For more control it would be possible now to remove the automatic clearing of the unicode_emoji/icon in icon()/unicode_emoji(), but I didn't see any real use-cases for this.

Footnotes

  1. "All parameters to this endpoint are optional and nullable." - https://discord.com/developers/docs/resources/guild#modify-guild-role

@github-actions github-actions bot added the builder Related to the `builder` module. label Sep 17, 2023
@arqunis arqunis added fix A solution to an existing bug. breaking change The public API is changed, resulting in miscompilations or unexpected new behaviour for users enhancement An improvement to Serenity. and removed fix A solution to an existing bug. labels Sep 18, 2023
@arqunis arqunis merged commit b35e972 into serenity-rs:next Sep 18, 2023
20 of 21 checks passed
@arqunis
Copy link
Member

arqunis commented Sep 18, 2023

Thanks!

mkrasnitski pushed a commit to mkrasnitski/serenity that referenced this pull request Sep 21, 2023
…ion to undefined (serenity-rs#2539)

All `EditRole` fields are skipped when they are `None`. This does not work for `EditRole::icon` and `EditRole::unicode_emoji` because the field being `undefined` is different from the field being `null` at the API: if the field is `undefined` it will be kept unchanged, and if it is `null` it will be cleared.

With a double `Option` it is possible to distinguish `undefined` from `null` from a set value. This is the [canonical](serde-rs/serde#984 (comment)) solution using serde (the example shows de-serialization but it works the same in reverse).

Then, `None` is "keep field unchanged", `Some(None)` is "clear this field" and `Some(Some(value)` is "set this field to this value"

# Breaking changes

- `EditRole::unicode_emoji()` takes a `Option<String>` instead of `impl Into<String>`.
- `EditRole::icon()` takes a `Option<&CreateAttachment>` instead of `&CreateAttachment`
mkrasnitski pushed a commit to mkrasnitski/serenity that referenced this pull request Oct 17, 2023
…ion to undefined (serenity-rs#2539)

All `EditRole` fields are skipped when they are `None`. This does not work for `EditRole::icon` and `EditRole::unicode_emoji` because the field being `undefined` is different from the field being `null` at the API: if the field is `undefined` it will be kept unchanged, and if it is `null` it will be cleared.

With a double `Option` it is possible to distinguish `undefined` from `null` from a set value. This is the [canonical](serde-rs/serde#984 (comment)) solution using serde (the example shows de-serialization but it works the same in reverse).

Then, `None` is "keep field unchanged", `Some(None)` is "clear this field" and `Some(Some(value)` is "set this field to this value"

# Breaking changes

- `EditRole::unicode_emoji()` takes a `Option<String>` instead of `impl Into<String>`.
- `EditRole::icon()` takes a `Option<&CreateAttachment>` instead of `&CreateAttachment`
mkrasnitski pushed a commit to mkrasnitski/serenity that referenced this pull request Oct 24, 2023
…ion to undefined (serenity-rs#2539)

All `EditRole` fields are skipped when they are `None`. This does not work for `EditRole::icon` and `EditRole::unicode_emoji` because the field being `undefined` is different from the field being `null` at the API: if the field is `undefined` it will be kept unchanged, and if it is `null` it will be cleared.

With a double `Option` it is possible to distinguish `undefined` from `null` from a set value. This is the [canonical](serde-rs/serde#984 (comment)) solution using serde (the example shows de-serialization but it works the same in reverse).

Then, `None` is "keep field unchanged", `Some(None)` is "clear this field" and `Some(Some(value)` is "set this field to this value"

# Breaking changes

- `EditRole::unicode_emoji()` takes a `Option<String>` instead of `impl Into<String>`.
- `EditRole::icon()` takes a `Option<&CreateAttachment>` instead of `&CreateAttachment`
arqunis pushed a commit to arqunis/serenity that referenced this pull request Oct 24, 2023
…ion to undefined (serenity-rs#2539)

All `EditRole` fields are skipped when they are `None`. This does not work for `EditRole::icon` and `EditRole::unicode_emoji` because the field being `undefined` is different from the field being `null` at the API: if the field is `undefined` it will be kept unchanged, and if it is `null` it will be cleared.

With a double `Option` it is possible to distinguish `undefined` from `null` from a set value. This is the [canonical](serde-rs/serde#984 (comment)) solution using serde (the example shows de-serialization but it works the same in reverse).

Then, `None` is "keep field unchanged", `Some(None)` is "clear this field" and `Some(Some(value)` is "set this field to this value"

# Breaking changes

- `EditRole::unicode_emoji()` takes a `Option<String>` instead of `impl Into<String>`.
- `EditRole::icon()` takes a `Option<&CreateAttachment>` instead of `&CreateAttachment`
arqunis pushed a commit to arqunis/serenity that referenced this pull request Oct 24, 2023
…ion to undefined (serenity-rs#2539)

All `EditRole` fields are skipped when they are `None`. This does not work for `EditRole::icon` and `EditRole::unicode_emoji` because the field being `undefined` is different from the field being `null` at the API: if the field is `undefined` it will be kept unchanged, and if it is `null` it will be cleared.

With a double `Option` it is possible to distinguish `undefined` from `null` from a set value. This is the [canonical](serde-rs/serde#984 (comment)) solution using serde (the example shows de-serialization but it works the same in reverse).

Then, `None` is "keep field unchanged", `Some(None)` is "clear this field" and `Some(Some(value)` is "set this field to this value"

# Breaking changes

- `EditRole::unicode_emoji()` takes a `Option<String>` instead of `impl Into<String>`.
- `EditRole::icon()` takes a `Option<&CreateAttachment>` instead of `&CreateAttachment`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change The public API is changed, resulting in miscompilations or unexpected new behaviour for users builder Related to the `builder` module. enhancement An improvement to Serenity.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants