Skip to content

feat(model): initial pass at dealing with unknown enum variants #1550

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

Merged
merged 7 commits into from
Jul 16, 2022

Conversation

AEnterprise
Copy link
Member

@AEnterprise AEnterprise commented Feb 26, 2022

Reworking enums to have unknown variants to handle discord adding new api features.

Goal: not losing any payloads whenever discord adds something new, while keeping the type safety the enums provide since people depend on that.

This is an initial WIP draft to get discussion going on how the final implementation should look, but is fully functional.

Left to do on this:

  • standardize serialization and deserialization tests. they where all over the place, some check serde tokens, others just conversions without serde. We need to decide what kind of test general model serializations and deserializations should have => best left for a seperate PR
  • figure out a better solution for interactions, possibly by splitting it into 2 enums (a seperate one used for getting the command list over http, and one for the gateway interaction itself. Where dropping unknown interaction types might be slightly acceptable, since we can't do meaningful deserialization with the current models. Or flattening the entire interaction struct like was done with channels recently. Needs more consideration
  • Some models are also used as outgoing http payloads. We need to decide if we want to allow sending payloads with these unknown variants or error on them. Allowing unknowns can be useful in allowing people to leverage new options without a library upgrade. But if this different option also needs another field set the library won't be able to do it, nor can we ensure the value is valid. For the creation of application commands this however wasn't an option due to our custom serializer.

@AEnterprise AEnterprise added t-feature Addition of a new feature c-model Affects the model crate m-breaking change Breaks the public API. w-unapproved Proposal for change has *not* been approved by @twilight-rs/core. labels Feb 26, 2022
@AEnterprise AEnterprise self-assigned this Feb 26, 2022
@github-actions github-actions bot added c-http Affects the http crate c-validate Affects the validate crate c-util Affects the util crate labels Feb 26, 2022
Copy link
Contributor

@PyroTechniac PyroTechniac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some basic formatting, probably missed a lot.

@AEnterprise
Copy link
Member Author

Thanks, for the formatting i'm aware there is probably a lot more that needs fixing. i chose to not fix them yet for this draft because the design of this isn't fully done yet, and i'm currently looking for feedback on how it should look/work in the end

Copy link
Contributor

@spring4175 spring4175 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only commented on things once and didn't comment on formatting. Do we still have uses of the serde_repr dependency after this?

@spring4175
Copy link
Contributor

standardize serialization and deserialization tests. they where all over the place, some check serde tokens, others just conversions without serde. We need to decide what kind of test general model serializations and deserializations should have

We don't really need to test the tokens, we're essentially testing serde at that point. We should test our own conversion implementations.

figure out a better solution for interactions, possibly by splitting it into 2 enums (a seperate one used for getting the command list over http, and one for the gateway interaction itself. Where dropping unknown interaction types might be slightly acceptable, since we can't do meaningful deserialization with the current models. Or flattening the entire interaction struct like was done with channels recently. Needs more consideration

I believe we're in the long-term process of separating types between their incoming and outgoing variants. I am in favor of more flattening in general but I don't believe it's in the scope of this PR.

Some models are also used as outgoing http payloads. We need to decide if we want to allow sending payloads with these unknown variants or error on them. Allowing unknowns can be useful in allowing people to leverage new options without a library upgrade. But if this different option also needs another field set the library won't be able to do it, nor can we ensure the value is valid. For the creation of application commands this however wasn't an option due to our custom serializer.

I think if people want to use cutting edge new API features that we don't support they can use manual HTTP request bodies. Type flattening may also aid in this, but again out of scope. We may need to place some sort of priority on investigating the role flattening would have for us in general.

@AEnterprise
Copy link
Member Author

Do we still have uses of the serde_repr dependency after this?

Yes, several gateway and interaction structs still use these.

We don't really need to test the tokens, we're essentially testing serde at that point. We should test our own conversion implementations.

i'll replace the relevant tests with just testing the conversions without serde then

I believe we're in the long-term process of separating types between their incoming and outgoing variants. I am in favor of more flattening in general but I don't believe it's in the scope of this PR.

Agreed, i think we can live with it being not perfect here in what data we give when it's unknown and then clean up these few last spots when things are flattened

@AEnterprise AEnterprise force-pushed the AE/feat/unknown-variants branch from 88f8027 to a258354 Compare March 12, 2022 10:28
@7596ff 7596ff linked an issue Mar 12, 2022 that may be closed by this pull request
@7596ff
Copy link
Contributor

7596ff commented Apr 15, 2022

This does need further work, and based on some discussion in Discord, there seems to be a path forward. We should bracket any work on unknown interaction variants for now, in order to solve that problem more correctly at a later date. Also, we should try to build on whatever existing tests there are for the affected types, and follow up later to make them more consistent with each other and more correct. Lastly, I'll be making a quick PR to add the Forum channel type, as a stopgap in a minor release, which will come before a) this PR and b) Erk's work on the entire forum feature later on.

7596ff added a commit that referenced this pull request Apr 15, 2022
As a stopgap before future work on Forum channels, add their channel
type in order to stop deserialization errors which would be more
correctly fixed in #1550.
7596ff added a commit that referenced this pull request Apr 15, 2022
As a stopgap before future work on Forum channels, add their channel
type in order to stop deserialization errors which would be more
correctly fixed in #1550.
@AEnterprise AEnterprise force-pushed the AE/feat/unknown-variants branch from a258354 to 882c585 Compare April 24, 2022 11:48
@github-actions github-actions bot removed the c-util Affects the util crate label Apr 24, 2022
@AEnterprise AEnterprise force-pushed the AE/feat/unknown-variants branch from 882c585 to 5230695 Compare April 24, 2022 11:58
@AEnterprise AEnterprise marked this pull request as ready for review April 24, 2022 11:58
@github-actions github-actions bot added the c-util Affects the util crate label Apr 24, 2022
Copy link
Contributor

@7596ff 7596ff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good, a bunch of small consistency nits

@AEnterprise AEnterprise force-pushed the AE/feat/unknown-variants branch 2 times, most recently from a258354 to 3e162cd Compare May 20, 2022 12:19
@AEnterprise AEnterprise requested a review from 7596ff May 20, 2022 12:35
@@ -52,6 +78,7 @@ impl ComponentType {
Self::Button => "Button",
Self::SelectMenu => "SelectMenu",
Self::TextInput => "TextInput",
Self::Unknown(_) => "Unknown",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Commenting on this one, applis on all).
I'm not sure I like the display implementation being "Unknown", should be the number imo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually isn't possible unless i'm missing something. These functions return an &'static str. Converting the number to a string would yield a string that is owned in this scope only and thus can not be returned out of the function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's impossible in this method, but I meant for the Display implementation; currently it just calls this method, it would be better to print the integer (+ Unknown)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we don't have a display implementation for most of these, this looks like the only one that has it. It also would require to duplicate the entire match. It seems better to keep this consistent here, and look at if they should all have display implementations (or if this one should be removed) separately

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's as simple as:

fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
    if let Unknown(int) = self {
        Display::fmt(&int, f)
    } else {
        f.write_str(self.name())
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we don't have a display implementation for most of these, this looks like the only one that has it.

Ah I missed this, maybe it should be removed at a later point then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of moving to a Display implementation later on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep it as is for now then to not scope creep this PR, and follow it up to move to display soon after

@spring4175 spring4175 removed the w-unapproved Proposal for change has *not* been approved by @twilight-rs/core. label May 20, 2022
@7596ff 7596ff dismissed stale reviews from spring4175 and PyroTechniac May 20, 2022 18:47

addressed

Copy link
Contributor

@7596ff 7596ff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Excited for this change and what it makes possible.

@baptiste0928
Copy link
Member

Looks good, should we mention in CONTRIBUTING.md that enums must have an Unknown variant where applicable?

@7596ff 7596ff requested review from spring4175 and removed request for spring4175 June 7, 2022 19:52
Copy link
Contributor

@spring4175 spring4175 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thanks for the effort on it! With a rebase is this good to go?

@7596ff 7596ff merged commit 8ac375c into next Jul 16, 2022
@7596ff 7596ff deleted the AE/feat/unknown-variants branch July 16, 2022 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-http Affects the http crate c-model Affects the model crate c-util Affects the util crate c-validate Affects the validate crate m-breaking change Breaks the public API. t-feature Addition of a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RFC] Handling unknown enum variants
6 participants