Skip to content

Commit

Permalink
fix(model): Deserialize unavailable guilds in GUILD_CREATE.
Browse files Browse the repository at this point in the history
This changes GuildCreate from being a tuple struct to being a enum
that can either be available or unavailable, and containing either a
full Guild or a UnavailableGuild.
  • Loading branch information
Erk- committed Mar 31, 2024
1 parent 703f016 commit aac819b
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 22 deletions.
2 changes: 1 addition & 1 deletion examples/gateway-request-members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async fn main() -> anyhow::Result<()> {
match event {
Event::GuildCreate(guild) => {
// Let's request all of the guild's members for caching.
shard.command(&RequestGuildMembers::builder(guild.id).query("", None));
shard.command(&RequestGuildMembers::builder(guild.id()).query("", None));
}
Event::Ready(_) => {
// You can also specify an individual member within a guild.
Expand Down
15 changes: 10 additions & 5 deletions twilight-cache-inmemory/src/event/guild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,12 @@ impl<CacheModels: CacheableModels> InMemoryCache<CacheModels> {

impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for GuildCreate {
fn update(&self, cache: &InMemoryCache<CacheModels>) {
cache.cache_guild(self.0.clone());
match self {
GuildCreate::Available(g) => cache.cache_guild(g.clone()),
GuildCreate::Unavailable(g) => {
cache.unavailable_guilds.insert(g.id);
}
}
}
}

Expand Down Expand Up @@ -350,7 +355,7 @@ mod tests {
let cache = DefaultInMemoryCache::new();
let guild = test::guild(Id::new(1), None);

cache.update(&GuildCreate(guild.clone()));
cache.update(&GuildCreate::Availible(guild.clone()));

Check failure on line 358 in twilight-cache-inmemory/src/event/guild.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available

let mutation = PartialGuild {
id: guild.id,
Expand Down Expand Up @@ -406,7 +411,7 @@ mod tests {
let member = test::member(user_id);
let guild = test::guild(guild_id, Some(1));

cache.update(&GuildCreate(guild));
cache.update(&GuildCreate::Availible(guild));

Check failure on line 414 in twilight-cache-inmemory/src/event/guild.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available
cache.update(&MemberAdd { guild_id, member });

assert_eq!(cache.guild(guild_id).unwrap().member_count, Some(2));
Expand All @@ -425,7 +430,7 @@ mod tests {
let mut guild = test::guild(guild_id, Some(1));
guild.members.push(member);

cache.update(&GuildCreate(guild.clone()));
cache.update(&GuildCreate::Availible(guild.clone()));

Check failure on line 433 in twilight-cache-inmemory/src/event/guild.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available

assert_eq!(
1,
Expand All @@ -446,7 +451,7 @@ mod tests {
);
assert!(cache.guild(guild_id).unwrap().unavailable);

cache.update(&GuildCreate(guild));
cache.update(&GuildCreate::Availible(guild));

Check failure on line 454 in twilight-cache-inmemory/src/event/guild.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available

assert_eq!(
1,
Expand Down
8 changes: 4 additions & 4 deletions twilight-cache-inmemory/src/permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ mod tests {
let cache = DefaultInMemoryCache::new();
let permissions = cache.permissions();

cache.update(&GuildCreate(base_guild()));
cache.update(&GuildCreate::Availible(base_guild()));

Check failure on line 926 in twilight-cache-inmemory/src/permission.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available
cache.update(&MemberAdd {
guild_id: GUILD_ID,
member: test::member(USER_ID),
Expand Down Expand Up @@ -969,7 +969,7 @@ mod tests {
let cache = DefaultInMemoryCache::new();
let permissions = cache.permissions();

cache.update(&GuildCreate(base_guild()));
cache.update(&GuildCreate::Availible(base_guild()));

Check failure on line 972 in twilight-cache-inmemory/src/permission.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available
assert!(matches!(
permissions.in_channel(USER_ID, CHANNEL_ID).unwrap_err().kind(),
ChannelErrorType::ChannelUnavailable { channel_id: c_id }
Expand Down Expand Up @@ -1030,7 +1030,7 @@ mod tests {
fn owner() -> Result<(), Box<dyn Error>> {
let cache = DefaultInMemoryCache::new();
let permissions = cache.permissions();
cache.update(&GuildCreate(base_guild()));
cache.update(&GuildCreate::Availible(base_guild()));

Check failure on line 1033 in twilight-cache-inmemory/src/permission.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available

assert!(permissions.root(OWNER_ID, GUILD_ID)?.is_all());

Expand Down Expand Up @@ -1088,7 +1088,7 @@ mod tests {
everyone_permissions,
)]);

cache.update(&GuildCreate(guild));
cache.update(&GuildCreate::Availible(guild));

Check failure on line 1091 in twilight-cache-inmemory/src/permission.rs

View workflow job for this annotation

GitHub Actions / Spelling

Availible ==> Available
let mut member = test::member(USER_ID);
member.communication_disabled_until = Some(in_future);
cache.update(&MemberAdd {
Expand Down
2 changes: 1 addition & 1 deletion twilight-model/src/gateway/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl Event {
Event::ChannelUpdate(e) => e.0.guild_id,
Event::CommandPermissionsUpdate(e) => Some(e.0.guild_id),
Event::GuildAuditLogEntryCreate(e) => e.0.guild_id,
Event::GuildCreate(e) => Some(e.0.id),
Event::GuildCreate(e) => Some(e.id()),
Event::GuildDelete(e) => Some(e.id),
Event::GuildEmojisUpdate(e) => Some(e.guild_id),
Event::GuildIntegrationsUpdate(e) => Some(e.guild_id),
Expand Down
62 changes: 51 additions & 11 deletions twilight-model/src/gateway/payload/incoming/guild_create.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,60 @@
use crate::guild::Guild;
use crate::{
guild::{Guild, UnavailableGuild},
id::{marker::GuildMarker, Id},
};
use serde::{Deserialize, Serialize};
use std::ops::{Deref, DerefMut};

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct GuildCreate(pub Guild);

impl Deref for GuildCreate {
type Target = Guild;
#[serde(untagged)]
pub enum GuildCreate {
Available(Guild),
Unavailable(UnavailableGuild),
}

fn deref(&self) -> &Self::Target {
&self.0
impl GuildCreate {
/// Extract guild id.
pub const fn id(&self) -> Id<GuildMarker> {
match self {
GuildCreate::Available(g) => g.id,
GuildCreate::Unavailable(g) => g.id,
}
}
}

impl DerefMut for GuildCreate {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
#[cfg(test)]
mod tests {
use serde_test::Token;

use crate::{guild::UnavailableGuild, id::Id};

use super::GuildCreate;

#[test]
fn unavailable_guild() {
let expected = GuildCreate::Unavailable(UnavailableGuild {
id: Id::new(1234),
unavailable: true,
});

// Note: This looks a bit strange because it does not use
// Token::TupleVariant, this is because it will
// serialize back into a struct, and thus make it
// fails. This also tests that the enum is transparent
// for serde.
serde_test::assert_tokens(
&expected,
&[
Token::Struct {
name: "UnavailableGuild",
len: 2,
},
Token::Str("id"),
Token::NewtypeStruct { name: "Id" },
Token::Str("1234"),
Token::Str("unavailable"),
Token::Bool(true),
Token::StructEnd,
],
);
}
}

0 comments on commit aac819b

Please sign in to comment.