forked from LykosAI/StabilityMatrix
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request LykosAI#402 from ionite34/fixes
- Loading branch information
Showing
11 changed files
with
170 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
StabilityMatrix.Avalonia/Converters/NullableDefaultNumericConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System; | ||
using System.ComponentModel; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
using System.Numerics; | ||
using Avalonia.Data.Converters; | ||
|
||
namespace StabilityMatrix.Avalonia.Converters; | ||
|
||
/// <summary> | ||
/// Converts a possibly boxed nullable value type to its default value | ||
/// </summary> | ||
public class NullableDefaultNumericConverter<TSource, TTarget> : IValueConverter | ||
where TSource : unmanaged, INumber<TSource> | ||
where TTarget : unmanaged, INumber<TTarget> | ||
{ | ||
public ReturnBehavior NanHandling { get; set; } = ReturnBehavior.DefaultValue; | ||
|
||
/// <summary> | ||
/// Unboxes a nullable value type | ||
/// </summary> | ||
private TSource Unbox(TTarget? value) | ||
{ | ||
if (!value.HasValue) | ||
{ | ||
return default; | ||
} | ||
|
||
if (TTarget.IsNaN(value.Value)) | ||
{ | ||
return NanHandling switch | ||
{ | ||
ReturnBehavior.DefaultValue => default, | ||
ReturnBehavior.Throw => throw new InvalidCastException("Cannot convert NaN to a numeric type"), | ||
_ | ||
=> throw new InvalidEnumArgumentException( | ||
nameof(NanHandling), | ||
(int)NanHandling, | ||
typeof(ReturnBehavior) | ||
) | ||
}; | ||
} | ||
|
||
return (TSource)System.Convert.ChangeType(value.Value, typeof(TSource)); | ||
} | ||
|
||
/// <summary> | ||
/// Convert a value type to a nullable value type | ||
/// </summary> | ||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) | ||
{ | ||
if (targetType != typeof(TTarget?) && !targetType.IsAssignableTo(typeof(TTarget))) | ||
{ | ||
// ReSharper disable once LocalizableElement | ||
throw new ArgumentException( | ||
$"Convert Target type {targetType.Name} must be assignable to {typeof(TTarget).Name}" | ||
); | ||
} | ||
|
||
return (TTarget?)System.Convert.ChangeType(value, typeof(TTarget)); | ||
} | ||
|
||
/// <summary> | ||
/// Convert a nullable value type to a value type | ||
/// </summary> | ||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) | ||
{ | ||
if (!targetType.IsAssignableTo(typeof(TSource))) | ||
{ | ||
// ReSharper disable once LocalizableElement | ||
throw new ArgumentException( | ||
$"ConvertBack Target type {targetType.Name} must be assignable to {typeof(TSource).Name}" | ||
); | ||
} | ||
|
||
return Unbox((TTarget?)value); | ||
} | ||
|
||
public enum ReturnBehavior | ||
{ | ||
DefaultValue, | ||
Throw | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
StabilityMatrix.Avalonia/Converters/NullableDefaultNumericConverters.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace StabilityMatrix.Avalonia.Converters; | ||
|
||
public static class NullableDefaultNumericConverters | ||
{ | ||
public static readonly NullableDefaultNumericConverter<int, decimal> IntToDecimal = new(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
StabilityMatrix.Tests/Avalonia/Converters/NullableDefaultNumericConverterTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System.Globalization; | ||
using StabilityMatrix.Avalonia.Converters; | ||
|
||
namespace StabilityMatrix.Tests.Avalonia.Converters; | ||
|
||
[TestClass] | ||
public class NullableDefaultNumericConverterTests | ||
{ | ||
[TestMethod] | ||
public void Convert_IntToDecimal_ValueReturnsNullable() | ||
{ | ||
const int value = 123; | ||
|
||
var converter = NullableDefaultNumericConverters.IntToDecimal; | ||
|
||
var result = converter.Convert(value, typeof(decimal?), null, CultureInfo.InvariantCulture); | ||
|
||
Assert.AreEqual((decimal?)123, result); | ||
} | ||
|
||
[TestMethod] | ||
public void ConvertBack_IntToDecimal_NullableReturnsDefault() | ||
{ | ||
decimal? value = null; | ||
|
||
var converter = NullableDefaultNumericConverters.IntToDecimal; | ||
|
||
var result = converter.ConvertBack(value, typeof(int), null, CultureInfo.InvariantCulture); | ||
|
||
Assert.AreEqual(0, result); | ||
} | ||
|
||
[TestMethod] | ||
public void ConvertBack_IntToDouble_NanReturnsDefault() | ||
{ | ||
const double value = double.NaN; | ||
|
||
var converter = new NullableDefaultNumericConverter<int, double>(); | ||
|
||
var result = converter.ConvertBack(value, typeof(int), null, CultureInfo.InvariantCulture); | ||
|
||
Assert.AreEqual(0, result); | ||
} | ||
} |