using System.Text.Json; using DysonNetwork.Shared.Proto; using NodaTime; using NodaTime.Serialization.SystemTextJson; namespace DysonNetwork.Pusher.Connection; public class WebSocketPacket { public string Type { get; set; } = null!; public object? Data { get; set; } = null!; public string? Endpoint { get; set; } public string? ErrorMessage { get; set; } /// /// Creates a WebSocketPacket from raw WebSocket message bytes /// /// Raw WebSocket message bytes /// Deserialized WebSocketPacket public static WebSocketPacket FromBytes(byte[] bytes) { var json = System.Text.Encoding.UTF8.GetString(bytes); var jsonOpts = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower, }; return JsonSerializer.Deserialize(json, jsonOpts) ?? throw new JsonException("Failed to deserialize WebSocketPacket"); } /// /// Deserializes the Data property to the specified type T /// /// Target type to deserialize to /// Deserialized data of type T public T? GetData() { if (Data is T typedData) return typedData; var jsonOpts = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower, }; return JsonSerializer.Deserialize( JsonSerializer.Serialize(Data, jsonOpts), jsonOpts ); } /// /// Serializes this WebSocketPacket to a byte array for sending over WebSocket /// /// Byte array representation of the packet public byte[] ToBytes() { var jsonOpts = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower, }.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb); var json = JsonSerializer.Serialize(this, jsonOpts); return System.Text.Encoding.UTF8.GetBytes(json); } public Shared.Proto.WebSocketPacket ToProtoValue() { return new Shared.Proto.WebSocketPacket { Type = Type, Data = GrpcTypeHelper.ConvertClassToValue(Data), ErrorMessage = ErrorMessage }; } public static WebSocketPacket FromProtoValue(Shared.Proto.WebSocketPacket packet) { return new WebSocketPacket { Type = packet.Type, Data = GrpcTypeHelper.ConvertValueToObject(packet.Data), ErrorMessage = packet.ErrorMessage }; } }