diff --git a/Discord.Net.sln b/Discord.Net.sln
index a63606787..edc7952fa 100644
--- a/Discord.Net.sln
+++ b/Discord.Net.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26228.4
+VisualStudioVersion = 15.0.26711.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Core", "src\Discord.Net.Core\Discord.Net.Core.csproj", "{91E9E7BD-75C9-4E98-84AA-2C271922E5C2}"
EndProject
@@ -14,8 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Commands", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.WebSocket", "src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj", "{688FD1D8-7F01-4539-B2E9-F473C5D699C7}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.WS4Net", "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj", "{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}"
@@ -24,6 +22,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests", "test\D
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Webhook", "src\Discord.Net.Webhook\Discord.Net.Webhook.csproj", "{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{1876A445-1C70-4F84-912B-4D3CEA21E0C3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Serialization", "src\Discord.Net.Serialization\Discord.Net.Serialization.csproj", "{AA3B67BE-767E-4230-9810-F7948B6AE689}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -130,6 +132,18 @@ Global
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x64.Build.0 = Release|Any CPU
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x86.ActiveCfg = Release|Any CPU
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30}.Release|x86.Build.0 = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|x64.Build.0 = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Debug|x86.Build.0 = Debug|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|x64.ActiveCfg = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|x64.Build.0 = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|x86.ActiveCfg = Release|Any CPU
+ {AA3B67BE-767E-4230-9810-F7948B6AE689}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -139,7 +153,11 @@ Global
{5688A353-121E-40A1-8BFA-B17B91FB48FB} = {288C363D-A636-4EAE-9AC1-4698B641B26E}
{078DD7E6-943D-4D09-AFC2-D2BA58B76C9C} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}
{688FD1D8-7F01-4539-B2E9-F473C5D699C7} = {288C363D-A636-4EAE-9AC1-4698B641B26E}
- {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7} = {B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012}
+ {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7} = {1876A445-1C70-4F84-912B-4D3CEA21E0C3}
{9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}
+ {AA3B67BE-767E-4230-9810-F7948B6AE689} = {1876A445-1C70-4F84-912B-4D3CEA21E0C3}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9828C525-49C7-48F4-A9E7-94E223052DA2}
EndGlobalSection
EndGlobal
diff --git a/src/Discord.Net.Core/Discord.Net.Core.csproj b/src/Discord.Net.Core/Discord.Net.Core.csproj
index adbed2ca0..af4a8a06a 100644
--- a/src/Discord.Net.Core/Discord.Net.Core.csproj
+++ b/src/Discord.Net.Core/Discord.Net.Core.csproj
@@ -8,6 +8,11 @@
true
+
+
+
+
+
@@ -15,6 +20,6 @@
-
+
\ No newline at end of file
diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.csproj b/src/Discord.Net.Rest/Discord.Net.Rest.csproj
index f5b26e181..420387dc1 100644
--- a/src/Discord.Net.Rest/Discord.Net.Rest.csproj
+++ b/src/Discord.Net.Rest/Discord.Net.Rest.csproj
@@ -9,11 +9,15 @@
+
+
+
+
@@ -21,7 +25,4 @@
-
-
-
\ No newline at end of file
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 52bfb6ddf..bfc2293ee 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -4,6 +4,8 @@ using Discord.Net;
using Discord.Net.Queue;
using Discord.Net.Rest;
using Discord.Serialization;
+using Discord.Serialization.Json;
+using Discord.Serialization.Json.Converters;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -11,6 +13,7 @@ using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Formatting;
@@ -21,13 +24,22 @@ namespace Discord.API
{
internal class DiscordRestApiClient : IDisposable
{
+ static DiscordRestApiClient()
+ {
+ SerializationFormat.Json.AddConverter();
+ SerializationFormat.Json.AddConverter(info => info.GetCustomAttribute() != null);
+ SerializationFormat.Json.AddConverter(info => info.GetCustomAttribute() != null);
+ SerializationFormat.Json.AddGenericConverter(typeof(EntityOrId<>), typeof(EntityOrIdPropertyConverter<>));
+ SerializationFormat.Json.AddGenericConverter(typeof(Optional<>), typeof(OptionalPropertyConverter<>));
+ }
+
private static readonly ConcurrentDictionary> _bucketIdGenerators = new ConcurrentDictionary>();
public event Func SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } }
private readonly AsyncEvent> _sentRequestEvent = new AsyncEvent>();
protected readonly SemaphoreSlim _stateLock;
- protected readonly ScopedSerializer _serializer;
+ protected readonly Serializer _serializer;
protected readonly ConcurrentQueue _formatters;
private readonly RestClientProvider _restClientProvider;
@@ -44,7 +56,7 @@ namespace Discord.API
internal IRestClient RestClient { get; private set; }
internal ulong? CurrentUserId { get; set;}
- public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, ScopedSerializer serializer, RetryMode defaultRetryMode = RetryMode.AlwaysRetry)
+ public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, Serializer serializer, RetryMode defaultRetryMode = RetryMode.AlwaysRetry)
{
_restClientProvider = restClientProvider;
UserAgent = userAgent;
@@ -1167,13 +1179,13 @@ namespace Discord.API
protected static double ToMilliseconds(Stopwatch stopwatch) => Math.Round((double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2);
protected ReadOnlyBuffer SerializeJson(ArrayFormatter data, object value)
{
- _serializer.WriteJson(data, value);
+ _serializer.Write(data, value);
return new ReadOnlyBuffer(data.Formatted.Array, 0, data.Formatted.Count);
}
protected T DeserializeJson(ReadOnlyBuffer data)
where T : class, new()
{
- return _serializer.ReadJson(data);
+ return _serializer.Read(data);
}
internal class BucketIds
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index e71339eff..b49303043 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -8,7 +8,7 @@ namespace Discord.Rest
{
public class DiscordRestClient : BaseDiscordClient, IDiscordClient
{
- private readonly ScopedSerializer _serializer;
+ private readonly Serializer _serializer;
private RestApplication _applicationInfo;
public new RestSelfUser CurrentUser => base.CurrentUser as RestSelfUser;
@@ -16,10 +16,10 @@ namespace Discord.Rest
public DiscordRestClient() : this(new DiscordRestConfig()) { }
public DiscordRestClient(DiscordRestConfig config) : base(config)
{
- _serializer = Serializer.CreateScope();
- _serializer.Error += async ex =>
+ _serializer = new Serializer(SerializationFormat.Json);
+ _serializer.Error += ex =>
{
- await _restLogger.WarningAsync("Serializer Error", ex);
+ _restLogger.WarningAsync("Serializer Error", ex).GetAwaiter().GetResult();
};
SetApiClient(new API.DiscordRestApiClient(config.RestClientProvider, DiscordConfig.UserAgent, _serializer, config.DefaultRetryMode));
diff --git a/src/Discord.Net.Rest/Extensions/JsonReaderExtensions.cs b/src/Discord.Net.Rest/Extensions/JsonReaderExtensions.cs
deleted file mode 100644
index 1aa7e34a1..000000000
--- a/src/Discord.Net.Rest/Extensions/JsonReaderExtensions.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.Text;
-using System.Text.Json;
-using System.Text.Utf8;
-
-namespace Discord.Serialization
-{
- internal static class JsonReaderExtensions
- {
- public static bool GetBool(this JsonReader reader) => GetBool(reader.Value);
- public static bool GetBool(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseBoolean(text, out bool result, out int ignored, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Boolean");
- }
-
- public static sbyte GetInt8(this JsonReader reader) => GetInt8(reader.Value);
- public static sbyte GetInt8(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseSByte(text, out sbyte result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Int8");
- }
- public static short GetInt16(this JsonReader reader) => GetInt16(reader.Value);
- public static short GetInt16(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseInt16(text, out short result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Int16");
- }
- public static int GetInt32(this JsonReader reader) => GetInt32(reader.Value);
- public static int GetInt32(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseInt32(text, out int result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Int32");
- }
- public static long GetInt64(this JsonReader reader) => GetInt64(reader.Value);
- public static long GetInt64(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseInt64(text, out long result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Int64");
- }
-
- public static byte GetUInt8(this JsonReader reader) => GetUInt8(reader.Value);
- public static byte GetUInt8(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseByte(text, out byte result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse UInt8");
- }
- public static ushort GetUInt16(this JsonReader reader) => GetUInt16(reader.Value);
- public static ushort GetUInt16(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseUInt16(text, out ushort result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse UInt16");
- }
- public static uint GetUInt32(this JsonReader reader) => GetUInt32(reader.Value);
- public static uint GetUInt32(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseUInt32(text, out uint result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse UInt32");
- }
- public static ulong GetUInt64(this JsonReader reader) => GetUInt64(reader.Value);
- public static ulong GetUInt64(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseUInt64(text, out ulong result, out int ignored, JsonConstants.NumberFormat, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse UInt64");
- }
-
- public static char GetChar(this JsonReader reader) => GetChar(reader.Value);
- public static char GetChar(this ReadOnlySpan text)
- {
- string str = GetString(text);
- if (str.Length == 1)
- return str[0];
- throw new SerializationException("Failed to parse Char");
- }
- public static string GetString(this JsonReader reader) => GetString(reader.Value);
- public static string GetString(this ReadOnlySpan text) => new Utf8String(text).ToString();
-
- public static float GetSingle(this JsonReader reader) => GetSingle(reader.Value);
- public static float GetSingle(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
- return (float)result;
- throw new SerializationException("Failed to parse Single");
- }
- public static double GetDouble(this JsonReader reader) => GetDouble(reader.Value);
- public static double GetDouble(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
- return (double)result;
- throw new SerializationException("Failed to parse Double");
- }
- public static decimal GetDecimal(this JsonReader reader) => GetDecimal(reader.Value);
- public static decimal GetDecimal(this ReadOnlySpan text)
- {
- if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
- return result;
- throw new SerializationException("Failed to parse Decimal");
- }
-
- public static DateTime GetDateTime(this JsonReader reader) => GetDateTime(reader.Value);
- public static DateTime GetDateTime(this ReadOnlySpan text)
- {
- string str = GetString(text);
- if (DateTime.TryParse(str, out var result)) //TODO: Improve perf
- return result;
- throw new SerializationException("Failed to parse DateTime");
- }
- public static DateTimeOffset GetDateTimeOffset(this JsonReader reader) => GetDateTimeOffset(reader.Value);
- public static DateTimeOffset GetDateTimeOffset(this ReadOnlySpan text)
- {
- string str = GetString(text);
- if (DateTimeOffset.TryParse(str, out var result)) //TODO: Improve perf
- return result;
- throw new SerializationException("Failed to parse DateTimeOffset");
- }
-
- public static void Skip(this JsonReader reader)
- {
- int initialDepth = reader._depth;
- while (reader.Read() && reader._depth > initialDepth) { }
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
index 9cd834e32..6fd212eed 100644
--- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
+++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs
@@ -104,7 +104,7 @@ namespace Discord.Net.Queue
{
try
{
- var error = Serializer.ReadJson(response.Data);
+ var error = Serializer.Json.Read(response.Data);
code = error.Code;
reason = error.Message;
}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/ArrayPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/ArrayPropertyConverter.cs
deleted file mode 100644
index 0e0ee5bfb..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/ArrayPropertyConverter.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Collections.Generic;
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class ArrayPropertyConverter : IPropertyConverter
- {
- private readonly IPropertyConverter _innerConverter;
-
- public ArrayPropertyConverter(IPropertyConverter innerConverter)
- {
- _innerConverter = innerConverter;
- }
-
- public T[] ReadJson(JsonReader reader, bool read = true)
- {
- if ((read && !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.ReadJson(reader));
- return list.ToArray();
- }
-
- public void WriteJson(JsonWriter writer, T[] value)
- {
- writer.WriteArrayStart();
- for (int i = 0; i < value.Length; i++)
- _innerConverter.WriteJson(writer, value[i]);
- writer.WriteArrayEnd();
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Converter.cs b/src/Discord.Net.Rest/Serialization/Converters/Converter.cs
deleted file mode 100644
index 9a15ad3a3..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Converter.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using Discord.API;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace Discord.Serialization.Converters
-{
- internal static class Converter
- {
- private static readonly MethodInfo _makeListConverterFunc
- = typeof(Converter).GetTypeInfo().GetDeclaredMethod(nameof(MakeListConverterInternal));
- private static readonly MethodInfo _makeOptionalConverterFunc
- = typeof(Converter).GetTypeInfo().GetDeclaredMethod(nameof(MakeOptionalConverterInternal));
- private static readonly MethodInfo _makeNullableConverterFunc
- = typeof(Converter).GetTypeInfo().GetDeclaredMethod(nameof(MakeNullableConverterInternal));
- private static readonly MethodInfo _makeEntityOrIdConverterFunc
- = typeof(Converter).GetTypeInfo().GetDeclaredMethod(nameof(MakeEntityOrIdConverterInternal));
-
- public static IPropertyConverter For()
- => (IPropertyConverter)ForInternal();
- private static object ForInternal()
- {
- var typeInfo = typeof(TProp).GetTypeInfo();
-
- //Generics
- if (typeof(TProp).IsConstructedGenericType)
- {
- Type genericType = typeof(TProp).GetGenericTypeDefinition();
- if (genericType == typeof(List<>))
- return MakeListConverter(typeof(TProp).GenericTypeArguments[0]);
- else if (genericType == typeof(Optional<>))
- return MakeOptionalConverter(typeof(TProp).GenericTypeArguments[0]);
- else if (genericType == typeof(Nullable<>))
- return MakeNullableConverter(typeof(TProp).GenericTypeArguments[0]);
- else if (genericType == typeof(EntityOrId<>))
- return MakeEntityOrIdConverter(typeof(TProp).GenericTypeArguments[0]);
- }
-
- //Enums
- if (typeInfo.IsEnum) return new EnumPropertyConverter();
-
- //Primitives
- if (typeof(TProp) == typeof(bool)) return new BooleanPropertyConverter();
-
- if (typeof(TProp) == typeof(sbyte)) return new Int8PropertyConverter();
- if (typeof(TProp) == typeof(short)) return new Int16PropertyConverter();
- if (typeof(TProp) == typeof(int)) return new Int32PropertyConverter();
- if (typeof(TProp) == typeof(long))
- {
- if (typeInfo.GetCustomAttribute() != null)
- return new Int53PropertyConverter();
- else
- return new Int64PropertyConverter();
- }
-
- if (typeof(TProp) == typeof(byte)) return new UInt8PropertyConverter();
- if (typeof(TProp) == typeof(ushort)) return new UInt16PropertyConverter();
- if (typeof(TProp) == typeof(uint)) return new UInt32PropertyConverter();
- if (typeof(TProp) == typeof(ulong))
- {
- if (typeInfo.GetCustomAttribute() != null)
- return new UInt53PropertyConverter();
- else
- return new UInt64PropertyConverter();
- }
-
- if (typeof(TProp) == typeof(float)) return new SinglePropertyConverter();
- if (typeof(TProp) == typeof(double)) return new DoublePropertyConverter();
- if (typeof(TProp) == typeof(decimal)) return new DecimalPropertyConverter();
-
- if (typeof(TProp) == typeof(char)) return new CharPropertyConverter();
- if (typeof(TProp) == typeof(string)) return new StringPropertyConverter();
-
- //Structs
- if (typeof(TProp) == typeof(DateTime)) return new DateTimePropertyConverter();
- if (typeof(TProp) == typeof(DateTimeOffset)) return new DateTimeOffsetPropertyConverter();
- if (typeof(TProp) == typeof(Image)) return new ImagePropertyConverter();
-
- throw new InvalidOperationException($"Unsupported model type: {typeof(TProp).Name}");
- }
-
- private static IPropertyConverter MakeListConverter(Type innerType)
- => _makeListConverterFunc.MakeGenericMethod(innerType).Invoke(null, null) as IPropertyConverter;
- private static IPropertyConverter> MakeListConverterInternal()
- => new ListPropertyConverter(For());
-
- private static IPropertyConverter MakeOptionalConverter(Type innerType)
- => _makeOptionalConverterFunc.MakeGenericMethod(innerType).Invoke(null, null) as IPropertyConverter;
- private static IPropertyConverter> MakeOptionalConverterInternal()
- => new OptionalPropertyConverter(For());
-
- private static IPropertyConverter MakeNullableConverter(Type innerType)
- => _makeNullableConverterFunc.MakeGenericMethod(innerType).Invoke(null, null) as IPropertyConverter;
- private static IPropertyConverter MakeNullableConverterInternal()
- where TInnerProp : struct
- => new NullablePropertyConverter(For());
-
- private static IPropertyConverter MakeEntityOrIdConverter(Type innerType)
- => _makeEntityOrIdConverterFunc.MakeGenericMethod(innerType).Invoke(null, null) as IPropertyConverter;
- private static IPropertyConverter> MakeEntityOrIdConverterInternal()
- => new EntityOrIdPropertyConverter(For());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/EntityOrIdPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/EntityOrIdPropertyConverter.cs
deleted file mode 100644
index 6af9f98eb..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/EntityOrIdPropertyConverter.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Discord.API;
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class EntityOrIdPropertyConverter : IPropertyConverter>
- {
- private readonly IPropertyConverter _innerConverter;
-
- public EntityOrIdPropertyConverter(IPropertyConverter innerConverter)
- {
- _innerConverter = innerConverter;
- }
-
- public EntityOrId ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType == JsonValueType.Number)
- return new EntityOrId(reader.GetUInt64());
- return new EntityOrId(_innerConverter.ReadJson(reader));
- }
-
- public void WriteJson(JsonWriter writer, EntityOrId value)
- {
- if (value.Object != null)
- _innerConverter.WriteJson(writer, value.Object);
- else
- writer.WriteValue(value.Id);
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/EnumPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/EnumPropertyConverter.cs
deleted file mode 100644
index 3b6f94dcb..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/EnumPropertyConverter.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class EnumPropertyConverter : IPropertyConverter
- {
- public T ReadJson(JsonReader reader, bool read = true)
- => throw new System.NotImplementedException();
- public void WriteJson(JsonWriter writer, T value)
- => throw new System.NotImplementedException();
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/IPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/IPropertyConverter.cs
deleted file mode 100644
index bd6d5d552..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/IPropertyConverter.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal interface IPropertyConverter
- {
- T ReadJson(JsonReader reader, bool read = true);
- void WriteJson(JsonWriter writer, T value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/ImagePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/ImagePropertyConverter.cs
deleted file mode 100644
index f94a68cd4..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/ImagePropertyConverter.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class ImagePropertyConverter : IPropertyConverter
- {
- public Image ReadJson(JsonReader reader, bool read = true)
- => throw new System.NotImplementedException();
- public void WriteJson(JsonWriter writer, Image value)
- => throw new System.NotImplementedException();
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/NullablePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/NullablePropertyConverter.cs
deleted file mode 100644
index 9be9b984e..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/NullablePropertyConverter.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class NullablePropertyConverter : IPropertyConverter
- where T : struct
- {
- private readonly IPropertyConverter _innerConverter;
-
- public NullablePropertyConverter(IPropertyConverter innerConverter)
- {
- _innerConverter = innerConverter;
- }
-
- public T? ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType == JsonValueType.Null)
- return null;
- return _innerConverter.ReadJson(reader);
- }
-
- public void WriteJson(JsonWriter writer, T? value)
- {
- if (value.HasValue)
- _innerConverter.WriteJson(writer, value.Value);
- else
- writer.WriteNull();
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/OptionalPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/OptionalPropertyConverter.cs
deleted file mode 100644
index 608fd5144..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/OptionalPropertyConverter.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class OptionalPropertyConverter : IPropertyConverter>
- {
- private readonly IPropertyConverter _innerConverter;
-
- public OptionalPropertyConverter(IPropertyConverter innerConverter)
- {
- _innerConverter = innerConverter;
- }
-
- public Optional ReadJson(JsonReader reader, bool read = true)
- => new Optional(_innerConverter.ReadJson(reader, read));
-
- public void WriteJson(JsonWriter writer, Optional value)
- {
- if (value.IsSpecified)
- _innerConverter.WriteJson(writer, value.Value);
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/CharPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/CharPropertyConverter.cs
deleted file mode 100644
index 23aaa88aa..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/CharPropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class CharPropertyConverter : IPropertyConverter
- {
- public char ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetChar();
- }
- public void WriteJson(JsonWriter writer, char value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimeOffsetPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimeOffsetPropertyConverter.cs
deleted file mode 100644
index e484a9196..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimeOffsetPropertyConverter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class DateTimeOffsetPropertyConverter : IPropertyConverter
- {
- public DateTimeOffset ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetDateTimeOffset();
- }
- public void WriteJson(JsonWriter writer, DateTimeOffset value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimePropertyConverter.cs
deleted file mode 100644
index 7ddb39084..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DateTimePropertyConverter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class DateTimePropertyConverter : IPropertyConverter
- {
- public DateTime ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetDateTime();
- }
- public void WriteJson(JsonWriter writer, DateTime value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DecimalPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/DecimalPropertyConverter.cs
deleted file mode 100644
index 786d12ebe..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DecimalPropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class DecimalPropertyConverter : IPropertyConverter
- {
- public decimal ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetDecimal();
- }
- public void WriteJson(JsonWriter writer, decimal value)
- => writer.WriteValue(value.ToString());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DoublePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/DoublePropertyConverter.cs
deleted file mode 100644
index 87590464d..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/DoublePropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class DoublePropertyConverter : IPropertyConverter
- {
- public double ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetDouble();
- }
- public void WriteJson(JsonWriter writer, double value)
- => writer.WriteValue(value.ToString());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int16PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int16PropertyConverter.cs
deleted file mode 100644
index a80137878..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int16PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class Int16PropertyConverter : IPropertyConverter
- {
- public short ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetInt16();
- }
- public void WriteJson(JsonWriter writer, short value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int32PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int32PropertyConverter.cs
deleted file mode 100644
index af189753d..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int32PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class Int32PropertyConverter : IPropertyConverter
- {
- public int ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetInt32();
- }
- public void WriteJson(JsonWriter writer, int value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int64PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int64PropertyConverter.cs
deleted file mode 100644
index ad6dec00a..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int64PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class Int64PropertyConverter : IPropertyConverter
- {
- public long ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetInt64();
- }
- public void WriteJson(JsonWriter writer, long value)
- => writer.WriteValue(value.ToString());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int8PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int8PropertyConverter.cs
deleted file mode 100644
index de725d531..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int8PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class Int8PropertyConverter : IPropertyConverter
- {
- public sbyte ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetInt8();
- }
- public void WriteJson(JsonWriter writer, sbyte value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/SinglePropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/SinglePropertyConverter.cs
deleted file mode 100644
index 222ae8683..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/SinglePropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class SinglePropertyConverter : IPropertyConverter
- {
- public float ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetSingle();
- }
- public void WriteJson(JsonWriter writer, float value)
- => writer.WriteValue(value.ToString());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/StringPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/StringPropertyConverter.cs
deleted file mode 100644
index 328adb885..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/StringPropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class StringPropertyConverter : IPropertyConverter
- {
- public string ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetString();
- }
- public void WriteJson(JsonWriter writer, string value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt16PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt16PropertyConverter.cs
deleted file mode 100644
index 2bb0bee85..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt16PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class UInt16PropertyConverter : IPropertyConverter
- {
- public ushort ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetUInt16();
- }
- public void WriteJson(JsonWriter writer, ushort value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt32PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt32PropertyConverter.cs
deleted file mode 100644
index a55f23804..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt32PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class UInt32PropertyConverter : IPropertyConverter
- {
- public uint ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetUInt32();
- }
- public void WriteJson(JsonWriter writer, uint value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt64PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt64PropertyConverter.cs
deleted file mode 100644
index 07eec7ea3..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt64PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class UInt64PropertyConverter : IPropertyConverter
- {
- public ulong ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.String)
- throw new SerializationException("Bad input, expected String");
- return reader.GetUInt64();
- }
- public void WriteJson(JsonWriter writer, ulong value)
- => writer.WriteValue(value.ToString());
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt8PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt8PropertyConverter.cs
deleted file mode 100644
index af62d8c05..000000000
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt8PropertyConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-
-namespace Discord.Serialization.Converters
-{
- internal class UInt8PropertyConverter : IPropertyConverter
- {
- public byte ReadJson(JsonReader reader, bool read = true)
- {
- if (read)
- reader.Read();
- if (reader.ValueType != JsonValueType.Number)
- throw new SerializationException("Bad input, expected Number");
- return reader.GetUInt8();
- }
- public void WriteJson(JsonWriter writer, byte value)
- => writer.WriteValue(value);
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs
new file mode 100644
index 000000000..4eeab4ca3
--- /dev/null
+++ b/src/Discord.Net.Rest/Serialization/JsonConverters/EntityOrIdPropertyConverter.cs
@@ -0,0 +1,32 @@
+using Discord.API;
+using System.Text.Json;
+
+namespace Discord.Serialization.Json.Converters
+{
+ internal class EntityOrIdPropertyConverter : IJsonPropertyConverter>
+ {
+ private readonly IJsonPropertyConverter _innerConverter;
+
+ public EntityOrIdPropertyConverter(IJsonPropertyConverter innerConverter)
+ {
+ _innerConverter = innerConverter;
+ }
+
+ public EntityOrId Read(JsonReader reader, bool read = true)
+ {
+ if (read)
+ reader.Read();
+ if (reader.ValueType == JsonValueType.Number)
+ return new EntityOrId(reader.ParseUInt64());
+ return new EntityOrId(_innerConverter.Read(reader));
+ }
+
+ public void Write(JsonWriter writer, EntityOrId value)
+ {
+ if (value.Object != null)
+ _innerConverter.Write(writer, value.Object);
+ 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
new file mode 100644
index 000000000..af3fcd76e
--- /dev/null
+++ b/src/Discord.Net.Rest/Serialization/JsonConverters/ImagePropertyConverter.cs
@@ -0,0 +1,12 @@
+using System.Text.Json;
+
+namespace Discord.Serialization.Json.Converters
+{
+ internal class ImagePropertyConverter : IJsonPropertyConverter
+ {
+ public API.Image Read(JsonReader reader, bool read = true)
+ => throw new System.NotImplementedException();
+ public void Write(JsonWriter writer, API.Image value)
+ => throw new System.NotImplementedException();
+ }
+}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int53PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs
similarity index 51%
rename from src/Discord.Net.Rest/Serialization/Converters/Primitives/Int53PropertyConverter.cs
rename to src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs
index d8bbd64fc..e8006a33e 100644
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/Int53PropertyConverter.cs
+++ b/src/Discord.Net.Rest/Serialization/JsonConverters/Int53PropertyConverter.cs
@@ -1,18 +1,18 @@
using System.Text.Json;
-namespace Discord.Serialization.Converters
+namespace Discord.Serialization.Json.Converters
{
- internal class Int53PropertyConverter : IPropertyConverter
+ internal class Int53PropertyConverter : IJsonPropertyConverter
{
- public long ReadJson(JsonReader reader, bool read = true)
+ public long Read(JsonReader reader, bool read = true)
{
if (read)
reader.Read();
if (reader.ValueType != JsonValueType.Number)
throw new SerializationException("Bad input, expected Number");
- return reader.GetInt64();
+ return reader.ParseInt64();
}
- public void WriteJson(JsonWriter writer, long value)
+ public void Write(JsonWriter writer, long value)
=> writer.WriteValue(value);
}
}
diff --git a/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs
new file mode 100644
index 000000000..82dc700ab
--- /dev/null
+++ b/src/Discord.Net.Rest/Serialization/JsonConverters/OptionalPropertyConverter.cs
@@ -0,0 +1,23 @@
+using System.Text.Json;
+
+namespace Discord.Serialization.Json.Converters
+{
+ internal class OptionalPropertyConverter : IJsonPropertyConverter>
+ {
+ private readonly IJsonPropertyConverter _innerConverter;
+
+ public OptionalPropertyConverter(IJsonPropertyConverter innerConverter)
+ {
+ _innerConverter = innerConverter;
+ }
+
+ public Optional Read(JsonReader reader, bool read = true)
+ => new Optional(_innerConverter.Read(reader, read));
+
+ public void Write(JsonWriter writer, Optional value)
+ {
+ if (value.IsSpecified)
+ _innerConverter.Write(writer, value.Value);
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt53PropertyConverter.cs b/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs
similarity index 50%
rename from src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt53PropertyConverter.cs
rename to src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs
index 49502ce5e..5dd482fe9 100644
--- a/src/Discord.Net.Rest/Serialization/Converters/Primitives/UInt53PropertyConverter.cs
+++ b/src/Discord.Net.Rest/Serialization/JsonConverters/UInt53PropertyConverter.cs
@@ -1,18 +1,18 @@
using System.Text.Json;
-namespace Discord.Serialization.Converters
+namespace Discord.Serialization.Json.Converters
{
- internal class UInt53PropertyConverter : IPropertyConverter
+ internal class UInt53PropertyConverter : IJsonPropertyConverter
{
- public ulong ReadJson(JsonReader reader, bool read = true)
+ public ulong Read(JsonReader reader, bool read = true)
{
if (read)
reader.Read();
if (reader.ValueType != JsonValueType.Number)
throw new SerializationException("Bad input, expected Number");
- return reader.GetUInt64();
+ return reader.ParseUInt64();
}
- public void WriteJson(JsonWriter writer, ulong value)
+ public void Write(JsonWriter writer, ulong value)
=> writer.WriteValue(value);
}
}
diff --git a/src/Discord.Net.Rest/Serialization/ModelMap.cs b/src/Discord.Net.Rest/Serialization/ModelMap.cs
deleted file mode 100644
index 737a470a7..000000000
--- a/src/Discord.Net.Rest/Serialization/ModelMap.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text.Json;
-
-namespace Discord.Serialization
-{
- internal static class ModelMap
- {
- private static readonly ConcurrentDictionary _cache = new ConcurrentDictionary();
-
- internal static ModelMap For()
- where T : class, new()
- {
- return _cache.GetOrAdd(typeof(T), _ =>
- {
- var type = typeof(T).GetTypeInfo();
- var properties = new Dictionary>();
-
- var propInfos = type.DeclaredProperties.ToArray();
- for (int i = 0; i < propInfos.Length; i++)
- {
- var propInfo = propInfos[i];
- if (!propInfo.CanRead || !propInfo.CanWrite)
- continue;
-
- var propMap = PropertyMap.Create(propInfo);
- properties.Add(propMap.Key, propMap);
- }
-
- return new ModelMap(properties);
- }) as ModelMap;
- }
- }
-
- internal class ModelMap
- where T : class, new()
- {
- private readonly PropertyMap[] _propertyList;
- private readonly Dictionary> _properties;
-
- public ModelMap(Dictionary> properties)
- {
- _properties = properties;
- _propertyList = _properties.Values.ToArray();
- }
-
- public T ReadJson(JsonReader reader)
- {
- var model = new T();
-
- if (!reader.Read() || reader.TokenType != JsonTokenType.StartObject)
- throw new InvalidOperationException("Bad input, expected StartObject");
- while (reader.Read())
- {
- if (reader.TokenType == JsonTokenType.EndObject)
- return model;
- if (reader.TokenType != JsonTokenType.PropertyName)
- throw new InvalidOperationException("Bad input, expected PropertyName");
-
- string key = reader.GetString();
- if (_properties.TryGetValue(key, out var property))
- property.ReadJson(model, reader);
- else
- reader.Skip(); //Unknown property, skip
-
- if (!reader.Read())
- throw new InvalidOperationException("Bad input, expected Value");
- }
- throw new InvalidOperationException("Bad input, expected EndObject");
- }
- public void WriteJson(T model, JsonWriter writer)
- {
- writer.WriteObjectStart();
- for (int i = 0; i < _propertyList.Length; i++)
- {
- var property = _propertyList[i];
- writer.WriteStartAttribute(property.Key);
- property.WriteJson(model, writer);
- }
- writer.WriteObjectEnd();
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/PropertyMap.cs b/src/Discord.Net.Rest/Serialization/PropertyMap.cs
deleted file mode 100644
index 0ac7057a2..000000000
--- a/src/Discord.Net.Rest/Serialization/PropertyMap.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Discord.Serialization.Converters;
-using System;
-using System.Reflection;
-using System.Text.Json;
-
-namespace Discord.Serialization
-{
- internal static class PropertyMap
- {
- public static PropertyMap Create(PropertyInfo propInfo)
- {
- var type = typeof(PropertyMap<,>).MakeGenericType(typeof(TModel), propInfo.PropertyType);
- return Activator.CreateInstance(type, propInfo) as PropertyMap;
- }
- }
-
- internal abstract class PropertyMap
- {
- public string Key { get; protected set; }
-
- public abstract void WriteJson(TModel model, JsonWriter writer);
- public abstract void ReadJson(TModel model, JsonReader reader);
- }
-
- internal class PropertyMap : PropertyMap
- {
- private readonly IPropertyConverter _converter;
- private readonly Func _getFunc;
- private readonly Action _setFunc;
-
- public PropertyMap(PropertyInfo propInfo)
- {
- var jsonProperty = propInfo.GetCustomAttribute();
- if (jsonProperty != null)
- Key = jsonProperty.Key;
- else
- Key = propInfo.Name;
-
- _getFunc = propInfo.GetMethod.CreateDelegate(typeof(Func)) as Func;
- _setFunc = propInfo.SetMethod.CreateDelegate(typeof(Action)) as Action;
-
- _converter = Converter.For();
- }
-
- private TProp GetValue(TModel model)
- => _getFunc(model);
- private void SetValue(TModel model, TProp prop)
- => _setFunc(model, prop);
-
- public override void WriteJson(TModel model, JsonWriter writer)
- {
- var value = GetValue(model);
- _converter.WriteJson(writer, value);
- }
- public override void ReadJson(TModel model, JsonReader reader)
- {
- var value = _converter.ReadJson(reader);
- SetValue(model, value);
- }
- }
-}
diff --git a/src/Discord.Net.Rest/Serialization/Serializer.cs b/src/Discord.Net.Rest/Serialization/Serializer.cs
deleted file mode 100644
index d205bb84d..000000000
--- a/src/Discord.Net.Rest/Serialization/Serializer.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Text;
-using System.Text.Formatting;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace Discord.Serialization
-{
- internal class Serializer
- {
- public static ScopedSerializer Global { get; } = new ScopedSerializer();
-
- public static T ReadJson(ReadOnlyBuffer data) where T : class, new() => Global.ReadJson(data);
- public static void WriteJson(ArrayFormatter data, T obj) where T : class, new() => Global.WriteJson(data, obj);
-
- public static ScopedSerializer CreateScope() => new ScopedSerializer();
- }
-
- internal class ScopedSerializer
- {
- private readonly AsyncEvent> _errorEvent = new AsyncEvent>();
- public event Func Error
- {
- add { _errorEvent.Add(value); }
- remove { _errorEvent.Remove(value); }
- }
-
- public T ReadJson(ReadOnlyBuffer data)
- where T : class, new()
- => ModelMap.For().ReadJson(new JsonReader(data.Span, SymbolTable.InvariantUtf8));
- public void WriteJson(ArrayFormatter data, T obj)
- where T : class, new()
- => ModelMap.For().WriteJson(obj, new JsonWriter(data));
- }
-}
diff --git a/src/Discord.Net.Rpc/DiscordRpcApiClient.cs b/src/Discord.Net.Rpc/DiscordRpcApiClient.cs
index f669fc642..34eb1efd3 100644
--- a/src/Discord.Net.Rpc/DiscordRpcApiClient.cs
+++ b/src/Discord.Net.Rpc/DiscordRpcApiClient.cs
@@ -41,11 +41,11 @@ namespace Discord.API
}
public Task SetResultAsync(ReadOnlyBuffer data)
{
- return Promise.TrySetResultAsync(Serializer.ReadJson(data));
+ return Promise.TrySetResultAsync(Serializer.Json.Read(data));
}
public Task SetExceptionAsync(ReadOnlyBuffer data)
{
- var error = Serializer.ReadJson(data);
+ var error = Serializer.Json.Read(data);
return Promise.TrySetExceptionAsync(new RpcException(error.Code, error.Message));
}
}
@@ -72,7 +72,7 @@ namespace Discord.API
public ConnectionState ConnectionState { get; private set; }
public DiscordRpcApiClient(string clientId, string userAgent, string origin, RestClientProvider restClientProvider, WebSocketProvider webSocketProvider,
- ScopedSerializer serializer, RetryMode defaultRetryMode = RetryMode.AlwaysRetry)
+ Serializer serializer, RetryMode defaultRetryMode = RetryMode.AlwaysRetry)
: base(restClientProvider, userAgent, serializer, defaultRetryMode)
{
_connectionLock = new SemaphoreSlim(1, 1);
@@ -99,7 +99,7 @@ namespace Discord.API
_decompressionStream.SetLength(_decompressionStream.Position);
_decompressionStream.Position = 0;
- var msg = _serializer.ReadJson(_decompressionStream.ToReadOnlyBuffer());
+ var msg = _serializer.Read(_decompressionStream.ToReadOnlyBuffer());
if (msg != null)
{
await _receivedRpcEvent.InvokeAsync(msg.Cmd, msg.Event, msg.Data).ConfigureAwait(false);
@@ -110,7 +110,7 @@ namespace Discord.API
}
else
{
- var msg = _serializer.ReadJson(data);
+ var msg = _serializer.Read(data);
if (msg != null)
{
await _receivedRpcEvent.InvokeAsync(msg.Cmd, msg.Event, msg.Data).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.cs b/src/Discord.Net.Rpc/DiscordRpcClient.cs
index ac34ab81f..2615972f9 100644
--- a/src/Discord.Net.Rpc/DiscordRpcClient.cs
+++ b/src/Discord.Net.Rpc/DiscordRpcClient.cs
@@ -16,7 +16,7 @@ namespace Discord.Rpc
private readonly ConnectionManager _connection;
private readonly Logger _rpcLogger;
private readonly SemaphoreSlim _stateLock, _authorizeLock;
- private readonly ScopedSerializer _serializer;
+ private readonly Serializer _serializer;
public ConnectionState ConnectionState { get; private set; }
public IReadOnlyCollection Scopes { get; private set; }
@@ -37,10 +37,10 @@ namespace Discord.Rpc
_authorizeLock = new SemaphoreSlim(1, 1);
_rpcLogger = LogManager.CreateLogger("RPC");
- _serializer = Serializer.CreateScope();
- _serializer.Error += async ex =>
+ _serializer = new Serializer(SerializationFormat.Json);
+ _serializer.Error += ex =>
{
- await _rpcLogger.WarningAsync("Serializer Error", ex);
+ _rpcLogger.WarningAsync("Serializer Error", ex).GetAwaiter().GetResult();
};
SetApiClient(new API.DiscordRpcApiClient(clientId, DiscordRestConfig.UserAgent, origin, config.RestClientProvider, config.WebSocketProvider, _serializer));
@@ -293,7 +293,7 @@ namespace Discord.Rpc
case "READY":
{
await _rpcLogger.DebugAsync("Received Dispatch (READY)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var options = new RequestOptions
{
@@ -335,7 +335,7 @@ namespace Discord.Rpc
case "CHANNEL_CREATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (CHANNEL_CREATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var channel = RpcChannelSummary.Create(data);
await _channelCreatedEvent.InvokeAsync(channel).ConfigureAwait(false);
@@ -346,7 +346,7 @@ namespace Discord.Rpc
case "GUILD_CREATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var guild = RpcGuildSummary.Create(data);
await _guildCreatedEvent.InvokeAsync(guild).ConfigureAwait(false);
@@ -355,7 +355,7 @@ namespace Discord.Rpc
case "GUILD_STATUS":
{
await _rpcLogger.DebugAsync("Received Dispatch (GUILD_STATUS)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var guildStatus = RpcGuildStatus.Create(data);
await _guildStatusUpdatedEvent.InvokeAsync(guildStatus).ConfigureAwait(false);
@@ -366,7 +366,7 @@ namespace Discord.Rpc
case "VOICE_STATE_CREATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_CREATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var voiceState = RpcVoiceState.Create(this, data);
await _voiceStateCreatedEvent.InvokeAsync(voiceState).ConfigureAwait(false);
@@ -375,7 +375,7 @@ namespace Discord.Rpc
case "VOICE_STATE_UPDATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_UPDATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var voiceState = RpcVoiceState.Create(this, data);
await _voiceStateUpdatedEvent.InvokeAsync(voiceState).ConfigureAwait(false);
@@ -384,7 +384,7 @@ namespace Discord.Rpc
case "VOICE_STATE_DELETE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_DELETE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var voiceState = RpcVoiceState.Create(this, data);
await _voiceStateDeletedEvent.InvokeAsync(voiceState).ConfigureAwait(false);
@@ -394,7 +394,7 @@ namespace Discord.Rpc
case "SPEAKING_START":
{
await _rpcLogger.DebugAsync("Received Dispatch (SPEAKING_START)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
await _speakingStartedEvent.InvokeAsync(data.UserId).ConfigureAwait(false);
}
@@ -402,7 +402,7 @@ namespace Discord.Rpc
case "SPEAKING_STOP":
{
await _rpcLogger.DebugAsync("Received Dispatch (SPEAKING_STOP)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
await _speakingStoppedEvent.InvokeAsync(data.UserId).ConfigureAwait(false);
}
@@ -410,7 +410,7 @@ namespace Discord.Rpc
case "VOICE_SETTINGS_UPDATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_SETTINGS_UPDATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var settings = VoiceSettings.Create(data);
await _voiceSettingsUpdated.InvokeAsync(settings).ConfigureAwait(false);
@@ -421,7 +421,7 @@ namespace Discord.Rpc
case "MESSAGE_CREATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var msg = RpcMessage.Create(this, data.ChannelId, data.Message);
await _messageReceivedEvent.InvokeAsync(msg).ConfigureAwait(false);
@@ -430,7 +430,7 @@ namespace Discord.Rpc
case "MESSAGE_UPDATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_UPDATE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
var msg = RpcMessage.Create(this, data.ChannelId, data.Message);
await _messageUpdatedEvent.InvokeAsync(msg).ConfigureAwait(false);
@@ -439,7 +439,7 @@ namespace Discord.Rpc
case "MESSAGE_DELETE":
{
await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_DELETE)").ConfigureAwait(false);
- var data = _serializer.ReadJson(payload.Value);
+ var data = _serializer.Read(payload.Value);
await _messageDeletedEvent.InvokeAsync(data.ChannelId, data.Message.Id).ConfigureAwait(false);
}
diff --git a/src/Discord.Net.Serialization/ConverterCollection.cs b/src/Discord.Net.Serialization/ConverterCollection.cs
new file mode 100644
index 000000000..71c416589
--- /dev/null
+++ b/src/Discord.Net.Serialization/ConverterCollection.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Discord.Serialization
+{
+ public class ConverterCollection
+ {
+ private class ConverterTypeCollection
+ {
+ public Type DefaultConverterType;
+ public List<(Func Condition, Type ConverterType)> Conditionals = new List<(Func, Type)>();
+ }
+
+ private static readonly MethodInfo _getConverterMethod
+ = typeof(ConverterCollection).GetTypeInfo().GetDeclaredMethod(nameof(Get));
+
+ private readonly ConcurrentDictionary _maps = new ConcurrentDictionary();
+ private readonly ConcurrentDictionary _types = new ConcurrentDictionary();
+ private readonly ConcurrentDictionary _genericTypes = new ConcurrentDictionary();
+
+ internal ConverterCollection() { }
+
+ public void Add()
+ {
+ var converters = _types.GetOrAdd(typeof(TType), _ => new ConverterTypeCollection());
+ converters.DefaultConverterType = typeof(TConverter);
+ }
+ public void Add(Func condition)
+ {
+ var converters = _types.GetOrAdd(typeof(TType), _ => new ConverterTypeCollection());
+ converters.Conditionals.Add((condition, typeof(TConverter)));
+ }
+
+ public void AddGeneric(Type openType, Type openConverterType)
+ {
+ if (openType.IsConstructedGenericType) throw new InvalidOperationException($"{nameof(openType)} must be an open generic");
+ if (openConverterType.IsConstructedGenericType) throw new InvalidOperationException($"{nameof(openConverterType)} must be an open generic");
+ var converters = _genericTypes.GetOrAdd(openType, _ => new ConverterTypeCollection());
+ converters.DefaultConverterType = openConverterType;
+ }
+ public void AddGeneric(Type openType, Type openConverterType, Func condition)
+ {
+ if (openType.IsConstructedGenericType) throw new InvalidOperationException($"{nameof(openType)} must be an open generic");
+ if (openConverterType.IsConstructedGenericType) throw new InvalidOperationException($"{nameof(openConverterType)} must be an open generic");
+ var converters = _genericTypes.GetOrAdd(openType, _ => new ConverterTypeCollection());
+ converters.Conditionals.Add((condition, openConverterType));
+ }
+
+ public object Get(PropertyInfo propInfo)
+ {
+ var typeInfo = typeof(TType).GetTypeInfo();
+
+ //Generic converters
+ if (typeInfo.IsGenericType)
+ {
+ var converterType = FindConverterType(typeInfo.GetGenericTypeDefinition(), _genericTypes, propInfo);
+ if (converterType != null)
+ {
+ var innerType = typeInfo.GenericTypeArguments[0];
+ converterType = converterType.MakeGenericType(innerType);
+ object innerConverter = GetInnerConverter(innerType, propInfo);
+ return Activator.CreateInstance(converterType, innerConverter);
+ }
+ }
+
+ //Normal converters
+ {
+ var converterType = FindConverterType(typeof(TType), _types, propInfo);
+ if (converterType != null)
+ return Activator.CreateInstance(converterType);
+ }
+
+ throw new InvalidOperationException($"Unsupported model type: {typeof(TType).Name}");
+ }
+ private object GetInnerConverter(Type type, PropertyInfo propInfo)
+ => _getConverterMethod.MakeGenericMethod(type).Invoke(this, new object[] { propInfo });
+
+ private Type FindConverterType(Type type, ConcurrentDictionary collection, PropertyInfo propInfo)
+ {
+ if (collection.TryGetValue(type, out var converters))
+ {
+ for (int i = 0; i < converters.Conditionals.Count; i++)
+ {
+ if (converters.Conditionals[i].Condition(propInfo))
+ return converters.Conditionals[i].ConverterType;
+ }
+ if (converters.DefaultConverterType != null)
+ return converters.DefaultConverterType;
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/Discord.Net.Serialization/Discord.Net.Serialization.csproj b/src/Discord.Net.Serialization/Discord.Net.Serialization.csproj
new file mode 100644
index 000000000..5d2cba89e
--- /dev/null
+++ b/src/Discord.Net.Serialization/Discord.Net.Serialization.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Discord.Net.Serialization
+ Discord.Serialization
+ The core components for the Discord.Net library.
+ net45;netstandard1.1;netstandard1.3
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs b/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs
new file mode 100644
index 000000000..c0b95ba2d
--- /dev/null
+++ b/src/Discord.Net.Serialization/Extensions/BufferExtensions.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Text;
+using System.Text.Utf8;
+
+namespace Discord.Serialization
+{
+ public static class BufferExtensions
+ {
+ private static readonly ParsedFormat _numberFormat = new ParsedFormat('D');
+
+ public static bool ParseBool(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseBoolean(text, out bool result, out int ignored, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Boolean");
+ }
+
+ public static sbyte ParseInt8(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseSByte(text, out sbyte result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Int8");
+ }
+ public static short ParseInt16(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseInt16(text, out short result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Int16");
+ }
+ public static int ParseInt32(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseInt32(text, out int result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Int32");
+ }
+ public static long ParseInt64(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseInt64(text, out long result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Int64");
+ }
+
+ public static byte ParseUInt8(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseByte(text, out byte result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse UInt8");
+ }
+ public static ushort ParseUInt16(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseUInt16(text, out ushort result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse UInt16");
+ }
+ public static uint ParseUInt32(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseUInt32(text, out uint result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse UInt32");
+ }
+ public static ulong ParseUInt64(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseUInt64(text, out ulong result, out int ignored, _numberFormat, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse UInt64");
+ }
+
+ public static char ParseChar(this ReadOnlySpan text)
+ {
+ string str = ParseString(text);
+ if (str.Length == 1)
+ return str[0];
+ throw new SerializationException("Failed to parse Char");
+ }
+ public static string ParseString(this ReadOnlySpan text) => new Utf8String(text).ToString();
+
+ public static float ParseSingle(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
+ return (float)result;
+ throw new SerializationException("Failed to parse Single");
+ }
+ public static double ParseDouble(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
+ return (double)result;
+ throw new SerializationException("Failed to parse Double");
+ }
+ public static decimal ParseDecimal(this ReadOnlySpan text)
+ {
+ if (PrimitiveParser.TryParseDecimal(text, out decimal result, out int ignored, SymbolTable.InvariantUtf8))
+ return result;
+ throw new SerializationException("Failed to parse Decimal");
+ }
+
+ public static DateTime ParseDateTime(this ReadOnlySpan text)
+ {
+ string str = ParseString(text);
+ if (DateTime.TryParse(str, out var result)) //TODO: Improve perf
+ return result;
+ throw new SerializationException("Failed to parse DateTime");
+ }
+ public static DateTimeOffset ParseDateTimeOffset(this ReadOnlySpan text)
+ {
+ string str = ParseString(text);
+ if (DateTimeOffset.TryParse(str, out var result)) //TODO: Improve perf
+ return result;
+ throw new SerializationException("Failed to parse DateTimeOffset");
+ }
+ }
+}
diff --git a/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs b/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs
new file mode 100644
index 000000000..7f8a45f61
--- /dev/null
+++ b/src/Discord.Net.Serialization/Extensions/JsonReaderExtensions.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Text.Json;
+
+namespace Discord.Serialization
+{
+ public static class JsonReaderExtensions
+ {
+ public static bool ParseBool(this JsonReader reader) => reader.Value.ParseBool();
+
+ public static sbyte ParseInt8(this JsonReader reader) => reader.Value.ParseInt8();
+ public static short ParseInt16(this JsonReader reader) => reader.Value.ParseInt16();
+ public static int ParseInt32(this JsonReader reader) => reader.Value.ParseInt32();
+ public static long ParseInt64(this JsonReader reader) => reader.Value.ParseInt64();
+
+ public static byte ParseUInt8(this JsonReader reader) => reader.Value.ParseUInt8();
+ public static ushort ParseUInt16(this JsonReader reader) => reader.Value.ParseUInt16();
+ public static uint ParseUInt32(this JsonReader reader) => reader.Value.ParseUInt32();
+ public static ulong ParseUInt64(this JsonReader reader) => reader.Value.ParseUInt64();
+
+ public static char ParseChar(this JsonReader reader) => reader.Value.ParseChar();
+ public static string ParseString(this JsonReader reader) => reader.Value.ParseString();
+
+ public static float ParseSingle(this JsonReader reader) => reader.Value.ParseSingle();
+ public static double ParseDouble(this JsonReader reader) => reader.Value.ParseDouble();
+ public static decimal ParseDecimal(this JsonReader reader) => reader.Value.ParseDecimal();
+
+ public static DateTime ParseDateTime(this JsonReader reader) => reader.Value.ParseDateTime();
+ public static DateTimeOffset ParseDateTimeOffset(this JsonReader reader) => reader.Value.ParseDateTimeOffset();
+
+ public static void Skip(this JsonReader reader)
+ {
+ int initialDepth = reader._depth;
+ while (reader.Read() && reader._depth > initialDepth) { }
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/Serialization/Converters/ListPropertyConverter.cs b/src/Discord.Net.Serialization/Json/Converters/Collections.cs
similarity index 55%
rename from src/Discord.Net.Rest/Serialization/Converters/ListPropertyConverter.cs
rename to src/Discord.Net.Serialization/Json/Converters/Collections.cs
index b1627bc5c..0b6fcaae1 100644
--- a/src/Discord.Net.Rest/Serialization/Converters/ListPropertyConverter.cs
+++ b/src/Discord.Net.Serialization/Json/Converters/Collections.cs
@@ -1,33 +1,33 @@
using System.Collections.Generic;
using System.Text.Json;
-namespace Discord.Serialization.Converters
+namespace Discord.Serialization.Json.Converters
{
- internal class ListPropertyConverter : IPropertyConverter>
+ internal class ListPropertyConverter : IJsonPropertyConverter>
{
- private readonly IPropertyConverter _innerConverter;
+ private readonly IJsonPropertyConverter _innerConverter;
- public ListPropertyConverter(IPropertyConverter innerConverter)
+ public ListPropertyConverter(IJsonPropertyConverter innerConverter)
{
_innerConverter = innerConverter;
}
- public List ReadJson(JsonReader reader, bool read = true)
+ public List