From fed2e9451794d659d4cc7486ac1eeccc25a78698 Mon Sep 17 00:00:00 2001 From: RogueException Date: Mon, 7 Aug 2017 01:44:10 -0300 Subject: [PATCH] Added ExcludeNull support --- .../JsonConverters/EntityOrIdPropertyConverter.cs | 17 ++++--- .../JsonConverters/ImagePropertyConverter.cs | 4 +- .../JsonConverters/Int53PropertyConverter.cs | 13 ++++-- .../JsonConverters/OptionalPropertyConverter.cs | 8 ++-- .../JsonConverters/UInt53PropertyConverter.cs | 13 ++++-- .../Json/Converters/Collections.cs | 15 ++++--- .../Json/Converters/Nullable.cs | 17 ++++--- .../Json/Converters/Primitives.DateTime.cs | 26 +++++++---- .../Json/Converters/Primitives.Enum.cs | 4 +- .../Json/Converters/Primitives.Float.cs | 39 +++++++++++----- .../Json/Converters/Primitives.Other.cs | 26 +++++++---- .../Json/Converters/Primitives.Signed.cs | 52 +++++++++++++++------- .../Json/Converters/Primitives.String.cs | 26 +++++++---- .../Json/Converters/Primitives.Unsigned.cs | 52 +++++++++++++++------- .../Json/IJsonPropertyConverter.cs | 4 +- src/Discord.Net.Serialization/Json/JsonFormat.cs | 6 +-- .../Json/JsonPropertyMap.cs | 6 ++- .../ModelPropertyAttribute.cs | 4 +- src/Discord.Net.Serialization/PropertyMap.cs | 8 ++-- src/Discord.Net.WebSocket/API/SocketFrame.cs | 4 +- 20 files changed, 225 insertions(+), 119 deletions(-) diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs index 4eeab4ca3..8cdbaab3e 100644 --- a/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs +++ b/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs @@ -12,21 +12,26 @@ namespace Discord.Serialization.Json.Converters _innerConverter = innerConverter; } - public EntityOrId Read(JsonReader reader, bool read = true) + public EntityOrId Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType == JsonValueType.Number) return new EntityOrId(reader.ParseUInt64()); - return new EntityOrId(_innerConverter.Read(reader)); + return new EntityOrId(_innerConverter.Read(map, reader, false)); } - public void Write(JsonWriter writer, EntityOrId value) + public void Write(PropertyMap map, JsonWriter writer, EntityOrId value, bool isTopLevel) { if (value.Object != null) - _innerConverter.Write(writer, value.Object); + _innerConverter.Write(map, writer, value.Object, isTopLevel); else - writer.WriteValue(value.Id); + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.Id); + else + writer.WriteValue(value.Id); + } } } } diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/ImagePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/ImagePropertyConverter.cs index af3fcd76e..1c73e9440 100644 --- a/src/Discord.Net.Rest/Serialization/JsonConverters/ImagePropertyConverter.cs +++ b/src/Discord.Net.Rest/Serialization/JsonConverters/ImagePropertyConverter.cs @@ -4,9 +4,9 @@ namespace Discord.Serialization.Json.Converters { internal class ImagePropertyConverter : IJsonPropertyConverter { - public API.Image Read(JsonReader reader, bool read = true) + public API.Image Read(PropertyMap map, JsonReader reader, bool isTopLevel) => throw new System.NotImplementedException(); - public void Write(JsonWriter writer, API.Image value) + public void Write(PropertyMap map, JsonWriter writer, API.Image value, bool isTopLevel) => throw new System.NotImplementedException(); } } diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs index e8006a33e..0b9f0a285 100644 --- a/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs +++ b/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs @@ -4,15 +4,20 @@ namespace Discord.Serialization.Json.Converters { internal class Int53PropertyConverter : IJsonPropertyConverter { - public long Read(JsonReader reader, bool read = true) + public long Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseInt64(); } - public void Write(JsonWriter writer, long value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, long value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs index 82dc700ab..8c0c276f4 100644 --- a/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs +++ b/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs @@ -11,13 +11,13 @@ namespace Discord.Serialization.Json.Converters _innerConverter = innerConverter; } - public Optional Read(JsonReader reader, bool read = true) - => new Optional(_innerConverter.Read(reader, read)); + public Optional Read(PropertyMap map, JsonReader reader, bool isTopLevel) + => new Optional(_innerConverter.Read(map, reader, isTopLevel)); - public void Write(JsonWriter writer, Optional value) + public void Write(PropertyMap map, JsonWriter writer, Optional value, bool isTopLevel) { if (value.IsSpecified) - _innerConverter.Write(writer, value.Value); + _innerConverter.Write(map, writer, value.Value, isTopLevel); } } } diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs index 5dd482fe9..02a76a1e5 100644 --- a/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs +++ b/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs @@ -4,15 +4,20 @@ namespace Discord.Serialization.Json.Converters { internal class UInt53PropertyConverter : IJsonPropertyConverter { - public ulong Read(JsonReader reader, bool read = true) + public ulong Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseUInt64(); } - public void Write(JsonWriter writer, ulong value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, ulong value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Collections.cs b/src/Discord.Net.Serialization/Json/Converters/Collections.cs index 0b6fcaae1..95567322e 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Collections.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Collections.cs @@ -12,22 +12,25 @@ namespace Discord.Serialization.Json.Converters _innerConverter = innerConverter; } - public List Read(JsonReader reader, bool read = true) + public List Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if ((read && !reader.Read()) || reader.TokenType != JsonTokenType.StartArray) + if ((isTopLevel && !reader.Read()) || reader.TokenType != JsonTokenType.StartArray) throw new SerializationException("Bad input, expected StartArray"); var list = new List(); while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - list.Add(_innerConverter.Read(reader)); + list.Add(_innerConverter.Read(map, reader, false)); return list; } - public void Write(JsonWriter writer, List value) + public void Write(PropertyMap map, JsonWriter writer, List value, bool isTopLevel) { - writer.WriteArrayStart(); + if (isTopLevel) + writer.WriteArrayStart(map.Key); + else + writer.WriteArrayStart(); for (int i = 0; i < value.Count; i++) - _innerConverter.Write(writer, value[i]); + _innerConverter.Write(map, writer, value[i], false); writer.WriteArrayEnd(); } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Nullable.cs b/src/Discord.Net.Serialization/Json/Converters/Nullable.cs index 625f4401c..2f39ca99a 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Nullable.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Nullable.cs @@ -12,21 +12,26 @@ namespace Discord.Serialization.Json.Converters _innerConverter = innerConverter; } - public T? Read(JsonReader reader, bool read = true) + public T? Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType == JsonValueType.Null) return null; - return _innerConverter.Read(reader, false); + return _innerConverter.Read(map, reader, false); } - public void Write(JsonWriter writer, T? value) + public void Write(PropertyMap map, JsonWriter writer, T? value, bool isTopLevel) { if (value.HasValue) - _innerConverter.Write(writer, value.Value); + _innerConverter.Write(map, writer, value.Value, isTopLevel); else - writer.WriteNull(); + { + if (isTopLevel) + writer.WriteAttributeNull(map.Key); + else + writer.WriteNull(); + } } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.DateTime.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.DateTime.cs index 3f5d9ccd7..2039c0e54 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.DateTime.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.DateTime.cs @@ -5,29 +5,39 @@ namespace Discord.Serialization.Json.Converters { internal class DateTimePropertyConverter : IJsonPropertyConverter { - public DateTime Read(JsonReader reader, bool read = true) + public DateTime Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseDateTime(); } - public void Write(JsonWriter writer, DateTime value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, DateTime value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class DateTimeOffsetPropertyConverter : IJsonPropertyConverter { - public DateTimeOffset Read(JsonReader reader, bool read = true) + public DateTimeOffset Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseDateTimeOffset(); } - public void Write(JsonWriter writer, DateTimeOffset value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, DateTimeOffset value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Enum.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Enum.cs index da19e8684..6f3d6fc5a 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Enum.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Enum.cs @@ -4,9 +4,9 @@ namespace Discord.Serialization.Json.Converters { internal class EnumPropertyConverter : IJsonPropertyConverter { - public T Read(JsonReader reader, bool read = true) + public T Read(PropertyMap map, JsonReader reader, bool isTopLevel) => throw new System.NotImplementedException(); - public void Write(JsonWriter writer, T value) + public void Write(PropertyMap map, JsonWriter writer, T value, bool isTopLevel) => throw new System.NotImplementedException(); } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Float.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Float.cs index f8824113c..4ee5fd3e0 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Float.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Float.cs @@ -4,43 +4,58 @@ namespace Discord.Serialization.Json.Converters { internal class SinglePropertyConverter : IJsonPropertyConverter { - public float Read(JsonReader reader, bool read = true) + public float Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseSingle(); } - public void Write(JsonWriter writer, float value) - => writer.WriteValue(value.ToString()); + public void Write(PropertyMap map, JsonWriter writer, float value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } internal class DoublePropertyConverter : IJsonPropertyConverter { - public double Read(JsonReader reader, bool read = true) + public double Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseDouble(); } - public void Write(JsonWriter writer, double value) - => writer.WriteValue(value.ToString()); + public void Write(PropertyMap map, JsonWriter writer, double value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } internal class DecimalPropertyConverter : IJsonPropertyConverter { - public decimal Read(JsonReader reader, bool read = true) + public decimal Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseDecimal(); } - public void Write(JsonWriter writer, decimal value) - => writer.WriteValue(value.ToString()); + public void Write(PropertyMap map, JsonWriter writer, decimal value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs index f64e079ce..81a165589 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Other.cs @@ -5,9 +5,9 @@ namespace Discord.Serialization.Json.Converters { internal class BooleanPropertyConverter : IJsonPropertyConverter { - public bool Read(JsonReader reader, bool read = true) + public bool Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); switch (reader.ValueType) { @@ -16,21 +16,31 @@ namespace Discord.Serialization.Json.Converters default: throw new SerializationException("Bad input, expected False or True"); } } - public void Write(JsonWriter writer, bool value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, bool value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class GuidPropertyConverter : IJsonPropertyConverter { - public Guid Read(JsonReader reader, bool read = true) + public Guid Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return Guid.Parse(reader.ParseString()); } - public void Write(JsonWriter writer, Guid value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, Guid value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Signed.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Signed.cs index a3ade8507..85465bc08 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Signed.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Signed.cs @@ -4,57 +4,77 @@ namespace Discord.Serialization.Json.Converters { internal class Int8PropertyConverter : IJsonPropertyConverter { - public sbyte Read(JsonReader reader, bool read = true) + public sbyte Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseInt8(); } - public void Write(JsonWriter writer, sbyte value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, sbyte value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class Int16PropertyConverter : IJsonPropertyConverter { - public short Read(JsonReader reader, bool read = true) + public short Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseInt16(); } - public void Write(JsonWriter writer, short value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, short value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class Int32PropertyConverter : IJsonPropertyConverter { - public int Read(JsonReader reader, bool read = true) + public int Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseInt32(); } - public void Write(JsonWriter writer, int value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, int value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class Int64PropertyConverter : IJsonPropertyConverter { - public long Read(JsonReader reader, bool read = true) + public long Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseInt64(); } - public void Write(JsonWriter writer, long value) - => writer.WriteValue(value.ToString()); + public void Write(PropertyMap map, JsonWriter writer, long value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.String.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.String.cs index 90c8604e8..9f2867899 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.String.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.String.cs @@ -4,29 +4,39 @@ namespace Discord.Serialization.Json.Converters { internal class CharPropertyConverter : IJsonPropertyConverter { - public char Read(JsonReader reader, bool read = true) + public char Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseChar(); } - public void Write(JsonWriter writer, char value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, char value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value.ToString()); + } } internal class StringPropertyConverter : IJsonPropertyConverter { - public string Read(JsonReader reader, bool read = true) + public string Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseString(); } - public void Write(JsonWriter writer, string value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, string value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } } diff --git a/src/Discord.Net.Serialization/Json/Converters/Primitives.Unsigned.cs b/src/Discord.Net.Serialization/Json/Converters/Primitives.Unsigned.cs index 3afa66a74..e5167ce47 100644 --- a/src/Discord.Net.Serialization/Json/Converters/Primitives.Unsigned.cs +++ b/src/Discord.Net.Serialization/Json/Converters/Primitives.Unsigned.cs @@ -4,57 +4,77 @@ namespace Discord.Serialization.Json.Converters { internal class UInt8PropertyConverter : IJsonPropertyConverter { - public byte Read(JsonReader reader, bool read = true) + public byte Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseUInt8(); } - public void Write(JsonWriter writer, byte value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, byte value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class UInt16PropertyConverter : IJsonPropertyConverter { - public ushort Read(JsonReader reader, bool read = true) + public ushort Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseUInt16(); } - public void Write(JsonWriter writer, ushort value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, ushort value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class UInt32PropertyConverter : IJsonPropertyConverter { - public uint Read(JsonReader reader, bool read = true) + public uint Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.Number) throw new SerializationException("Bad input, expected Number"); return reader.ParseUInt32(); } - public void Write(JsonWriter writer, uint value) - => writer.WriteValue(value); + public void Write(PropertyMap map, JsonWriter writer, uint value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value); + else + writer.WriteValue(value); + } } internal class UInt64PropertyConverter : IJsonPropertyConverter { - public ulong Read(JsonReader reader, bool read = true) + public ulong Read(PropertyMap map, JsonReader reader, bool isTopLevel) { - if (read) + if (isTopLevel) reader.Read(); if (reader.ValueType != JsonValueType.String) throw new SerializationException("Bad input, expected String"); return reader.ParseUInt64(); } - public void Write(JsonWriter writer, ulong value) - => writer.WriteValue(value.ToString()); + public void Write(PropertyMap map, JsonWriter writer, ulong value, bool isTopLevel) + { + if (isTopLevel) + writer.WriteAttribute(map.Key, value.ToString()); + else + writer.WriteValue(value.ToString()); + } } } diff --git a/src/Discord.Net.Serialization/Json/IJsonPropertyConverter.cs b/src/Discord.Net.Serialization/Json/IJsonPropertyConverter.cs index f09acb1b7..1a9709b7a 100644 --- a/src/Discord.Net.Serialization/Json/IJsonPropertyConverter.cs +++ b/src/Discord.Net.Serialization/Json/IJsonPropertyConverter.cs @@ -4,7 +4,7 @@ namespace Discord.Serialization.Json { public interface IJsonPropertyConverter { - T Read(JsonReader reader, bool read = true); - void Write(JsonWriter writer, T value); + T Read(PropertyMap map, JsonReader reader, bool isTopLevel); + void Write(PropertyMap map, JsonWriter writer, T value, bool isTopLevel); } } diff --git a/src/Discord.Net.Serialization/Json/JsonFormat.cs b/src/Discord.Net.Serialization/Json/JsonFormat.cs index 4d406ba78..8b55f150d 100644 --- a/src/Discord.Net.Serialization/Json/JsonFormat.cs +++ b/src/Discord.Net.Serialization/Json/JsonFormat.cs @@ -92,11 +92,7 @@ namespace Discord.Serialization.Json writer.WriteObjectStart(); for (int i = 0; i < map.Properties.Length; i++) - { - var property = map.Properties[i]; - writer.WriteStartAttribute(property.Key); - (property as IJsonPropertyMap).Write(model, writer); - } + (map.Properties[i] as IJsonPropertyMap).Write(model, writer); writer.WriteObjectEnd(); } } diff --git a/src/Discord.Net.Serialization/Json/JsonPropertyMap.cs b/src/Discord.Net.Serialization/Json/JsonPropertyMap.cs index 5d745deee..2fa374270 100644 --- a/src/Discord.Net.Serialization/Json/JsonPropertyMap.cs +++ b/src/Discord.Net.Serialization/Json/JsonPropertyMap.cs @@ -22,11 +22,13 @@ namespace Discord.Serialization.Json public void Write(TModel model, JsonWriter writer) { var value = _getFunc(model); - _converter.Write(writer, value); + if (value == null && ExcludeNull) + return; + _converter.Write(this, writer, value, true); } public void Read(TModel model, JsonReader reader) { - var value = _converter.Read(reader); + var value = _converter.Read(this, reader, true); _setFunc(model, value); } } diff --git a/src/Discord.Net.Serialization/ModelPropertyAttribute.cs b/src/Discord.Net.Serialization/ModelPropertyAttribute.cs index 185576e43..c1ceeca73 100644 --- a/src/Discord.Net.Serialization/ModelPropertyAttribute.cs +++ b/src/Discord.Net.Serialization/ModelPropertyAttribute.cs @@ -5,9 +5,9 @@ namespace Discord.Serialization public class ModelPropertyAttribute : Attribute { public string Key { get; } - public bool IgnoreNull { get; set; } + public bool ExcludeNull { get; set; } - public ModelPropertyAttribute(string key) + public ModelPropertyAttribute(string key = null) { Key = key; } diff --git a/src/Discord.Net.Serialization/PropertyMap.cs b/src/Discord.Net.Serialization/PropertyMap.cs index 4102f8ecc..b2f3e2ab3 100644 --- a/src/Discord.Net.Serialization/PropertyMap.cs +++ b/src/Discord.Net.Serialization/PropertyMap.cs @@ -5,14 +5,14 @@ namespace Discord.Serialization public abstract class PropertyMap { public string Key { get; } + public bool ExcludeNull { get; } public PropertyMap(PropertyInfo propInfo) { var jsonProperty = propInfo.GetCustomAttribute(); - if (jsonProperty != null) - Key = jsonProperty.Key; - else - Key = propInfo.Name; + + Key = jsonProperty?.Key ?? propInfo.Name; + ExcludeNull = jsonProperty?.ExcludeNull ?? false; } } } diff --git a/src/Discord.Net.WebSocket/API/SocketFrame.cs b/src/Discord.Net.WebSocket/API/SocketFrame.cs index 24b7faa60..fa7ea4a09 100644 --- a/src/Discord.Net.WebSocket/API/SocketFrame.cs +++ b/src/Discord.Net.WebSocket/API/SocketFrame.cs @@ -8,9 +8,9 @@ namespace Discord.API { [ModelProperty("op")] public int Operation { get; set; } - [ModelProperty("t", IgnoreNull = true)] + [ModelProperty("t", ExcludeNull = true)] public string Type { get; set; } - [ModelProperty("s", IgnoreNull = true)] + [ModelProperty("s", ExcludeNull = true)] public int? Sequence { get; set; } [ModelProperty("d")] public ReadOnlyBuffer Payload { get; set; }