@@ -12,21 +12,26 @@ namespace Discord.Serialization.Json.Converters | |||||
_innerConverter = innerConverter; | _innerConverter = innerConverter; | ||||
} | } | ||||
public EntityOrId<T> Read(JsonReader reader, bool read = true) | |||||
public EntityOrId<T> Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType == JsonValueType.Number) | if (reader.ValueType == JsonValueType.Number) | ||||
return new EntityOrId<T>(reader.ParseUInt64()); | return new EntityOrId<T>(reader.ParseUInt64()); | ||||
return new EntityOrId<T>(_innerConverter.Read(reader)); | |||||
return new EntityOrId<T>(_innerConverter.Read(map, reader, false)); | |||||
} | } | ||||
public void Write(JsonWriter writer, EntityOrId<T> value) | |||||
public void Write(PropertyMap map, JsonWriter writer, EntityOrId<T> value, bool isTopLevel) | |||||
{ | { | ||||
if (value.Object != null) | if (value.Object != null) | ||||
_innerConverter.Write(writer, value.Object); | |||||
_innerConverter.Write(map, writer, value.Object, isTopLevel); | |||||
else | else | ||||
writer.WriteValue(value.Id); | |||||
{ | |||||
if (isTopLevel) | |||||
writer.WriteAttribute(map.Key, value.Id); | |||||
else | |||||
writer.WriteValue(value.Id); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -4,9 +4,9 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class ImagePropertyConverter : IJsonPropertyConverter<API.Image> | internal class ImagePropertyConverter : IJsonPropertyConverter<API.Image> | ||||
{ | { | ||||
public API.Image Read(JsonReader reader, bool read = true) | |||||
public API.Image Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
=> throw new System.NotImplementedException(); | => 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(); | => throw new System.NotImplementedException(); | ||||
} | } | ||||
} | } |
@@ -4,15 +4,20 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class Int53PropertyConverter : IJsonPropertyConverter<long> | internal class Int53PropertyConverter : IJsonPropertyConverter<long> | ||||
{ | { | ||||
public long Read(JsonReader reader, bool read = true) | |||||
public long Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseInt64(); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -11,13 +11,13 @@ namespace Discord.Serialization.Json.Converters | |||||
_innerConverter = innerConverter; | _innerConverter = innerConverter; | ||||
} | } | ||||
public Optional<T> Read(JsonReader reader, bool read = true) | |||||
=> new Optional<T>(_innerConverter.Read(reader, read)); | |||||
public Optional<T> Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
=> new Optional<T>(_innerConverter.Read(map, reader, isTopLevel)); | |||||
public void Write(JsonWriter writer, Optional<T> value) | |||||
public void Write(PropertyMap map, JsonWriter writer, Optional<T> value, bool isTopLevel) | |||||
{ | { | ||||
if (value.IsSpecified) | if (value.IsSpecified) | ||||
_innerConverter.Write(writer, value.Value); | |||||
_innerConverter.Write(map, writer, value.Value, isTopLevel); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -4,15 +4,20 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class UInt53PropertyConverter : IJsonPropertyConverter<ulong> | internal class UInt53PropertyConverter : IJsonPropertyConverter<ulong> | ||||
{ | { | ||||
public ulong Read(JsonReader reader, bool read = true) | |||||
public ulong Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseUInt64(); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -12,22 +12,25 @@ namespace Discord.Serialization.Json.Converters | |||||
_innerConverter = innerConverter; | _innerConverter = innerConverter; | ||||
} | } | ||||
public List<T> Read(JsonReader reader, bool read = true) | |||||
public List<T> 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"); | throw new SerializationException("Bad input, expected StartArray"); | ||||
var list = new List<T>(); | var list = new List<T>(); | ||||
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) | while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) | ||||
list.Add(_innerConverter.Read(reader)); | |||||
list.Add(_innerConverter.Read(map, reader, false)); | |||||
return list; | return list; | ||||
} | } | ||||
public void Write(JsonWriter writer, List<T> value) | |||||
public void Write(PropertyMap map, JsonWriter writer, List<T> value, bool isTopLevel) | |||||
{ | { | ||||
writer.WriteArrayStart(); | |||||
if (isTopLevel) | |||||
writer.WriteArrayStart(map.Key); | |||||
else | |||||
writer.WriteArrayStart(); | |||||
for (int i = 0; i < value.Count; i++) | for (int i = 0; i < value.Count; i++) | ||||
_innerConverter.Write(writer, value[i]); | |||||
_innerConverter.Write(map, writer, value[i], false); | |||||
writer.WriteArrayEnd(); | writer.WriteArrayEnd(); | ||||
} | } | ||||
} | } | ||||
@@ -12,21 +12,26 @@ namespace Discord.Serialization.Json.Converters | |||||
_innerConverter = innerConverter; | _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(); | reader.Read(); | ||||
if (reader.ValueType == JsonValueType.Null) | if (reader.ValueType == JsonValueType.Null) | ||||
return 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) | if (value.HasValue) | ||||
_innerConverter.Write(writer, value.Value); | |||||
_innerConverter.Write(map, writer, value.Value, isTopLevel); | |||||
else | else | ||||
writer.WriteNull(); | |||||
{ | |||||
if (isTopLevel) | |||||
writer.WriteAttributeNull(map.Key); | |||||
else | |||||
writer.WriteNull(); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -5,29 +5,39 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class DateTimePropertyConverter : IJsonPropertyConverter<DateTime> | internal class DateTimePropertyConverter : IJsonPropertyConverter<DateTime> | ||||
{ | { | ||||
public DateTime Read(JsonReader reader, bool read = true) | |||||
public DateTime Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseDateTime(); | 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<DateTimeOffset> | internal class DateTimeOffsetPropertyConverter : IJsonPropertyConverter<DateTimeOffset> | ||||
{ | { | ||||
public DateTimeOffset Read(JsonReader reader, bool read = true) | |||||
public DateTimeOffset Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseDateTimeOffset(); | 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); | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,9 +4,9 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class EnumPropertyConverter<T> : IJsonPropertyConverter<T> | internal class EnumPropertyConverter<T> : IJsonPropertyConverter<T> | ||||
{ | { | ||||
public T Read(JsonReader reader, bool read = true) | |||||
public T Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
=> throw new System.NotImplementedException(); | => 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(); | => throw new System.NotImplementedException(); | ||||
} | } | ||||
} | } |
@@ -4,43 +4,58 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class SinglePropertyConverter : IJsonPropertyConverter<float> | internal class SinglePropertyConverter : IJsonPropertyConverter<float> | ||||
{ | { | ||||
public float Read(JsonReader reader, bool read = true) | |||||
public float Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseSingle(); | 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<double> | internal class DoublePropertyConverter : IJsonPropertyConverter<double> | ||||
{ | { | ||||
public double Read(JsonReader reader, bool read = true) | |||||
public double Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseDouble(); | 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<decimal> | internal class DecimalPropertyConverter : IJsonPropertyConverter<decimal> | ||||
{ | { | ||||
public decimal Read(JsonReader reader, bool read = true) | |||||
public decimal Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseDecimal(); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -5,9 +5,9 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class BooleanPropertyConverter : IJsonPropertyConverter<bool> | internal class BooleanPropertyConverter : IJsonPropertyConverter<bool> | ||||
{ | { | ||||
public bool Read(JsonReader reader, bool read = true) | |||||
public bool Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
switch (reader.ValueType) | switch (reader.ValueType) | ||||
{ | { | ||||
@@ -16,21 +16,31 @@ namespace Discord.Serialization.Json.Converters | |||||
default: throw new SerializationException("Bad input, expected False or True"); | 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<Guid> | internal class GuidPropertyConverter : IJsonPropertyConverter<Guid> | ||||
{ | { | ||||
public Guid Read(JsonReader reader, bool read = true) | |||||
public Guid Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return Guid.Parse(reader.ParseString()); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,57 +4,77 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class Int8PropertyConverter : IJsonPropertyConverter<sbyte> | internal class Int8PropertyConverter : IJsonPropertyConverter<sbyte> | ||||
{ | { | ||||
public sbyte Read(JsonReader reader, bool read = true) | |||||
public sbyte Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseInt8(); | 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<short> | internal class Int16PropertyConverter : IJsonPropertyConverter<short> | ||||
{ | { | ||||
public short Read(JsonReader reader, bool read = true) | |||||
public short Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseInt16(); | 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<int> | internal class Int32PropertyConverter : IJsonPropertyConverter<int> | ||||
{ | { | ||||
public int Read(JsonReader reader, bool read = true) | |||||
public int Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseInt32(); | 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<long> | internal class Int64PropertyConverter : IJsonPropertyConverter<long> | ||||
{ | { | ||||
public long Read(JsonReader reader, bool read = true) | |||||
public long Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseInt64(); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,29 +4,39 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class CharPropertyConverter : IJsonPropertyConverter<char> | internal class CharPropertyConverter : IJsonPropertyConverter<char> | ||||
{ | { | ||||
public char Read(JsonReader reader, bool read = true) | |||||
public char Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseChar(); | 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<string> | internal class StringPropertyConverter : IJsonPropertyConverter<string> | ||||
{ | { | ||||
public string Read(JsonReader reader, bool read = true) | |||||
public string Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseString(); | 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); | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,57 +4,77 @@ namespace Discord.Serialization.Json.Converters | |||||
{ | { | ||||
internal class UInt8PropertyConverter : IJsonPropertyConverter<byte> | internal class UInt8PropertyConverter : IJsonPropertyConverter<byte> | ||||
{ | { | ||||
public byte Read(JsonReader reader, bool read = true) | |||||
public byte Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseUInt8(); | 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<ushort> | internal class UInt16PropertyConverter : IJsonPropertyConverter<ushort> | ||||
{ | { | ||||
public ushort Read(JsonReader reader, bool read = true) | |||||
public ushort Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseUInt16(); | 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<uint> | internal class UInt32PropertyConverter : IJsonPropertyConverter<uint> | ||||
{ | { | ||||
public uint Read(JsonReader reader, bool read = true) | |||||
public uint Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.Number) | if (reader.ValueType != JsonValueType.Number) | ||||
throw new SerializationException("Bad input, expected Number"); | throw new SerializationException("Bad input, expected Number"); | ||||
return reader.ParseUInt32(); | 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<ulong> | internal class UInt64PropertyConverter : IJsonPropertyConverter<ulong> | ||||
{ | { | ||||
public ulong Read(JsonReader reader, bool read = true) | |||||
public ulong Read(PropertyMap map, JsonReader reader, bool isTopLevel) | |||||
{ | { | ||||
if (read) | |||||
if (isTopLevel) | |||||
reader.Read(); | reader.Read(); | ||||
if (reader.ValueType != JsonValueType.String) | if (reader.ValueType != JsonValueType.String) | ||||
throw new SerializationException("Bad input, expected String"); | throw new SerializationException("Bad input, expected String"); | ||||
return reader.ParseUInt64(); | 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()); | |||||
} | |||||
} | } | ||||
} | } |
@@ -4,7 +4,7 @@ namespace Discord.Serialization.Json | |||||
{ | { | ||||
public interface IJsonPropertyConverter<T> | public interface IJsonPropertyConverter<T> | ||||
{ | { | ||||
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); | |||||
} | } | ||||
} | } |
@@ -92,11 +92,7 @@ namespace Discord.Serialization.Json | |||||
writer.WriteObjectStart(); | writer.WriteObjectStart(); | ||||
for (int i = 0; i < map.Properties.Length; i++) | for (int i = 0; i < map.Properties.Length; i++) | ||||
{ | |||||
var property = map.Properties[i]; | |||||
writer.WriteStartAttribute(property.Key); | |||||
(property as IJsonPropertyMap<TModel>).Write(model, writer); | |||||
} | |||||
(map.Properties[i] as IJsonPropertyMap<TModel>).Write(model, writer); | |||||
writer.WriteObjectEnd(); | writer.WriteObjectEnd(); | ||||
} | } | ||||
} | } | ||||
@@ -22,11 +22,13 @@ namespace Discord.Serialization.Json | |||||
public void Write(TModel model, JsonWriter writer) | public void Write(TModel model, JsonWriter writer) | ||||
{ | { | ||||
var value = _getFunc(model); | 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) | public void Read(TModel model, JsonReader reader) | ||||
{ | { | ||||
var value = _converter.Read(reader); | |||||
var value = _converter.Read(this, reader, true); | |||||
_setFunc(model, value); | _setFunc(model, value); | ||||
} | } | ||||
} | } | ||||
@@ -5,9 +5,9 @@ namespace Discord.Serialization | |||||
public class ModelPropertyAttribute : Attribute | public class ModelPropertyAttribute : Attribute | ||||
{ | { | ||||
public string Key { get; } | 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; | Key = key; | ||||
} | } | ||||
@@ -5,14 +5,14 @@ namespace Discord.Serialization | |||||
public abstract class PropertyMap | public abstract class PropertyMap | ||||
{ | { | ||||
public string Key { get; } | public string Key { get; } | ||||
public bool ExcludeNull { get; } | |||||
public PropertyMap(PropertyInfo propInfo) | public PropertyMap(PropertyInfo propInfo) | ||||
{ | { | ||||
var jsonProperty = propInfo.GetCustomAttribute<ModelPropertyAttribute>(); | var jsonProperty = propInfo.GetCustomAttribute<ModelPropertyAttribute>(); | ||||
if (jsonProperty != null) | |||||
Key = jsonProperty.Key; | |||||
else | |||||
Key = propInfo.Name; | |||||
Key = jsonProperty?.Key ?? propInfo.Name; | |||||
ExcludeNull = jsonProperty?.ExcludeNull ?? false; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -8,9 +8,9 @@ namespace Discord.API | |||||
{ | { | ||||
[ModelProperty("op")] | [ModelProperty("op")] | ||||
public int Operation { get; set; } | public int Operation { get; set; } | ||||
[ModelProperty("t", IgnoreNull = true)] | |||||
[ModelProperty("t", ExcludeNull = true)] | |||||
public string Type { get; set; } | public string Type { get; set; } | ||||
[ModelProperty("s", IgnoreNull = true)] | |||||
[ModelProperty("s", ExcludeNull = true)] | |||||
public int? Sequence { get; set; } | public int? Sequence { get; set; } | ||||
[ModelProperty("d")] | [ModelProperty("d")] | ||||
public ReadOnlyBuffer<byte> Payload { get; set; } | public ReadOnlyBuffer<byte> Payload { get; set; } | ||||