Skip to content

Commit

Permalink
Fix BindOptions for STJ. API adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
Quahu committed Aug 14, 2024
1 parent 12c283f commit 2f9d927
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Disqord.Serialization.Json;
using Qmmands;
using Qommon;

Expand Down Expand Up @@ -84,15 +85,17 @@ static IReadOnlyDictionary<string, ISlashCommandInteractionOption> GetArguments(
continue;
}

if (option.Value is not string stringValue)
if (option.Value.Type != JsonValueType.String)
{
var value = GetOptionValue(option);
arguments[parameter] = actualType.IsEnum
? Enum.ToObject(actualType, option.Value)
: Convert.ChangeType(option.Value, actualType, context.Locale);
? Enum.ToObject(actualType, value)
: Convert.ChangeType(value, actualType, context.Locale);

continue;
}

var stringValue = option.Value.ToType<string>()!;
if (interaction is IAutoCompleteInteraction)
{
// Treat string values as arguments for auto-complete.
Expand All @@ -105,7 +108,7 @@ static IReadOnlyDictionary<string, ISlashCommandInteractionOption> GetArguments(
{
// If the option is just a string, pass it through to type parsing.
var rawArguments = context.RawArguments ??= new Dictionary<IParameter, MultiString>();
rawArguments[parameter] = option.Value as string;
rawArguments[parameter] = stringValue;
continue;
}

Expand Down Expand Up @@ -134,5 +137,30 @@ static IReadOnlyDictionary<string, ISlashCommandInteractionOption> GetArguments(

return Next.ExecuteAsync(context);
}

private static object GetOptionValue(ISlashCommandInteractionOption option)
{
var value = option.Value!;
switch (option.Type)
{
case SlashCommandOptionType.Integer:
{
return value.ToType<long>();
}
case SlashCommandOptionType.Boolean:
{
return value.ToType<bool>();
}
case SlashCommandOptionType.Number:
{
return value.ToType<double>();
}
default:
{
Throw.ArgumentOutOfRangeException(nameof(option));
return default;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Disqord.Serialization.Json;

namespace Disqord;

Expand All @@ -23,7 +24,7 @@ public interface ISlashCommandInteractionOption
/// <remarks>
/// <see cref="Value"/> and <see cref="Options"/> are mutually exclusive.
/// </remarks>
object? Value { get; }
IJsonValue? Value { get; }

/// <summary>
/// Gets the nested options of this option.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Disqord.Models;
using Disqord.Serialization.Json;
using Qommon;
using Qommon.Collections.ReadOnly;

Expand All @@ -15,7 +16,7 @@ public class TransientSlashCommandInteractionOption : TransientClientEntity<Appl
public SlashCommandOptionType Type => Model.Type;

/// <inheritdoc/>
public object? Value => Model.Value.GetValueOrDefault()?.ToType<object>();
public IJsonValue? Value => Model.Value.GetValueOrDefault();

/// <inheritdoc/>
public IReadOnlyDictionary<string, ISlashCommandInteractionOption> Options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,21 @@ public class DefaultJsonValue : DefaultJsonNode, IJsonValue
/// <inheritdoc cref="DefaultJsonNode.Token"/>
public new JValue Token => (base.Token as JValue)!;

public JsonValueType Type => Token.Type switch
{
JTokenType.Object => JsonValueType.Object,
JTokenType.Array => JsonValueType.Array,
JTokenType.Integer or JTokenType.Float => JsonValueType.Number,
JTokenType.String or JTokenType.Date or JTokenType.Raw or JTokenType.Bytes or JTokenType.Guid or JTokenType.Uri or JTokenType.TimeSpan => JsonValueType.String,
JTokenType.Boolean when Token.Value<bool>() => JsonValueType.True,
JTokenType.Boolean when !Token.Value<bool>() => JsonValueType.False,
_ => JsonValueType.Null
};

public DefaultJsonValue(JValue token, JsonSerializer serializer)
: base(token, serializer)
{ }

/// <inheritdoc/>
public T? GetValue<T>()
{
return Token.Value<T>();
}

/// <inheritdoc/>
public override string ToString()
{
Expand Down
7 changes: 6 additions & 1 deletion src/Disqord.Core/Serialization/Json/Nodes/IJsonValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@
/// Represents a JSON value node, i.e. a single JSON value.
/// </summary>
public interface IJsonValue : IJsonNode
{ }
{
/// <summary>
/// Gets the type of this JSON value.
/// </summary>
JsonValueType Type { get; }
}
12 changes: 12 additions & 0 deletions src/Disqord.Core/Serialization/Json/Nodes/JsonValueType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Disqord.Serialization.Json;

public enum JsonValueType
{
Null,
True,
False,
Number,
String,
Array,
Object
}
13 changes: 4 additions & 9 deletions src/Disqord.Core/Serialization/Json/STJ/Nodes/SystemJsonNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,13 @@ private protected SystemJsonNode(JsonNode node, JsonSerializerOptions options)
{
try
{
if (Node is JsonValue jsonValue)
var value = Node.Deserialize<T>(Options);
if (typeof(T) != typeof(JsonElement) && value is JsonElement)
{
if (jsonValue.TryGetValue(out T? value))
{
return value;
}

// TODO: not sure if this helps
return jsonValue.Deserialize<JsonElement>().Deserialize<T>();
Throw.ArgumentException($"Cannot convert the value to type {typeof(T)}.");
}

return Node.Deserialize<T>(Options);
return value;
}
catch (JsonException ex)
{
Expand Down
17 changes: 14 additions & 3 deletions src/Disqord.Core/Serialization/Json/STJ/Nodes/SystemJsonValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,32 @@ namespace Disqord.Serialization.Json.System;
/// Represents a default JSON value node.
/// Wraps a <see cref="JsonValue"/>.
/// </summary>
[DebuggerDisplay($"{nameof(Value)}")]
[DebuggerDisplay($"{nameof(DebuggerDisplay)}")]
internal sealed class SystemJsonValue : SystemJsonNode, IJsonValue
{
/// <inheritdoc cref="SystemJsonNode.Node"/>
public new JsonValue Node => (base.Node as JsonValue)!;

private object? Value => ToType<object>();
public JsonValueType Type => Node.GetValueKind() switch
{
JsonValueKind.Object => JsonValueType.Object,
JsonValueKind.Array => JsonValueType.Array,
JsonValueKind.String => JsonValueType.String,
JsonValueKind.Number => JsonValueType.Number,
JsonValueKind.True => JsonValueType.True,
JsonValueKind.False => JsonValueType.False,
_ => JsonValueType.Null
};

internal SystemJsonValue(JsonValue value, JsonSerializerOptions options)
: base(value, options)
{ }

private string DebuggerDisplay => Node.ToJsonString(Options);

/// <inheritdoc/>
public override string? ToString()
{
return Value?.ToString();
return Node.ToJsonString(Options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public SystemJsonSerializer()
IgnoreReadOnlyProperties = true,
RespectNullableAnnotations = true,
NewLine = "\n",
UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode,
TypeInfoResolver = new JsonTypeInfoResolver(),
Converters =
{
Expand All @@ -35,7 +36,7 @@ public SystemJsonSerializer()
new OptionalConverter(),
new StringConverter(),
new SnowflakeConverter(),
new StreamConverter()
new StreamConverter(),
}
};

Expand Down

0 comments on commit 2f9d927

Please sign in to comment.