Explicitly select json converters, added Image and Int53 attributes, fixed a couple of routes.

This commit is contained in:
RogueException
2016-05-15 02:07:52 -03:00
parent d1d6bf2c52
commit 1ee5e6d771
22 changed files with 132 additions and 70 deletions

View File

@@ -8,9 +8,9 @@ namespace Discord.API
public ulong TargetId { get; set; }
[JsonProperty("type")]
public PermissionTarget TargetType { get; set; }
[JsonProperty("deny")]
[JsonProperty("deny"), Int53]
public ulong Deny { get; set; }
[JsonProperty("allow")]
[JsonProperty("allow"), Int53]
public ulong Allow { get; set; }
}
}

View File

@@ -14,7 +14,7 @@ namespace Discord.API
public bool? Hoist { get; set; }
[JsonProperty("position")]
public int? Position { get; set; }
[JsonProperty("permissions")]
[JsonProperty("permissions"), Int53]
public ulong? Permissions { get; set; }
[JsonProperty("managed")]
public bool? Managed { get; set; }

View File

@@ -12,7 +12,7 @@ namespace Discord.API
public string Icon { get; set; }
[JsonProperty("owner")]
public bool Owner { get; set; }
[JsonProperty("permissions")]
public uint Permissions { get; set; }
[JsonProperty("permissions"), Int53]
public ulong Permissions { get; set; }
}
}

View File

@@ -29,7 +29,7 @@ namespace Discord.API
public TokenType AuthTokenType { get; private set; }
public IRestClient RestClient { get; private set; }
public IRequestQueue RequestQueue { get; private set; }
internal DiscordRawClient(RestClientProvider restClientProvider)
{
_restClient = restClientProvider(DiscordConfig.ClientAPIUrl);
@@ -38,18 +38,10 @@ namespace Discord.API
_requestQueue = new RequestQueue(_restClient);
_serializer = new JsonSerializer();
_serializer.Converters.Add(new OptionalConverter());
_serializer.Converters.Add(new ChannelTypeConverter());
_serializer.Converters.Add(new ImageConverter());
_serializer.Converters.Add(new NullableUInt64Converter());
_serializer.Converters.Add(new PermissionTargetConverter());
_serializer.Converters.Add(new StringEntityConverter());
_serializer.Converters.Add(new UInt64ArrayConverter());
_serializer.Converters.Add(new UInt64Converter());
_serializer.Converters.Add(new UInt64EntityConverter());
_serializer.Converters.Add(new UserStatusConverter());
_serializer.ContractResolver = new OptionalContractResolver();
_serializer = new JsonSerializer()
{
ContractResolver = new DiscordContractResolver()
};
}
public async Task Login(TokenType tokenType, string token, CancellationToken cancelToken)
@@ -202,7 +194,7 @@ namespace Discord.API
{
if (guildId == 0) throw new ArgumentOutOfRangeException(nameof(guildId));
return await Send<IEnumerable<Channel>>("GET", $"guild/{guildId}/channels").ConfigureAwait(false);
return await Send<IEnumerable<Channel>>("GET", $"guilds/{guildId}/channels").ConfigureAwait(false);
}
public async Task<Channel> CreateGuildChannel(ulong guildId, CreateGuildChannelParams args)
{
@@ -539,7 +531,7 @@ namespace Discord.API
{
if (guildId == 0) throw new ArgumentOutOfRangeException(nameof(guildId));
return await Send<IEnumerable<Role>>("GET", $"guild/{guildId}/roles").ConfigureAwait(false);
return await Send<IEnumerable<Role>>("GET", $"guilds/{guildId}/roles").ConfigureAwait(false);
}
public async Task<Role> CreateGuildRole(ulong guildId)
{

View File

@@ -0,0 +1,7 @@
using System;
namespace Discord.API
{
[AttributeUsage(AttributeTargets.Property)]
public class ImageAttribute : Attribute { }
}

View File

@@ -0,0 +1,7 @@
using System;
namespace Discord.API
{
[AttributeUsage(AttributeTargets.Property)]
public class Int53Attribute : Attribute { }
}

View File

@@ -11,7 +11,7 @@ namespace Discord.API.Rest
[JsonProperty("region")]
public string Region { get; set; }
[JsonProperty("icon"), JsonConverter(typeof(ImageConverter))]
[JsonProperty("icon"), Image]
public Optional<Stream> Icon { get; set; }
}
}

