Guild data polymorphism
This commit is contained in:
parent
da9be4735e
commit
073e17c96b
@ -5,7 +5,7 @@ namespace Discord.API;
|
|||||||
public class ChannelData
|
public class ChannelData
|
||||||
{
|
{
|
||||||
public required ulong Id { get; init; }
|
public required ulong Id { get; init; }
|
||||||
public int? Type { get; init; }
|
public required int Type { get; init; }
|
||||||
public ulong? GuildId { get; init; }
|
public ulong? GuildId { get; init; }
|
||||||
public int? Position { get; init; }
|
public int? Position { get; init; }
|
||||||
public string? Name { get; init; }
|
public string? Name { get; init; }
|
||||||
|
|||||||
10
Discord.API/DataTypes/GuildCreateData.cs
Normal file
10
Discord.API/DataTypes/GuildCreateData.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
public class GuildCreateData : GuildData{
|
||||||
|
public required DateTime JoinedAt { get; init; }
|
||||||
|
public required bool Large { get; init; }
|
||||||
|
public required uint MemberCount { get; init; }
|
||||||
|
public required VoiceStateData[] VoiceStates { get; init; }
|
||||||
|
public required GuildMemberData[] Members { get; init; }
|
||||||
|
public required ChannelData[] Channels { get; init; }
|
||||||
|
}
|
||||||
@ -1,20 +1,20 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
|
|
||||||
public class GuildData : UnavailableGuildData
|
|
||||||
|
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
|
||||||
|
[JsonDerivedType(typeof(GuildCreateData))]
|
||||||
|
[JsonDerivedType(typeof(GuildUpdateData))]
|
||||||
|
public abstract class GuildData : UnavailableGuildData
|
||||||
{
|
{
|
||||||
public override bool Unavailable => false;
|
public override bool Unavailable => false;
|
||||||
public string? Name { get; init; }
|
public required string Name { get; init; }
|
||||||
public ulong? AfkChannelId { get; init; }
|
public required ulong? AfkChannelId { get; init; }
|
||||||
public int? AfkTimeout { get; init; }
|
public required int AfkTimeout { get; init; }
|
||||||
public RoleData[]? Roles { get; init; }
|
public required RoleData[] Roles { get; init; }
|
||||||
public ulong? SystemChannelId { get; init; }
|
public required ulong? SystemChannelId { get; init; }
|
||||||
public uint? SystemChannelFlags { get; init; }
|
public required uint SystemChannelFlags { get; init; }
|
||||||
public string? Description { get; init; }
|
public required string? Description { get; init; }
|
||||||
public int? NsfwLevel { get; init; }
|
public required int NsfwLevel { get; init; }
|
||||||
public DateTime? JoinedAt { get; init; }
|
|
||||||
public bool? Large { get; init; }
|
|
||||||
public uint? MemberCount { get; init; }
|
|
||||||
public VoiceStateData[]? VoiceStates { get; init; }
|
|
||||||
public GuildMemberData[]? Members { get; init; }
|
|
||||||
public ChannelData[]? Channels { get; init; }
|
|
||||||
}
|
}
|
||||||
@ -3,49 +3,31 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
|
|
||||||
internal class GuildDataConverter : JsonConverter<UnavailableGuildData>
|
internal class GuildDataConverter : JsonConverter<GuildData>
|
||||||
{
|
{
|
||||||
public override UnavailableGuildData? Read(ref Utf8JsonReader reader, Type typeToConvert,
|
public override GuildData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
JsonSerializerOptions options)
|
|
||||||
{
|
{
|
||||||
JsonDocument json_doc = JsonDocument.ParseValue(ref reader);
|
JsonDocument json_doc = JsonDocument.ParseValue(ref reader);
|
||||||
if (!json_doc.RootElement.TryGetProperty("unavailable", out var unavailable_prop) ||
|
if(json_doc.RootElement.TryGetProperty("joined_at", out _)){
|
||||||
unavailable_prop.ValueKind == JsonValueKind.False)
|
return json_doc.Deserialize(SourceGenerationContext.Default.GuildCreateData);
|
||||||
{
|
}else{
|
||||||
return json_doc.Deserialize(SourceGenerationContext.Default.GuildData);
|
return json_doc.Deserialize(SourceGenerationContext.Default.GuildUpdateData);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (json_doc.RootElement.TryGetProperty("id", out var id_prop) &&
|
|
||||||
id_prop.ValueKind is JsonValueKind.String or JsonValueKind.Number)
|
|
||||||
{
|
|
||||||
ulong id = id_prop.ValueKind switch
|
|
||||||
{
|
|
||||||
JsonValueKind.Number => id_prop.GetUInt64(),
|
|
||||||
JsonValueKind.String => ulong.Parse(id_prop.GetString() ?? "")
|
|
||||||
};
|
|
||||||
return new UnavailableGuildData()
|
|
||||||
{
|
|
||||||
Id = id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new JsonException("Id property not found in guild data");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, UnavailableGuildData value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, GuildData value, JsonSerializerOptions options)
|
||||||
{
|
|
||||||
if (value is GuildData)
|
|
||||||
{
|
|
||||||
writer.WriteRawValue(JsonSerializer.SerializeToUtf8Bytes(value, SourceGenerationContext.Default.GuildData));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
switch(value){
|
||||||
|
case GuildCreateData gcd:
|
||||||
|
writer.WriteRawValue(JsonSerializer.SerializeToUtf8Bytes(gcd, SourceGenerationContext.Default.GuildCreateData));
|
||||||
|
break;
|
||||||
|
case GuildUpdateData gud:
|
||||||
|
writer.WriteRawValue(JsonSerializer.SerializeToUtf8Bytes(gud, SourceGenerationContext.Default.GuildUpdateData));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
writer.WriteStartObject();
|
writer.WriteStartObject();
|
||||||
writer.WriteBoolean("unavailable", true);
|
writer.WriteEndObject();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
5
Discord.API/DataTypes/GuildUpdateData.cs
Normal file
5
Discord.API/DataTypes/GuildUpdateData.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
public class GuildUpdateData : GuildData{
|
||||||
|
|
||||||
|
}
|
||||||
52
Discord.API/DataTypes/UnavailableGuildDataConverter.cs
Normal file
52
Discord.API/DataTypes/UnavailableGuildDataConverter.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
internal class UnavailableGuildDataConverter : JsonConverter<UnavailableGuildData>
|
||||||
|
{
|
||||||
|
public override UnavailableGuildData? Read(ref Utf8JsonReader reader, Type typeToConvert,
|
||||||
|
JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
JsonDocument json_doc = JsonDocument.ParseValue(ref reader);
|
||||||
|
if (!json_doc.RootElement.TryGetProperty("unavailable", out var unavailable_prop) ||
|
||||||
|
unavailable_prop.ValueKind == JsonValueKind.False)
|
||||||
|
{
|
||||||
|
return json_doc.Deserialize(SourceGenerationContext.Default.GuildData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (json_doc.RootElement.TryGetProperty("id", out var id_prop) &&
|
||||||
|
id_prop.ValueKind is JsonValueKind.String or JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
ulong id = id_prop.ValueKind switch
|
||||||
|
{
|
||||||
|
JsonValueKind.Number => id_prop.GetUInt64(),
|
||||||
|
JsonValueKind.String => ulong.Parse(id_prop.GetString() ?? ""),
|
||||||
|
_ => throw new JsonException("This should be impossible")
|
||||||
|
};
|
||||||
|
return new UnavailableGuildData()
|
||||||
|
{
|
||||||
|
Id = id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException("Id property not found in guild data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, UnavailableGuildData value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value is GuildData)
|
||||||
|
{
|
||||||
|
writer.WriteRawValue(JsonSerializer.SerializeToUtf8Bytes(value, SourceGenerationContext.Default.GuildData));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteStartObject();
|
||||||
|
writer.WriteBoolean("unavailable", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,7 +10,7 @@ using System.Text.Json;
|
|||||||
IgnoreReadOnlyProperties = false,
|
IgnoreReadOnlyProperties = false,
|
||||||
IncludeFields = true,
|
IncludeFields = true,
|
||||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower,
|
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower,
|
||||||
Converters = [typeof(GatewayPacketConverter), typeof(GuildDataConverter)],
|
Converters = [typeof(GatewayPacketConverter), typeof(UnavailableGuildDataConverter)],
|
||||||
NumberHandling = JsonNumberHandling.AllowReadingFromString
|
NumberHandling = JsonNumberHandling.AllowReadingFromString
|
||||||
)]
|
)]
|
||||||
[JsonSerializable(typeof(GatewayPacket))]
|
[JsonSerializable(typeof(GatewayPacket))]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user