Code/Util/NumericCast.cs
namespace Nodebox.Util;

public static class NumericCast {
    // This is retarded
    public static TDestination Cast<TSource, TDestination>(TSource value) {
        var s = typeof(TSource);
        var d = typeof(TDestination);

        var result = (TDestination)(object)(0 switch {
            var _ when s == typeof(float) && d == typeof(float) => (float)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(double) => (double)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(int) => (int)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(uint) => (uint)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(long) => (long)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(ulong) => (ulong)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(short) => (short)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(ushort) => (ushort)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(sbyte) => (sbyte)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(byte) => (byte)(float)(object)value,
            var _ when s == typeof(float) && d == typeof(char) => (char)(float)(object)value,
            // var _ when s == typeof(float) && d == typeof(bool) => (bool)(float)(object)value,

            var _ when s == typeof(double) && d == typeof(float) => (float)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(double) => (double)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(int) => (int)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(uint) => (uint)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(long) => (long)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(ulong) => (ulong)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(short) => (short)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(ushort) => (ushort)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(sbyte) => (sbyte)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(byte) => (byte)(double)(object)value,
            var _ when s == typeof(double) && d == typeof(char) => (char)(double)(object)value,
            // var _ when s == typeof(double) && d == typeof(bool) => (bool)(double)(object)value,

            var _ when s == typeof(int) && d == typeof(float) => (float)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(double) => (double)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(int) => (int)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(uint) => (uint)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(long) => (long)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(ulong) => (ulong)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(short) => (short)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(ushort) => (ushort)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(sbyte) => (sbyte)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(byte) => (byte)(int)(object)value,
            var _ when s == typeof(int) && d == typeof(char) => (char)(int)(object)value,
            // var _ when s == typeof(int) && d == typeof(bool) => (bool)(int)(object)value,

            var _ when s == typeof(uint) && d == typeof(float) => (float)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(double) => (double)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(int) => (int)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(uint) => (uint)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(long) => (long)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(ulong) => (ulong)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(short) => (short)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(ushort) => (ushort)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(sbyte) => (sbyte)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(byte) => (byte)(uint)(object)value,
            var _ when s == typeof(uint) && d == typeof(char) => (char)(uint)(object)value,
            // var _ when s == typeof(uint) && d == typeof(bool) => (bool)(uint)(object)value,

            var _ when s == typeof(long) && d == typeof(float) => (float)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(double) => (double)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(int) => (int)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(uint) => (uint)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(long) => (long)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(ulong) => (ulong)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(short) => (short)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(ushort) => (ushort)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(sbyte) => (sbyte)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(byte) => (byte)(long)(object)value,
            var _ when s == typeof(long) && d == typeof(char) => (char)(long)(object)value,
            // var _ when s == typeof(long) && d == typeof(bool) => (bool)(long)(object)value,

            var _ when s == typeof(ulong) && d == typeof(float) => (float)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(double) => (double)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(int) => (int)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(uint) => (uint)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(long) => (long)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(ulong) => (ulong)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(short) => (short)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(ushort) => (ushort)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(sbyte) => (sbyte)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(byte) => (byte)(ulong)(object)value,
            var _ when s == typeof(ulong) && d == typeof(char) => (char)(ulong)(object)value,
            // var _ when s == typeof(ulong) && d == typeof(bool) => (bool)(ulong)(object)value,

            var _ when s == typeof(short) && d == typeof(float) => (float)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(double) => (double)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(int) => (int)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(uint) => (uint)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(long) => (long)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(ulong) => (ulong)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(short) => (short)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(ushort) => (ushort)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(sbyte) => (sbyte)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(byte) => (byte)(short)(object)value,
            var _ when s == typeof(short) && d == typeof(char) => (char)(short)(object)value,
            // var _ when s == typeof(short) && d == typeof(bool) => (bool)(short)(object)value,

            var _ when s == typeof(ushort) && d == typeof(float) => (float)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(double) => (double)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(int) => (int)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(uint) => (uint)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(long) => (long)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(ulong) => (ulong)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(short) => (short)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(ushort) => (ushort)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(sbyte) => (sbyte)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(byte) => (byte)(ushort)(object)value,
            var _ when s == typeof(ushort) && d == typeof(char) => (char)(ushort)(object)value,
            // var _ when s == typeof(ushort) && d == typeof(bool) => (bool)(ushort)(object)value,

            var _ when s == typeof(sbyte) && d == typeof(float) => (float)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(double) => (double)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(int) => (int)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(uint) => (uint)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(long) => (long)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(ulong) => (ulong)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(short) => (short)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(ushort) => (ushort)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(sbyte) => (sbyte)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(byte) => (byte)(sbyte)(object)value,
            var _ when s == typeof(sbyte) && d == typeof(char) => (char)(sbyte)(object)value,
            // var _ when s == typeof(sbyte) && d == typeof(bool) => (bool)(sbyte)(object)value,

            var _ when s == typeof(byte) && d == typeof(float) => (float)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(double) => (double)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(int) => (int)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(uint) => (uint)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(long) => (long)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(ulong) => (ulong)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(short) => (short)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(ushort) => (ushort)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(sbyte) => (sbyte)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(byte) => (byte)(byte)(object)value,
            var _ when s == typeof(byte) && d == typeof(char) => (char)(byte)(object)value,
            // var _ when s == typeof(byte) && d == typeof(bool) => (bool)(byte)(object)value,

            var _ when s == typeof(char) && d == typeof(float) => (float)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(double) => (double)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(int) => (int)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(uint) => (uint)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(long) => (long)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(ulong) => (ulong)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(short) => (short)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(ushort) => (ushort)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(sbyte) => (sbyte)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(byte) => (byte)(char)(object)value,
            var _ when s == typeof(char) && d == typeof(char) => (char)(char)(object)value,
            // var _ when s == typeof(char) && d == typeof(bool) => (bool)(char)(object)value,

            var _ when s == typeof(bool) && d == typeof(float) => (bool)(object)value ? 1f : 0f,
            var _ when s == typeof(bool) && d == typeof(double) => (bool)(object)value ? 1.0 : 0.0,
            var _ when s == typeof(bool) && d == typeof(int) => (bool)(object)value ? 1 : 0,
            var _ when s == typeof(bool) && d == typeof(uint) => (uint)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(long) => (long)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(ulong) => (ulong)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(short) => (short)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(ushort) => (ushort)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(sbyte) => (sbyte)((bool)(object)value ? 1 : 0),
            var _ when s == typeof(bool) && d == typeof(byte) => (byte)((bool)(object)value ? 1 : 0),
            // var _ when s == typeof(bool) && d == typeof(char) => (char)(bool)(object)value,
            var _ when s == typeof(bool) && d == typeof(bool) => (bool)(bool)(object)value,


            _ => throw new InvalidCastException(),
        });

        return result;
    }
}