View File

@@ -14,7 +14,7 @@ namespace Discord.API.Rest
public Optional<string> Password { get; set; }
[JsonProperty("new_password")]
public Optional<string> NewPassword { get; set; }
[JsonProperty("avatar"), JsonConverter(typeof(ImageConverter))]
[JsonProperty("avatar"), Image]
public Optional<Stream> Avatar { get; set; }
}
}

View File

@@ -16,11 +16,11 @@ namespace Discord.API.Rest
public Optional<ulong?> AFKChannelId { get; set; }
[JsonProperty("afk_timeout")]
public Optional<int> AFKTimeout { get; set; }
[JsonProperty("icon"), JsonConverter(typeof(ImageConverter))]
[JsonProperty("icon"), Image]
public Optional<Stream> Icon { get; set; }
[JsonProperty("owner_id")]
public Optional<GuildMember> Owner { get; set; }
[JsonProperty("splash"), JsonConverter(typeof(ImageConverter))]
[JsonProperty("splash"), Image]
public Optional<Stream> Splash { get; set; }
}
}

View File

@@ -67,6 +67,7 @@
<Compile Include="API\Common\UserGuild.cs" />
<Compile Include="API\Common\VoiceRegion.cs" />
<Compile Include="API\Common\VoiceState.cs" />
<Compile Include="API\ImageAttribute.cs" />
<Compile Include="API\IOptional.cs" />
<Compile Include="API\IWebSocketMessage.cs" />
<Compile Include="API\Optional.cs" />
@@ -105,7 +106,8 @@
<Compile Include="Common\Entities\Users\StreamType.cs" />
<Compile Include="DiscordConfig.cs" />
<Compile Include="API\DiscordRawClient.cs" />
<Compile Include="Net\Converters\OptionalContractResolver.cs" />
<Compile Include="API\Int53Attribute.cs" />
<Compile Include="Net\Converters\DiscordContractResolver.cs" />
<Compile Include="Net\Converters\OptionalConverter.cs" />
<Compile Include="Net\RateLimitException.cs" />
<Compile Include="Net\Rest\RequestQueue\BucketGroup.cs" />

View File

@@ -5,7 +5,9 @@ namespace Discord.Net.Converters
{
public class ChannelTypeConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(ChannelType);
public static readonly ChannelTypeConverter Instance = new ChannelTypeConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -0,0 +1,65 @@
using Discord.API;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace Discord.Net.Converters
{
public class DiscordContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var type = property.PropertyType;
JsonConverter converter = null;
if (member.MemberType == MemberTypes.Property)
{
//Primitives
if (type == typeof(ulong) && member.GetCustomAttribute<Int53Attribute>() == null)
converter = UInt64Converter.Instance;
else if (type == typeof(ulong?) && member.GetCustomAttribute<Int53Attribute>() == null)
converter = NullableUInt64Converter.Instance;
else if (typeof(IEnumerable<ulong[]>).IsAssignableFrom(type) && member.GetCustomAttribute<Int53Attribute>() == null)
converter = NullableUInt64Converter.Instance;
//Enums
else if (type == typeof(ChannelType))
converter = ChannelTypeConverter.Instance;
else if (type == typeof(PermissionTarget))
converter = PermissionTargetConverter.Instance;
else if (type == typeof(UserStatus))
converter = UserStatusConverter.Instance;
//Entities
else if (typeof(IEntity<ulong>).IsAssignableFrom(type))
converter = UInt64EntityConverter.Instance;
else if (typeof(IEntity<string>).IsAssignableFrom(type))
converter = StringEntityConverter.Instance;
//Special
else if (type == typeof(string) && member.GetCustomAttribute<ImageAttribute>() != null)
converter = ImageConverter.Instance;
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Optional<>))
{
var parentArg = Expression.Parameter(typeof(object));
var optional = Expression.Property(Expression.Convert(parentArg, property.DeclaringType), member as PropertyInfo);
var isSpecified = Expression.Property(optional, OptionalConverter.IsSpecifiedProperty);
var lambda = Expression.Lambda<Func<object, bool>>(isSpecified, parentArg).Compile();
property.ShouldSerialize = x => lambda(x);
converter = OptionalConverter.Instance;
}
}
if (converter != null)
{
property.Converter = converter;
property.MemberConverter = converter;
}
return property;
}
}
}

