Guild data polymorphism
This commit is contained in:
parent
da9be4735e
commit
073e17c96b
@ -5,7 +5,7 @@ namespace Discord.API;
|
||||
public class ChannelData
|
||||
{
|
||||
public required ulong Id { get; init; }
|
||||
public int? Type { get; init; }
|
||||
public required int Type { get; init; }
|
||||
public ulong? GuildId { get; init; }
|
||||
public int? Position { 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;
|
||||
|
||||
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 string? Name { get; init; }
|
||||
public ulong? AfkChannelId { get; init; }
|
||||
public int? AfkTimeout { get; init; }
|
||||
public RoleData[]? Roles { get; init; }
|
||||
public ulong? SystemChannelId { get; init; }
|
||||
public uint? SystemChannelFlags { get; init; }
|
||||
public string? Description { get; init; }
|
||||
public 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; }
|
||||
public required string Name { get; init; }
|
||||
public required ulong? AfkChannelId { get; init; }
|
||||
public required int AfkTimeout { get; init; }
|
||||
public required RoleData[] Roles { get; init; }
|
||||
public required ulong? SystemChannelId { get; init; }
|
||||
public required uint SystemChannelFlags { get; init; }
|
||||
public required string? Description { get; init; }
|
||||
public required int NsfwLevel { get; init; }
|
||||
}
|
||||
@ -3,49 +3,31 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Discord.API;
|
||||
|
||||
internal class GuildDataConverter : JsonConverter<UnavailableGuildData>
|
||||
internal class GuildDataConverter : JsonConverter<GuildData>
|
||||
{
|
||||
public override UnavailableGuildData? Read(ref Utf8JsonReader reader, Type typeToConvert,
|
||||
JsonSerializerOptions options)
|
||||
public override GuildData? 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() ?? "")
|
||||
};
|
||||
return new UnavailableGuildData()
|
||||
{
|
||||
Id = id
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Id property not found in guild data");
|
||||
}
|
||||
if(json_doc.RootElement.TryGetProperty("joined_at", out _)){
|
||||
return json_doc.Deserialize(SourceGenerationContext.Default.GuildCreateData);
|
||||
}else{
|
||||
return json_doc.Deserialize(SourceGenerationContext.Default.GuildUpdateData);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, UnavailableGuildData value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value is GuildData)
|
||||
{
|
||||
writer.WriteRawValue(JsonSerializer.SerializeToUtf8Bytes(value, SourceGenerationContext.Default.GuildData));
|
||||
}
|
||||
else
|
||||
public override void Write(Utf8JsonWriter writer, GuildData value, JsonSerializerOptions options)
|
||||
{
|
||||
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.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,
|
||||
IncludeFields = true,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower,
|
||||
Converters = [typeof(GatewayPacketConverter), typeof(GuildDataConverter)],
|
||||
Converters = [typeof(GatewayPacketConverter), typeof(UnavailableGuildDataConverter)],
|
||||
NumberHandling = JsonNumberHandling.AllowReadingFromString
|
||||
)]
|
||||
[JsonSerializable(typeof(GatewayPacket))]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user