Fixed modals with value type properties (#3091)
* Fixed type reader/converter parsing exception * Fixed modals with value types properties * Made OverridesToString result lazy and store it
This commit is contained in:
@@ -68,8 +68,13 @@ namespace Discord.Interactions
|
|||||||
{
|
{
|
||||||
case TextInputComponentInfo textComponent:
|
case TextInputComponentInfo textComponent:
|
||||||
{
|
{
|
||||||
|
var boxedValue = textComponent.Getter(modal);
|
||||||
|
var value = textComponent.TypeOverridesToString
|
||||||
|
? boxedValue.ToString()
|
||||||
|
: boxedValue as string;
|
||||||
|
|
||||||
builder.AddTextInput(textComponent.Label, textComponent.CustomId, textComponent.Style, textComponent.Placeholder, textComponent.IsRequired ? textComponent.MinLength : null,
|
builder.AddTextInput(textComponent.Label, textComponent.CustomId, textComponent.Style, textComponent.Placeholder, textComponent.IsRequired ? textComponent.MinLength : null,
|
||||||
textComponent.MaxLength, textComponent.IsRequired, textComponent.Getter(modal) as string);
|
textComponent.MaxLength, textComponent.IsRequired, value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Discord.Interactions
|
namespace Discord.Interactions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -5,6 +7,12 @@ namespace Discord.Interactions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TextInputComponentInfo : InputComponentInfo
|
public class TextInputComponentInfo : InputComponentInfo
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <c>true</c> when <see cref="InputComponentInfo.Type"/> overrides <see cref="object.ToString"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal bool TypeOverridesToString => _typeOverridesToString.Value;
|
||||||
|
private readonly Lazy<bool> _typeOverridesToString;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the style of the text input.
|
/// Gets the style of the text input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -37,6 +45,8 @@ namespace Discord.Interactions
|
|||||||
MinLength = builder.MinLength;
|
MinLength = builder.MinLength;
|
||||||
MaxLength = builder.MaxLength;
|
MaxLength = builder.MaxLength;
|
||||||
InitialValue = builder.InitialValue;
|
InitialValue = builder.InitialValue;
|
||||||
|
|
||||||
|
_typeOverridesToString = new(() => ReflectionUtils<object>.OverridesToString(Type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,8 @@ namespace Discord.Interactions
|
|||||||
{
|
{
|
||||||
var instanceParam = Expression.Parameter(typeof(T), "instance");
|
var instanceParam = Expression.Parameter(typeof(T), "instance");
|
||||||
var prop = Expression.Property(instanceParam, propertyInfo);
|
var prop = Expression.Property(instanceParam, propertyInfo);
|
||||||
return Expression.Lambda<Func<T, object>>(prop, instanceParam).Compile();
|
var cast = Expression.Convert(prop, typeof(object));
|
||||||
|
return Expression.Lambda<Func<T, object>>(cast, instanceParam).Compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Func<T, object> CreateLambdaPropertyGetter(Type type, PropertyInfo propertyInfo)
|
internal static Func<T, object> CreateLambdaPropertyGetter(Type type, PropertyInfo propertyInfo)
|
||||||
@@ -185,7 +186,8 @@ namespace Discord.Interactions
|
|||||||
var instanceParam = Expression.Parameter(typeof(T), "instance");
|
var instanceParam = Expression.Parameter(typeof(T), "instance");
|
||||||
var instanceAccess = Expression.Convert(instanceParam, type);
|
var instanceAccess = Expression.Convert(instanceParam, type);
|
||||||
var prop = Expression.Property(instanceAccess, propertyInfo);
|
var prop = Expression.Property(instanceAccess, propertyInfo);
|
||||||
return Expression.Lambda<Func<T, object>>(prop, instanceParam).Compile();
|
var cast = Expression.Convert(prop, typeof(object));
|
||||||
|
return Expression.Lambda<Func<T, object>>(cast, instanceParam).Compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Func<object[], object[], T> CreateLambdaMemberInit(TypeInfo typeInfo, ConstructorInfo constructor, Predicate<PropertyInfo> propertySelect = null)
|
internal static Func<object[], object[], T> CreateLambdaMemberInit(TypeInfo typeInfo, ConstructorInfo constructor, Predicate<PropertyInfo> propertySelect = null)
|
||||||
@@ -227,5 +229,29 @@ namespace Discord.Interactions
|
|||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether <paramref name="type"/> or any base type of it overrides <see cref="object.ToString"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type to check. If <c>null</c> <typeparamref name="T"/> will be used.</param>
|
||||||
|
internal static bool OverridesToString(Type type = null)
|
||||||
|
{
|
||||||
|
type ??= typeof(T);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
var method = type.GetMethod(nameof(ToString), bindingAttr: BindingFlags.Public | BindingFlags.Instance, types: Type.EmptyTypes);
|
||||||
|
#else
|
||||||
|
var method = type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
|
||||||
|
.SingleOrDefault(m => m.Name == nameof(ToString) && m.GetParameters().Length == 0);
|
||||||
|
#endif
|
||||||
|
if (method != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
while ((type = type.BaseType) != typeof(object));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user