Prechádzať zdrojové kódy

Improved Calculator Converters

Frank van den Bos 1 rok pred
rodič
commit
e925390d9d

+ 7 - 6
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/AbstractMultiConverter.cs

@@ -10,24 +10,25 @@ namespace InABox.Mobile
     public abstract class AbstractMultiConverter<TIn, TOut> : BindableObject, IMultiValueConverter
     {
         
-        protected abstract TOut Convert(IEnumerable<TIn?> value, object? parameter = null);
+        protected abstract TOut Convert(IEnumerable<TIn?>? value, object? parameter = null);
 
-        protected virtual IEnumerable<TIn> Deconvert(TOut? value, object? parameter = null)
+        protected virtual IEnumerable<TIn?>? Deconvert(TOut? value, object? parameter = null)
         {
             return default;
         }
         
-        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        public object? Convert(object[]? values, Type targetType, object parameter, CultureInfo culture)
         {
+            if (values?.Any() != true)
+                return default(TOut);
             var typed = values.Select(x => x is TIn tin ? tin : default);
             return Convert(typed, parameter);
         }
 
-        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        public object?[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
         {
-            
             var typed = value is TOut tout ? tout : default;
-            var result = Deconvert(typed);
+            var result = Deconvert(typed) ?? new TIn?[] { };
             return result.Select(x => x as object).ToArray();
         }
         

+ 53 - 0
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/AbstractCalculator.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using JetBrains.Annotations;
+
+namespace InABox.Mobile
+{
+
+    public abstract class AbstractCalculatorFunction<TValue, TType> where TType : struct, IComparable
+    {
+        
+        protected abstract TValue Calculate(TValue current, TValue next, TType type) ;
+        public TValue Calculate(TValue[] value, TType type)
+        {
+            if (!value.Any())
+                return default;
+            var result = value.First();
+            result = value.Skip(1).Aggregate(result, (current, next) => Calculate(current, next, type));
+            return result;
+        }
+        
+    }
+    
+    public abstract class AbstractCalculator<TValue,TFunction, TType> : AbstractMultiConverter<TValue,TValue> 
+        where TFunction : AbstractCalculatorFunction<TValue,TType>, new()
+        where TType : struct, IComparable
+    {
+
+        public TValue Default { get; private set; }
+        
+        public TType Type { get; set; }
+        
+        public TFunction Function { get; private set; }
+
+        protected AbstractCalculator()
+        {
+            Default = default;
+            Function = new TFunction();
+        }
+        
+        protected override TValue Convert(IEnumerable<TValue> value, object parameter = null)
+        {
+            var enumerable = value as TValue[] ?? value?.ToArray() ?? new TValue[] { };
+            if (Function == null || !enumerable.Any())
+                return Default;
+
+            var result = Function.Calculate(enumerable, Type);
+            return result;
+        }
+    }
+}

+ 62 - 0
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/AbstractNumericCalculator.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using JetBrains.Annotations;
+
+namespace InABox.Mobile
+{
+    
+    public abstract class AbstractNumericArrayConverter<TValue> : TypeConverter
+    {
+
+        protected abstract TValue[] Convert(IEnumerable<string> values);
+        
+        public override object ConvertFrom(
+            ITypeDescriptorContext context, CultureInfo culture, object value)
+        {
+            if (value is string list)
+            {
+                try
+                {
+                    var result =  Convert(list.Split(','));
+                    return result;
+                }
+                catch
+                {
+                    
+                }
+            }
+
+            return new TValue[] { };
+        }
+    
+        public override bool CanConvertFrom(
+            ITypeDescriptorContext context, Type sourceType)
+        {
+            if (sourceType == typeof(string))
+                return true;
+    
+            return base.CanConvertFrom(context, sourceType);
+        }
+    }
+    
+    public abstract class AbstractNumericCalculator<TValue,TFunction> : AbstractCalculator<TValue, TFunction, NumericCalculatorType> 
+        where TFunction : AbstractCalculatorFunction<TValue,NumericCalculatorType>, new()
+
+
+    {
+        
+        [CanBeNull] public abstract TValue[] Constants { get; set; }
+        
+        protected override TValue Convert(IEnumerable<TValue> value, object parameter = null)
+        {
+            var enumerable = value as TValue[] ?? value.ToArray();
+            var values = Constants != null
+                ? Constants.Concat(enumerable.ToArray())
+                : enumerable;
+            return base.Convert(values, parameter);
+        }
+    }
+}

+ 2 - 2
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Combiner/CombinerFunctions.cs → InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/CombinerFunctions.cs

@@ -1,6 +1,6 @@
 namespace InABox.Mobile
 {
-    public enum NumericCombinerFunction
+    public enum NumericCalculatorType
     {
         Sum,
         Product,
@@ -9,7 +9,7 @@ namespace InABox.Mobile
         Minimum
     }
     
-    public enum StringCombinerFunction
+    public enum StringCalculatorType
     {
         Append
     }

+ 41 - 0
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/DoubleCalculator.cs

@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Net.Http.Headers;
+
+namespace InABox.Mobile
+{
+    public class DoubleCalculatorFunction : AbstractCalculatorFunction<double, NumericCalculatorType>
+    {
+        
+        protected override double Calculate(double current, double next, NumericCalculatorType type)
+        {
+            var result = type switch
+            {
+                NumericCalculatorType.Sum => current + next,
+                NumericCalculatorType.Product => current * next,
+                NumericCalculatorType.Subtraction => current - next,
+                NumericCalculatorType.Maximum => current > next ? current : next,
+                NumericCalculatorType.Minimum => current < next ? current : next,
+                _ => current
+            };
+            return result;
+        }
+    }
+
+    public class DoubleArrayConverter : AbstractNumericArrayConverter<double>
+    {
+        protected override double[] Convert(IEnumerable<string> values)
+        {
+            var result =  values.Select(double.Parse).ToArray();
+            return result;
+        }
+    }
+    
+    public class DoubleCalculator : AbstractNumericCalculator<double, DoubleCalculatorFunction>
+    {
+        [TypeConverter(typeof(DoubleArrayConverter))]
+        public override double[] Constants { get; set; }
+    }
+    
+}

+ 39 - 0
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/IntegerCalculator.cs

@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace InABox.Mobile
+{
+    public class IntegerCalculatorFunction : AbstractCalculatorFunction<int, NumericCalculatorType>
+    {
+        
+        protected override int Calculate(int current, int next, NumericCalculatorType type)
+        {
+            var result = type switch
+            {
+                NumericCalculatorType.Sum => current + next,
+                NumericCalculatorType.Product => current * next,
+                NumericCalculatorType.Subtraction => current - next,
+                NumericCalculatorType.Maximum => current > next ? current : next,
+                NumericCalculatorType.Minimum => current < next ? current : next,
+                _ => current
+            };
+            return result;
+        }
+    }
+
+    public class IntegerArrayConverter : AbstractNumericArrayConverter<int>
+    {
+        protected override int[] Convert(IEnumerable<string> values)
+        {
+            var result =  values.Select(int.Parse).ToArray();
+            return result;
+        }
+    }
+    
+    public class IntegerCalculator : AbstractNumericCalculator<int, IntegerCalculatorFunction>
+    {
+        [TypeConverter(typeof(IntegerArrayConverter))]
+        public override int[] Constants { get; set; }
+    }
+}

+ 45 - 0
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Calculator/StringCalculator.cs

@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace InABox.Mobile
+{
+    // public class StringCalculator : AbstractCalculator<string, StringCombinerFunction>
+    // {
+    //     
+    //     public string Separator { get; set; }
+    //     protected override string Combine(string current, string next)
+    //     {
+    //         return Function switch
+    //         {
+    //             StringCombinerFunction.Append => string.Join(Separator, new [] { current, next } ),
+    //         _ => current
+    //         };
+    //     }
+    // }
+    
+    public class StringCalculatorFunction : AbstractCalculatorFunction<string, StringCalculatorType>
+    {
+        public string Separator { get; set; }
+        protected override string Calculate(string current, string next, StringCalculatorType type)
+        {
+            var result = type switch
+            {
+                StringCalculatorType.Append => string.Join(Separator, new [] { current, next } ),
+                _ => current
+            };
+            return result;
+        }
+    }
+    
+    public class StringCalculator : AbstractCalculator<string, StringCalculatorFunction, StringCalculatorType>
+    {
+        
+        public string Separator
+        {
+            get => Function.Separator;
+            set => Function.Separator = value;
+        }
+        
+    }
+}

+ 0 - 21
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Combiner/AbstractCombiner.cs

@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace InABox.Mobile
-{
-    public abstract class AbstractCombiner<TValue,TFunction> : AbstractMultiConverter<TValue,TValue> 
-        where TFunction : struct, IConvertible
-    {
-
-        public TFunction Function { get; set; }
-        
-        protected abstract TValue Combine(TValue current, TValue next);
-        protected override TValue Convert(IEnumerable<TValue> value, object parameter = null)
-        {
-            if (value?.Any() != true)
-                return default;
-            return value.Aggregate<TValue,TValue>(default,Combine);
-        }
-    }
-}

+ 0 - 18
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Combiner/DoubleCombiner.cs

@@ -1,18 +0,0 @@
-namespace InABox.Mobile
-{
-    public class DoubleCombiner : AbstractCombiner<double, NumericCombinerFunction>
-    {
-        protected override double Combine(double current, double next)
-        {
-            return Function switch
-            {
-                NumericCombinerFunction.Sum => current + next,
-                NumericCombinerFunction.Product => current * next,
-                NumericCombinerFunction.Subtraction => current - next,
-                NumericCombinerFunction.Maximum => current > next ? current : next,
-                NumericCombinerFunction.Minimum => current < next ? current : next,
-                _ => current
-            };
-        }
-    }
-}

+ 0 - 20
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Combiner/IntegerCombiner.cs

@@ -1,20 +0,0 @@
-using System.Linq;
-
-namespace InABox.Mobile
-{
-    public class IntegerCombiner : AbstractCombiner<int, NumericCombinerFunction>
-    {
-        protected override int Combine(int current, int next)
-        {
-            return Function switch
-            {
-                NumericCombinerFunction.Sum => current + next,
-                NumericCombinerFunction.Product => current * next,
-                NumericCombinerFunction.Subtraction => current - next,
-                NumericCombinerFunction.Maximum => current > next ? current : next,
-                NumericCombinerFunction.Minimum => current < next ? current : next,
-                _ => current
-            };
-        }
-    }
-}

+ 0 - 16
InABox.Mobile/InABox.Mobile.Shared/Converters/MultiConverters/Combiner/StringCombiner.cs

@@ -1,16 +0,0 @@
-namespace InABox.Mobile
-{
-    public class StringCombiner : AbstractCombiner<string, StringCombinerFunction>
-    {
-        
-        public string Separator { get; set; }
-        protected override string Combine(string current, string next)
-        {
-            return Function switch
-            {
-                StringCombinerFunction.Append => string.Join(Separator, new [] { current, next } ),
-            _ => current
-            };
-        }
-    }
-}