using System; using System.Collections.Generic; using MoralisUnity.Platform.Abstractions; namespace MoralisUnity.Platform.Operations { class MoralisIncrementOperation : IMoralisFieldOperation { static IDictionary, Func> Adders { get; } = new Dictionary, Func> { [new Tuple(typeof(sbyte), typeof(sbyte))] = (left, right) => (sbyte)left + (sbyte)right, [new Tuple(typeof(sbyte), typeof(short))] = (left, right) => (sbyte)left + (short)right, [new Tuple(typeof(sbyte), typeof(int))] = (left, right) => (sbyte)left + (int)right, [new Tuple(typeof(sbyte), typeof(long))] = (left, right) => (sbyte)left + (long)right, [new Tuple(typeof(sbyte), typeof(float))] = (left, right) => (sbyte)left + (float)right, [new Tuple(typeof(sbyte), typeof(double))] = (left, right) => (sbyte)left + (double)right, [new Tuple(typeof(sbyte), typeof(decimal))] = (left, right) => (sbyte)left + (decimal)right, [new Tuple(typeof(byte), typeof(byte))] = (left, right) => (byte)left + (byte)right, [new Tuple(typeof(byte), typeof(short))] = (left, right) => (byte)left + (short)right, [new Tuple(typeof(byte), typeof(ushort))] = (left, right) => (byte)left + (ushort)right, [new Tuple(typeof(byte), typeof(int))] = (left, right) => (byte)left + (int)right, [new Tuple(typeof(byte), typeof(uint))] = (left, right) => (byte)left + (uint)right, [new Tuple(typeof(byte), typeof(long))] = (left, right) => (byte)left + (long)right, [new Tuple(typeof(byte), typeof(ulong))] = (left, right) => (byte)left + (ulong)right, [new Tuple(typeof(byte), typeof(float))] = (left, right) => (byte)left + (float)right, [new Tuple(typeof(byte), typeof(double))] = (left, right) => (byte)left + (double)right, [new Tuple(typeof(byte), typeof(decimal))] = (left, right) => (byte)left + (decimal)right, [new Tuple(typeof(short), typeof(short))] = (left, right) => (short)left + (short)right, [new Tuple(typeof(short), typeof(int))] = (left, right) => (short)left + (int)right, [new Tuple(typeof(short), typeof(long))] = (left, right) => (short)left + (long)right, [new Tuple(typeof(short), typeof(float))] = (left, right) => (short)left + (float)right, [new Tuple(typeof(short), typeof(double))] = (left, right) => (short)left + (double)right, [new Tuple(typeof(short), typeof(decimal))] = (left, right) => (short)left + (decimal)right, [new Tuple(typeof(ushort), typeof(ushort))] = (left, right) => (ushort)left + (ushort)right, [new Tuple(typeof(ushort), typeof(int))] = (left, right) => (ushort)left + (int)right, [new Tuple(typeof(ushort), typeof(uint))] = (left, right) => (ushort)left + (uint)right, [new Tuple(typeof(ushort), typeof(long))] = (left, right) => (ushort)left + (long)right, [new Tuple(typeof(ushort), typeof(ulong))] = (left, right) => (ushort)left + (ulong)right, [new Tuple(typeof(ushort), typeof(float))] = (left, right) => (ushort)left + (float)right, [new Tuple(typeof(ushort), typeof(double))] = (left, right) => (ushort)left + (double)right, [new Tuple(typeof(ushort), typeof(decimal))] = (left, right) => (ushort)left + (decimal)right, [new Tuple(typeof(int), typeof(int))] = (left, right) => (int)left + (int)right, [new Tuple(typeof(int), typeof(long))] = (left, right) => (int)left + (long)right, [new Tuple(typeof(int), typeof(float))] = (left, right) => (int)left + (float)right, [new Tuple(typeof(int), typeof(double))] = (left, right) => (int)left + (double)right, [new Tuple(typeof(int), typeof(decimal))] = (left, right) => (int)left + (decimal)right, [new Tuple(typeof(uint), typeof(uint))] = (left, right) => (uint)left + (uint)right, [new Tuple(typeof(uint), typeof(long))] = (left, right) => (uint)left + (long)right, [new Tuple(typeof(uint), typeof(ulong))] = (left, right) => (uint)left + (ulong)right, [new Tuple(typeof(uint), typeof(float))] = (left, right) => (uint)left + (float)right, [new Tuple(typeof(uint), typeof(double))] = (left, right) => (uint)left + (double)right, [new Tuple(typeof(uint), typeof(decimal))] = (left, right) => (uint)left + (decimal)right, [new Tuple(typeof(long), typeof(long))] = (left, right) => (long)left + (long)right, [new Tuple(typeof(long), typeof(float))] = (left, right) => (long)left + (float)right, [new Tuple(typeof(long), typeof(double))] = (left, right) => (long)left + (double)right, [new Tuple(typeof(long), typeof(decimal))] = (left, right) => (long)left + (decimal)right, [new Tuple(typeof(char), typeof(char))] = (left, right) => (char)left + (char)right, [new Tuple(typeof(char), typeof(ushort))] = (left, right) => (char)left + (ushort)right, [new Tuple(typeof(char), typeof(int))] = (left, right) => (char)left + (int)right, [new Tuple(typeof(char), typeof(uint))] = (left, right) => (char)left + (uint)right, [new Tuple(typeof(char), typeof(long))] = (left, right) => (char)left + (long)right, [new Tuple(typeof(char), typeof(ulong))] = (left, right) => (char)left + (ulong)right, [new Tuple(typeof(char), typeof(float))] = (left, right) => (char)left + (float)right, [new Tuple(typeof(char), typeof(double))] = (left, right) => (char)left + (double)right, [new Tuple(typeof(char), typeof(decimal))] = (left, right) => (char)left + (decimal)right, [new Tuple(typeof(float), typeof(float))] = (left, right) => (float)left + (float)right, [new Tuple(typeof(float), typeof(double))] = (left, right) => (float)left + (double)right, [new Tuple(typeof(ulong), typeof(ulong))] = (left, right) => (ulong)left + (ulong)right, [new Tuple(typeof(ulong), typeof(float))] = (left, right) => (ulong)left + (float)right, [new Tuple(typeof(ulong), typeof(double))] = (left, right) => (ulong)left + (double)right, [new Tuple(typeof(ulong), typeof(decimal))] = (left, right) => (ulong)left + (decimal)right, [new Tuple(typeof(double), typeof(double))] = (left, right) => (double)left + (double)right, [new Tuple(typeof(decimal), typeof(decimal))] = (left, right) => (decimal)left + (decimal)right }; static object Add(object first, object second) => Adders.TryGetValue(new Tuple(first.GetType(), second.GetType()), out Func adder) ? adder(first, second) : throw new InvalidCastException($"Could not add objects of type {first.GetType()} and {second.GetType()} to each other."); // [JsonProperty("__op")] public string __op { get { return "Increment"; } } //[JsonProperty("amount")] public object amount { get; } public MoralisIncrementOperation(object amt) => amount = amt; public IMoralisFieldOperation MergeWithPrevious(IMoralisFieldOperation previous) => previous switch { null => this, MoralisDeleteOperation _ => new MoralisSetOperation(amount), // This may be a bug, but it was in the original logic. MoralisSetOperation { Value: string { } } => throw new InvalidOperationException("Cannot increment a non-number type."), MoralisSetOperation { Value: var value } => new MoralisSetOperation(Add(value, amount)), MoralisIncrementOperation { amount: var amt } => new MoralisIncrementOperation(Add(amt, amount)), _ => throw new InvalidOperationException("Operation is invalid after previous operation.") }; public object Apply(object oldValue, string key) { if (oldValue is string) throw new InvalidOperationException("Cannot increment a non-number type."); if (oldValue == null) oldValue = 0; return Add(oldValue, amount); } } }