View File

@@ -7,7 +7,9 @@ namespace Discord.Net.Converters
{
public class ImageConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Stream) || objectType == typeof(Optional<Stream>);
public static readonly ImageConverter Instance = new ImageConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -6,7 +6,9 @@ namespace Discord.Net.Converters
{
public class NullableUInt64Converter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(ulong?);
public static readonly NullableUInt64Converter Instance = new NullableUInt64Converter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -1,34 +0,0 @@
using Discord.API;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Discord.Net.Converters
{
public class OptionalContractResolver : DefaultContractResolver
{
private static readonly PropertyInfo _isSpecified = typeof(IOptional).GetProperty(nameof(IOptional.IsSpecified));
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var type = property.PropertyType;
if (member.MemberType == MemberTypes.Property)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Optional<>))
{
var parentArg = Expression.Parameter(typeof(object));
var optional = Expression.Property(Expression.Convert(parentArg, property.DeclaringType), member as PropertyInfo);
var isSpecified = Expression.Property(optional, _isSpecified);
var lambda = Expression.Lambda<Func<object, bool>>(isSpecified, parentArg).Compile();
property.ShouldSerialize = x => lambda(x);
}
}
return property;
}
}
}

View File

@@ -1,12 +1,16 @@
using Discord.API;
using Newtonsoft.Json;
using System;
using System.Reflection;
namespace Discord.Net.Converters
{
public class OptionalConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Optional<>);
public static readonly OptionalConverter Instance = new OptionalConverter();
internal static readonly PropertyInfo IsSpecifiedProperty = typeof(IOptional).GetProperty(nameof(IOptional.IsSpecified));
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => false;
public override bool CanWrite => true;

View File

@@ -5,7 +5,9 @@ namespace Discord.Net.Converters
{
public class PermissionTargetConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(PermissionTarget);
public static readonly PermissionTargetConverter Instance = new PermissionTargetConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -5,7 +5,9 @@ namespace Discord.Net.Converters
{
public class StringEntityConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(IEntity<string>);
public static readonly StringEntityConverter Instance = new StringEntityConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => false;
public override bool CanWrite => true;

View File

@@ -7,7 +7,9 @@ namespace Discord.Net.Converters
{
public class UInt64ArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong[]>);
public static readonly UInt64ArrayConverter Instance = new UInt64ArrayConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -6,7 +6,9 @@ namespace Discord.Net.Converters
{
public class UInt64Converter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(ulong);
public static readonly UInt64Converter Instance = new UInt64Converter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;

View File

@@ -1,11 +1,14 @@
using Newtonsoft.Json;
using System;
using System.Globalization;
namespace Discord.Net.Converters
{
public class UInt64EntityConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(IEntity<ulong>);
public static readonly UInt64EntityConverter Instance = new UInt64EntityConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => false;
public override bool CanWrite => true;
@@ -17,7 +20,7 @@ namespace Discord.Net.Converters
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue((value as IEntity<ulong>).Id);
writer.WriteValue((value as IEntity<ulong>).Id.ToString(CultureInfo.InvariantCulture));
else
writer.WriteNull();
}

View File

@@ -5,7 +5,9 @@ namespace Discord.Net.Converters
{
public class UserStatusConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(UserStatus);
public static readonly UserStatusConverter Instance = new UserStatusConverter();
public override bool CanConvert(Type objectType) => true;
public override bool CanRead => true;
public override bool CanWrite => true;