Implement DiscordGuild SystemChannel
Created by: uwx
Summary
Implements SystemChannel (system_channel_id
on API side). This controls what channel new member messages are sent to, and such.
Details
The problem
This boi:
So, system_channel_id
is a snowflake, and on guild modify it can be null
to indicate no system channel, or not present to indicate no change. There is no easy way to represent this in C#. an Optional<ulong?>
doesn't serialize properly (a non-null or a null with NullValueHandling.Include
set will always be present, this is not what we want); ulong?
is too broad (with NullValueHandling.Include
this will disable system channel when we don't want it to. with NullValueHandling.Ignore
this will make it impossible to disable system channel.)
The solution
Currently: an ulong?
with NullValueHandling.Include
(so it's possible to disable system channel), but with bool HasSystemChannelId
property that set only when the property is present, an Optional<ulong?>
wrapper on the outside that sets HasSystemChannelId, and a ShouldSerialize
method pointing to HasSystemChannelId, which JSON.NET will understand and properly ignore the value if necessary.
The drawback
Well, we're adding an extra property and an extra method for every optional endpoint argument, which is far from optimal.
The (potential) solution to the drawback
To be honest, I have no idea. A custom JsonConverter for Optional<Nullable<struct>>
would probably work if you can ignore the value from inside the JsonConverter. TODO: check whether this is possible.
The alternative, hacky solution
Include the original SystemChannel as default for ModifyAsync. This introduces a race condition and a concept that all further optional endpoint arguments have to depend on, which is probably a bad idea.
Changes proposed
- Update DiscordApiClient.ModifyGuildAsync to include system channel param
- Update DiscordGuild.ModifyAsync and GuildEditModel to include system channel
- Added DiscordGuild.SystemChannel (I have no clue if I did it right, I'm tired)
Notes
Please don't immediately close this PR because I used camelCase for the variables instead of under_score