From 62186f43974e9d076b867657297eb9637a5c851d Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Sun, 17 Mar 2024 22:04:12 +0100
Subject: [PATCH 01/12] Initial helper classes
---
src/CuteUtils/BoolExtentions.cs | 53 ++++
src/CuteUtils/Class1.cs | 6 -
src/CuteUtils/CollectionExtentions.cs | 129 ++++++++
src/CuteUtils/ConsoleExtentions.cs | 148 +++++++++
src/CuteUtils/FluentMath/Shapes/Rectangle.cs | 43 +++
.../TypeExtentions/DecimalFluent.cs | 161 ++++++++++
.../FluentMath/TypeExtentions/DoubleFluent.cs | 287 ++++++++++++++++++
.../FluentMath/TypeExtentions/Int16Fluent.cs | 119 ++++++++
.../FluentMath/TypeExtentions/Int32Fluent.cs | 119 ++++++++
.../FluentMath/TypeExtentions/Int64Fluent.cs | 119 ++++++++
.../FluentMath/TypeExtentions/SingleFluent.cs | 287 ++++++++++++++++++
src/CuteUtils/Logging/LogConfig.cs | 83 +++++
src/CuteUtils/Logging/LogFormatBuilder.cs | 147 +++++++++
src/CuteUtils/Logging/LogFormatType.cs | 42 +++
src/CuteUtils/Logging/LogSeverity.cs | 32 ++
src/CuteUtils/Logging/LogTarget.cs | 23 ++
src/CuteUtils/Logging/Logger.cs | 278 +++++++++++++++++
src/CuteUtils/RandomExtentions.cs | 30 ++
src/CuteUtils/Reflection.cs | 60 ++++
src/CuteUtils/StringExtentions.cs | 169 +++++++++++
src/CuteUtils/Tasks/BlockingTaskQueue.cs | 91 ++++++
src/CuteUtils/Tasks/TaskQueue.cs | 134 ++++++++
22 files changed, 2554 insertions(+), 6 deletions(-)
create mode 100644 src/CuteUtils/BoolExtentions.cs
delete mode 100644 src/CuteUtils/Class1.cs
create mode 100644 src/CuteUtils/CollectionExtentions.cs
create mode 100644 src/CuteUtils/ConsoleExtentions.cs
create mode 100644 src/CuteUtils/FluentMath/Shapes/Rectangle.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/DecimalFluent.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/DoubleFluent.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/Int16Fluent.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/Int32Fluent.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/Int64Fluent.cs
create mode 100644 src/CuteUtils/FluentMath/TypeExtentions/SingleFluent.cs
create mode 100644 src/CuteUtils/Logging/LogConfig.cs
create mode 100644 src/CuteUtils/Logging/LogFormatBuilder.cs
create mode 100644 src/CuteUtils/Logging/LogFormatType.cs
create mode 100644 src/CuteUtils/Logging/LogSeverity.cs
create mode 100644 src/CuteUtils/Logging/LogTarget.cs
create mode 100644 src/CuteUtils/Logging/Logger.cs
create mode 100644 src/CuteUtils/RandomExtentions.cs
create mode 100644 src/CuteUtils/Reflection.cs
create mode 100644 src/CuteUtils/StringExtentions.cs
create mode 100644 src/CuteUtils/Tasks/BlockingTaskQueue.cs
create mode 100644 src/CuteUtils/Tasks/TaskQueue.cs
diff --git a/src/CuteUtils/BoolExtentions.cs b/src/CuteUtils/BoolExtentions.cs
new file mode 100644
index 0000000..93a9d24
--- /dev/null
+++ b/src/CuteUtils/BoolExtentions.cs
@@ -0,0 +1,53 @@
+namespace CuteUtils;
+
+///
+/// Extensions
+///
+public static class BoolExt
+{
+ ///
+ /// Sets value to true if input is true. If input is false the value will not change.
+ ///
+ ///
+ ///
+ public static void OneWayTrue(this ref bool bol, bool input)
+ {
+ if (!bol && input)
+ {
+ bol = true;
+ }
+ }
+
+ ///
+ /// Sets value to false if input is false. If input is true the value will not change.
+ ///
+ ///
+ ///
+ public static void OneWayFalse(this ref bool bol, bool input)
+ {
+ if (bol && !input)
+ {
+ bol = false;
+ }
+ }
+
+ ///
+ /// Converts bool to int.
+ ///
+ ///
+ ///
+ public static int ToInt(this bool input)
+ {
+ return input ? 1 : 0;
+ }
+
+ ///
+ /// Converts int to bool.
+ ///
+ ///
+ ///
+ public static void FromInt(this ref bool bol, int input)
+ {
+ bol = input == 1;
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Class1.cs b/src/CuteUtils/Class1.cs
deleted file mode 100644
index 2f8ed95..0000000
--- a/src/CuteUtils/Class1.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace CuteUtils;
-
-public class Class1
-{
-
-}
diff --git a/src/CuteUtils/CollectionExtentions.cs b/src/CuteUtils/CollectionExtentions.cs
new file mode 100644
index 0000000..a9dcb84
--- /dev/null
+++ b/src/CuteUtils/CollectionExtentions.cs
@@ -0,0 +1,129 @@
+using System.Diagnostics;
+
+namespace CuteUtils;
+
+///
+/// Table Style
+///
+public enum TableStyle
+{
+ ///
+ /// The default representation of the table
+ ///
+ Default,
+
+ ///
+ /// The minimal representation of the table
+ ///
+ Minimum,
+
+ ///
+ /// The alternative representation of the table
+ ///
+ Alternative,
+
+ ///
+ /// The list representation of the table
+ ///
+ List
+}
+
+///
+/// and Extensions
+///
+public static class CollectionExt
+{
+ ///
+ /// Prints all items of an
+ ///
+ ///
+ ///
+ ///
+ public static void Print(this IEnumerable collection, char delimiter = ',', bool printToDebugConsole = false)
+ {
+ int i = 0;
+ int length = collection.Count() - 1;
+ string split = delimiter + (delimiter == '\n' ? string.Empty : " ");
+ foreach (T item in collection)
+ {
+ if (item is IEnumerable ie)
+ {
+ ie.Print(delimiter, printToDebugConsole);
+ }
+ else if (printToDebugConsole)
+ {
+ Debug.Write(item?.ToString() + (i < length ? split : string.Empty));
+ }
+ else
+ {
+ Console.Write(item?.ToString() + (i < length ? split : string.Empty));
+ }
+ i++;
+ }
+ }
+
+ ///
+ /// Creates and prints table from 2D array
+ ///
+ ///
+ ///
+ ///
+ public static void PrintTable(this T[,] array, TableStyle tableStyle = TableStyle.Default)
+ {
+ int[] itemLength = new int[array.GetLength(1)];
+ char verticalChar = tableStyle == TableStyle.Minimum ? ' ' : '|';
+
+ for (int i = 0; i < array.GetLength(0); i++)
+ {
+ for (int j = 0; j < array.GetLength(1); j++)
+ {
+ itemLength[j] = Math.Max(array[i, j]!.ToString()!.Length + 2, itemLength[j]);
+ }
+ }
+
+ PrintLine(tableStyle, itemLength, array.GetLength(1), tableStyle == TableStyle.List);
+
+ for (int i = 0; i < array.GetLength(0); i++)
+ {
+ for (int j = 0; j < array.GetLength(1); j++)
+ {
+ string item = " " + array[i, j]?.ToString() + " ";
+ item = verticalChar + item + new string(' ', itemLength[j] - item.Length);
+ Console.Write(tableStyle == TableStyle.Minimum && j == 0 ? item.TrimStart() : item);
+ }
+
+ Console.Write(verticalChar);
+
+ PrintLine(tableStyle, itemLength, array.GetLength(1), i == 0);
+ }
+ }
+
+ private static void PrintLine(TableStyle tableStyle, int[] itemLength, int itemCount, bool forcePrint = false)
+ {
+ char intersect = tableStyle is TableStyle.Alternative or TableStyle.List ? '+' : '-';
+
+ Console.WriteLine();
+ if (tableStyle is TableStyle.Minimum or TableStyle.List)
+ {
+ if (tableStyle == TableStyle.List && forcePrint)
+ {
+ Console.Write(intersect);
+ }
+
+ if (!forcePrint)
+ {
+ return;
+ }
+ }
+ else
+ {
+ Console.Write(intersect);
+ }
+
+ for (int k = 0; k < itemCount; k++)
+ {
+ Console.Write(new string('-', itemLength[k] - (tableStyle == TableStyle.Minimum ? 1 : 0)) + intersect);
+ }
+ Console.WriteLine();
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/ConsoleExtentions.cs b/src/CuteUtils/ConsoleExtentions.cs
new file mode 100644
index 0000000..347a30d
--- /dev/null
+++ b/src/CuteUtils/ConsoleExtentions.cs
@@ -0,0 +1,148 @@
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+
+#pragma warning disable S3998 // Threads should not lock on objects with weak identity
+
+namespace CuteUtils;
+
+///
+/// Extensions
+///
+public static class ConsoleExt
+{
+ ///
+ /// Writes the text representation of the specified object to the standard output stream.
+ ///
+ ///
+ ///
+ public static void Write(object value, ConsoleColor color)
+ {
+ lock (Console.Out)
+ {
+ ConsoleColor oldColor = Console.ForegroundColor;
+ Console.ForegroundColor = color;
+ Console.Write(value);
+ Console.ForegroundColor = oldColor;
+ }
+ }
+
+ ///
+ /// Writes the text representation of the specified object, followed by the current line terminator, to the standard output stream.
+ ///
+ ///
+ ///
+ public static void WriteLine(object value, ConsoleColor color)
+ {
+ lock (Console.Out)
+ {
+ ConsoleColor oldColor = Console.ForegroundColor;
+ Console.ForegroundColor = color;
+ Console.WriteLine(value);
+ Console.ForegroundColor = oldColor;
+ }
+ }
+
+ ///
+ /// Reads the next line of characters from the standard input stream and tries to convert it to the specified type.
+ ///
+ ///
+ /// The input string converted to the specified type.
+ ///
+ public static T ReadLine()
+ {
+ string attemptedValue = Console.ReadLine() ?? string.Empty;
+ Type type = typeof(T);
+ TypeConverter converter = TypeDescriptor.GetConverter(type);
+
+ return (T)converter.ConvertFromString(attemptedValue)!;
+ }
+
+ ///
+ /// Reads the next line of characters from the standard input stream and tries to convert it to the specified type.
+ ///
+ ///
+ /// The input string converted to the specified type.
+ /// if the conversion was successful. Otherwise
+ public static bool TryReadLine([NotNullWhen(true)] out T? input)
+ {
+ string attemptedValue = Console.ReadLine() ?? string.Empty;
+ Type type = typeof(T);
+ TypeConverter converter = TypeDescriptor.GetConverter(type);
+ if (converter != null && converter.IsValid(attemptedValue))
+ {
+ input = (T)converter.ConvertFromString(attemptedValue)!;
+ return true;
+ }
+ else
+ {
+ input = default;
+ return false;
+ }
+ }
+
+ ///
+ /// Obtains the next character or function key pressed by the user and converts it to the specified type.
+ /// The pressed key is displayed in the console window.
+ ///
+ /// The type of the
+ /// The input character converted to the specified type.
+ ///
+ public static T ReadKey()
+ {
+ string attemptedValue = Console.ReadKey().KeyChar.ToString();
+ Type type = typeof(T);
+ TypeConverter converter = TypeDescriptor.GetConverter(type);
+
+ return (T)converter.ConvertFromString(attemptedValue)!;
+ }
+
+ ///
+ /// Obtains the next character or function key pressed by the user and tries to convert it to the specified type.
+ /// The pressed key is displayed in the console window.
+ ///
+ /// The input character converted to the specified type.
+ /// The type of the
+ /// if the conversion was successful. Otherwise
+ public static bool TryReadKey([NotNullWhen(true)] out T? input)
+ {
+ string attemptedValue = Console.ReadKey().KeyChar.ToString();
+ Type type = typeof(T);
+ TypeConverter converter = TypeDescriptor.GetConverter(type);
+ if (converter != null && converter.IsValid(attemptedValue))
+
+ {
+ input = (T)converter.ConvertFromString(attemptedValue)!;
+ return true;
+ }
+ else
+ {
+ input = default;
+ return false;
+ }
+ }
+
+ ///
+ /// Suspends execution of the current method until the user presses a key
+ ///
+ /// The key that has to be pressed
+ /// The message that will be displayed
+ public static void Pause(ConsoleKey key, string? message = null)
+ {
+ Console.WriteLine(message ?? $"Press {key} to continue...");
+ ConsoleKey? consoleKey = null;
+ while (consoleKey != key)
+ {
+ consoleKey = Console.ReadKey(true).Key;
+ }
+ }
+
+ ///
+ /// Suspends execution of the current method until the user presses a key
+ ///
+ /// The message that will be displayed
+ public static void Pause(string message = "Press any key to continue...")
+ {
+ Console.WriteLine(message);
+ _ = Console.ReadKey(true);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Rectangle.cs b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
new file mode 100644
index 0000000..424424b
--- /dev/null
+++ b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
@@ -0,0 +1,43 @@
+namespace CuteUtils.FluentMath.Shapes;
+
+///
+/// Represents a rectangle
+///
+public class Rectangle
+{
+ ///
+ /// The length of the
+ ///
+ public double Length { get; set; }
+
+ ///
+ /// The width of the
+ ///
+ public double Width { get; set; }
+
+ ///
+ /// The diagonal of the
+ ///
+ public double Diagonal => Math.Sqrt(Math.Pow(Length, 2) + Math.Pow(Width, 2));
+
+ ///
+ /// The area of the
+ ///
+ public double Area => Length * Width;
+
+ ///
+ /// The perimeter of the
+ ///
+ public double Perimeter => Length * 2 + Width * 2;
+
+ ///
+ /// Creates a new rectangle instance
+ ///
+ /// The length of the rectangle
+ /// The width of the rectangle
+ public Rectangle(double length, double width)
+ {
+ Length = length;
+ Width = width;
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/DecimalFluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/DecimalFluent.cs
new file mode 100644
index 0000000..0740e68
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/DecimalFluent.cs
@@ -0,0 +1,161 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// DecimalFluent class
+///
+public static class DecimalFluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static double ToDouble(this decimal num)
+ {
+ return (double)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static float ToSingle(this decimal num)
+ {
+ return (float)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static short ToInt16(this decimal num)
+ {
+ return (short)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static int ToInt32(this decimal num)
+ {
+ return (int)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static long ToInt64(this decimal num)
+ {
+ return (long)num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static decimal Add(this decimal num, decimal value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static decimal Subtract(this decimal num, decimal value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static decimal Multiply(this decimal num, decimal value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static decimal Divide(this decimal num, decimal value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static decimal Abs(this decimal num)
+ {
+ return Math.Abs(num);
+ }
+
+ ///
+ public static decimal Ceiling(this decimal num)
+ {
+ return Math.Ceiling(num);
+ }
+
+ ///
+ public static decimal Clamp(this decimal num, decimal min, decimal max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static decimal Floor(this decimal num)
+ {
+ return Math.Floor(num);
+ }
+
+ ///
+ public static decimal Round(this decimal num)
+ {
+ return Math.Round(num);
+ }
+
+ ///
+ public static decimal Round(this decimal num, MidpointRounding mode)
+ {
+ return Math.Round(num, mode);
+ }
+
+ ///
+ public static decimal Round(this decimal num, int digits)
+ {
+ return Math.Round(num, digits);
+ }
+
+ ///
+ public static decimal Round(this decimal num, int digits, MidpointRounding mode)
+ {
+ return Math.Round(num, digits, mode);
+ }
+
+ ///
+ public static int Sign(this decimal num)
+ {
+ return Math.Sign(num);
+ }
+
+ ///
+ public static decimal Truncate(this decimal num)
+ {
+ return Math.Truncate(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/DoubleFluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/DoubleFluent.cs
new file mode 100644
index 0000000..e067c93
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/DoubleFluent.cs
@@ -0,0 +1,287 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// DoubleFluent class
+///
+public static class DoubleFluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static decimal ToDecimal(this double num)
+ {
+ return (decimal)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static float ToSingle(this double num)
+ {
+ return (float)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static short ToInt16(this double num)
+ {
+ return (short)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static int ToInt32(this double num)
+ {
+ return (int)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static long ToInt64(this double num)
+ {
+ return (long)num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static double Add(this double num, double value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static double Subtract(this double num, double value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static double Multiply(this double num, double value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static double Divide(this double num, double value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static double Abs(this double num)
+ {
+ return Math.Abs(num);
+ }
+
+ ///
+ public static double Acos(this double num)
+ {
+ return Math.Acos(num);
+ }
+
+ ///
+ public static double Acosh(this double num)
+ {
+ return Math.Acosh(num);
+ }
+
+ ///
+ public static double Asin(this double num)
+ {
+ return Math.Asin(num);
+ }
+
+ ///
+ public static double Asinh(this double num)
+ {
+ return Math.Asinh(num);
+ }
+
+ ///
+ public static double Atan(this double num)
+ {
+ return Math.Atan(num);
+ }
+
+ ///
+ public static double Atan2(this double num, double valuee)
+ {
+ return Math.Atan2(num, valuee);
+ }
+
+ ///
+ public static double Atanh(this double num)
+ {
+ return Math.Atanh(num);
+ }
+
+ ///
+ public static double Cbrt(this double num)
+ {
+ return Math.Cbrt(num);
+ }
+
+ ///
+ public static double Ceiling(this double num)
+ {
+ return Math.Ceiling(num);
+ }
+
+ ///
+ public static double Clamp(this double num, double min, double max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static double Cos(this double num)
+ {
+ return Math.Cos(num);
+ }
+
+ ///
+ public static double Cosh(this double num)
+ {
+ return Math.Cosh(num);
+ }
+
+ ///
+ public static double Exp(this double num)
+ {
+ return Math.Exp(num);
+ }
+
+ ///
+ public static double Floor(this double num)
+ {
+ return Math.Floor(num);
+ }
+
+ ///
+ public static double IEEERemainder(this double num, double valuee)
+ {
+ return Math.IEEERemainder(num, valuee);
+ }
+
+ ///
+ public static double Log(this double num)
+ {
+ return Math.Log(num);
+ }
+
+ ///
+ public static double Log(this double num, double newBase)
+ {
+ return Math.Log(num, newBase);
+ }
+
+ ///
+ public static double Log10(this double num)
+ {
+ return Math.Log10(num);
+ }
+
+ ///
+ public static double Pow(this double num, double power)
+ {
+ return Math.Pow(num, power);
+ }
+
+ ///
+ public static double Round(this double num)
+ {
+ return Math.Round(num);
+ }
+
+ ///
+ public static double Round(this double num, MidpointRounding mode)
+ {
+ return Math.Round(num, mode);
+ }
+
+ ///
+ public static double Round(this double num, int digits)
+ {
+ return Math.Round(num, digits);
+ }
+
+ ///
+ public static double Round(this double num, int digits, MidpointRounding mode)
+ {
+ return Math.Round(num, digits, mode);
+ }
+
+ ///
+ public static int Sign(this double num)
+ {
+ return Math.Sign(num);
+ }
+
+ ///
+ public static double Sin(this double num)
+ {
+ return Math.Sin(num);
+ }
+
+ ///
+ public static double Sinh(this double num)
+ {
+ return Math.Sinh(num);
+ }
+
+ ///
+ public static double Sqrt(this double num)
+ {
+ return Math.Sqrt(num);
+ }
+
+ ///
+ public static double Tan(this double num)
+ {
+ return Math.Tan(num);
+ }
+
+ ///
+ public static double Tanh(this double num)
+ {
+ return Math.Tanh(num);
+ }
+
+ ///
+ public static double Truncate(this double num)
+ {
+ return Math.Truncate(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/Int16Fluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/Int16Fluent.cs
new file mode 100644
index 0000000..b0a53cc
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/Int16Fluent.cs
@@ -0,0 +1,119 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// IntegerFluent class
+///
+public static class Int16Fluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static decimal ToDecimal(this short num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static float ToSingle(this short num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static double ToDouble(this short num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static int ToInt32(this short num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static long ToInt64(this short num)
+ {
+ return num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Add(this short num, short value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Subtract(this short num, short value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Multiply(this short num, short value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Divide(this short num, short value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static short Abs(this short num)
+ {
+ return Math.Abs(num);
+ }
+
+ ///
+ public static short Clamp(this short num, short min, short max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static int Sign(this short num)
+ {
+ return Math.Sign(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/Int32Fluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/Int32Fluent.cs
new file mode 100644
index 0000000..754c1bb
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/Int32Fluent.cs
@@ -0,0 +1,119 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// IntegerFluent class
+///
+public static class Int32Fluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static decimal ToDecimal(this int num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static float ToSingle(this int num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static double ToDouble(this int num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static short ToInt16(this int num)
+ {
+ return (short)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static long ToInt64(this int num)
+ {
+ return num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Add(this int num, int value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Subtract(this int num, int value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Multiply(this int num, int value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static int Divide(this int num, int value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static int Abs(this int num)
+ {
+ return Math.Abs(num);
+ }
+
+ ///
+ public static int Clamp(this int num, int min, int max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static int Sign(this int num)
+ {
+ return Math.Sign(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/Int64Fluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/Int64Fluent.cs
new file mode 100644
index 0000000..d8c9297
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/Int64Fluent.cs
@@ -0,0 +1,119 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// IntegerFluent class
+///
+public static class Int64Fluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static decimal ToDecimal(this long num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static float ToSingle(this long num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static double ToDouble(this long num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static short ToInt16(this long num)
+ {
+ return (short)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static int ToInt32(this long num)
+ {
+ return (int)num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static long Add(this long num, long value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static long Subtract(this long num, long value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static long Multiply(this long num, long value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static long Divide(this long num, long value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static long Abs(this long num)
+ {
+ return Math.Abs(num);
+ }
+
+ ///
+ public static long Clamp(this long num, long min, long max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static long Sign(this long num)
+ {
+ return Math.Sign(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/TypeExtentions/SingleFluent.cs b/src/CuteUtils/FluentMath/TypeExtentions/SingleFluent.cs
new file mode 100644
index 0000000..f5d2874
--- /dev/null
+++ b/src/CuteUtils/FluentMath/TypeExtentions/SingleFluent.cs
@@ -0,0 +1,287 @@
+namespace CuteUtils.FluentMath.TypeExtentions;
+
+///
+/// FloatFluent class
+///
+public static class SingleFluent
+{
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static decimal ToDecimal(this float num)
+ {
+ return (decimal)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static double ToDouble(this float num)
+ {
+ return num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static short ToInt16(this float num)
+ {
+ return (short)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static int ToInt32(this float num)
+ {
+ return (int)num;
+ }
+
+ ///
+ /// Converts number to
+ ///
+ ///
+ /// Number as
+ public static long ToInt64(this float num)
+ {
+ return (long)num;
+ }
+
+ ///
+ /// Adds the two nums
+ ///
+ ///
+ ///
+ ///
+ public static float Add(this float num, float value)
+ {
+ return num + value;
+ }
+
+ ///
+ /// Subtracts the two nums
+ ///
+ ///
+ ///
+ ///
+ public static float Subtract(this float num, float value)
+ {
+ return num - value;
+ }
+
+ ///
+ /// Multiples the two nums
+ ///
+ ///
+ ///
+ ///
+ public static float Multiply(this float num, float value)
+ {
+ return num * value;
+ }
+
+ ///
+ /// Divides the two nums
+ ///
+ ///
+ ///
+ ///
+ public static float Divide(this float num, float value)
+ {
+ return num / value;
+ }
+
+ ///
+ public static float Abs(this float num)
+ {
+ return MathF.Abs(num);
+ }
+
+ ///
+ public static float Acos(this float num)
+ {
+ return MathF.Acos(num);
+ }
+
+ ///
+ public static float Acosh(this float num)
+ {
+ return MathF.Acosh(num);
+ }
+
+ ///
+ public static float Asin(this float num)
+ {
+ return MathF.Asin(num);
+ }
+
+ ///
+ public static float Asinh(this float num)
+ {
+ return MathF.Asinh(num);
+ }
+
+ ///
+ public static float Atan(this float num)
+ {
+ return MathF.Atan(num);
+ }
+
+ ///
+ public static float Atan2(this float num, float value)
+ {
+ return MathF.Atan2(num, value);
+ }
+
+ ///
+ public static float Atanh(this float num)
+ {
+ return MathF.Atanh(num);
+ }
+
+ ///
+ public static float Cbrt(this float num)
+ {
+ return MathF.Cbrt(num);
+ }
+
+ ///
+ public static float Ceiling(this float num)
+ {
+ return MathF.Ceiling(num);
+ }
+
+ ///
+ public static float Clamp(this float num, float min, float max)
+ {
+ return Math.Clamp(num, min, max);
+ }
+
+ ///
+ public static float Cos(this float num)
+ {
+ return MathF.Cos(num);
+ }
+
+ ///
+ public static float Cosh(this float num)
+ {
+ return MathF.Cosh(num);
+ }
+
+ ///
+ public static float Exp(this float num)
+ {
+ return MathF.Exp(num);
+ }
+
+ ///
+ public static float Floor(this float num)
+ {
+ return MathF.Floor(num);
+ }
+
+ ///
+ public static float IEEERemainder(this float num, float value)
+ {
+ return MathF.IEEERemainder(num, value);
+ }
+
+ ///
+ public static float Log(this float num)
+ {
+ return MathF.Log(num);
+ }
+
+ ///
+ public static float Log(this float num, float newBase)
+ {
+ return MathF.Log(num, newBase);
+ }
+
+ ///
+ public static float Log10(this float num)
+ {
+ return MathF.Log10(num);
+ }
+
+ ///
+ public static float Pow(this float num, float power)
+ {
+ return MathF.Pow(num, power);
+ }
+
+ ///
+ public static float Round(this float num)
+ {
+ return MathF.Round(num);
+ }
+
+ ///
+ public static float Round(this float num, MidpointRounding mode)
+ {
+ return MathF.Round(num, mode);
+ }
+
+ ///
+ public static float Round(this float num, int digits)
+ {
+ return MathF.Round(num, digits);
+ }
+
+ ///
+ public static float Round(this float num, int digits, MidpointRounding mode)
+ {
+ return MathF.Round(num, digits, mode);
+ }
+
+ ///
+ public static int Sign(this float num)
+ {
+ return MathF.Sign(num);
+ }
+
+ ///
+ public static float Sin(this float num)
+ {
+ return MathF.Sin(num);
+ }
+
+ ///
+ public static float Sinh(this float num)
+ {
+ return MathF.Sinh(num);
+ }
+
+ ///
+ public static float Sqrt(this float num)
+ {
+ return MathF.Sqrt(num);
+ }
+
+ ///
+ public static float Tan(this float num)
+ {
+ return MathF.Tan(num);
+ }
+
+ ///
+ public static float Tanh(this float num)
+ {
+ return MathF.Tanh(num);
+ }
+
+ ///
+ public static float Truncate(this float num)
+ {
+ return MathF.Truncate(num);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/LogConfig.cs b/src/CuteUtils/Logging/LogConfig.cs
new file mode 100644
index 0000000..67306e6
--- /dev/null
+++ b/src/CuteUtils/Logging/LogConfig.cs
@@ -0,0 +1,83 @@
+using Stone_Red_C_Sharp_Utilities.Logging;
+
+using Stone_Red_Utilities.Logging;
+
+namespace CuteUtils.Logging;
+
+///
+/// Logging configuration.
+///
+public class LogConfig
+{
+ ///
+ /// The configuration for messages.
+ ///
+ public OutputConfig DebugConfig { get; set; } = new OutputConfig();
+
+ ///
+ /// The configuration for messages.
+ ///
+ public OutputConfig InfoConfig { get; set; } = new OutputConfig();
+
+ ///
+ /// The configuration for messages.
+ ///
+ public OutputConfig WarnConfig { get; set; } = new OutputConfig();
+
+ ///
+ /// The configuration for messages.
+ ///
+ public OutputConfig ErrorConfig { get; set; } = new OutputConfig();
+
+ ///
+ /// The configuration for messages.
+ ///
+ public OutputConfig FatalConfig { get; set; } = new OutputConfig();
+
+ ///
+ /// The configuration for the message format.
+ ///
+ public FormatConfig FormatConfig { get; set; } = new FormatConfig();
+}
+
+///
+/// Output configuration.
+///
+public class OutputConfig
+{
+ ///
+ /// The console color of the log message.
+ ///
+ public ConsoleColor ConsoleColor { get; set; } = ConsoleColor.White;
+
+ ///
+ /// The target for the log message.
+ ///
+ public LogTarget LogTarget { get; set; } = LogTarget.DebugConsole;
+
+ ///
+ /// The log file path.
+ ///
+ public string FilePath { get; set; } = "log.log";
+}
+
+///
+/// Format configuration.
+///
+public class FormatConfig
+{
+ ///
+ /// The format for the debug console.
+ ///
+ public LogFormatBuilder DebugConsoleFormat { get; set; } = $"{{{LogFormatType.DateTime}:yyyy-MM-dd HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Source},-15}} | {{{LogFormatType.Message}}}";
+
+ ///
+ /// The format for the console.
+ ///
+ public LogFormatBuilder ConsoleFormat { get; set; } = $"{{{LogFormatType.DateTime}:yyyy-MM-dd HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Source},-15}} | {{{LogFormatType.Message}}}";
+
+ ///
+ /// The format for the log file.
+ ///
+ public LogFormatBuilder FileFormat { get; set; } = $"{{{LogFormatType.DateTime}:yyyy-MM-dd HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Source},-15}} | {{{LogFormatType.Message}}}";
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/LogFormatBuilder.cs b/src/CuteUtils/Logging/LogFormatBuilder.cs
new file mode 100644
index 0000000..cfb0cd3
--- /dev/null
+++ b/src/CuteUtils/Logging/LogFormatBuilder.cs
@@ -0,0 +1,147 @@
+using Stone_Red_C_Sharp_Utilities.Logging;
+
+using System.Text;
+
+namespace CuteUtils.Logging;
+
+///
+/// A builder for
+///
+public class LogFormatBuilder
+{
+ private readonly StringBuilder stringBuilder = new StringBuilder();
+
+ ///
+ /// Creates a new instance.
+ ///
+ public LogFormatBuilder()
+ {
+ }
+
+ ///
+ /// Creates a new instance.
+ ///
+ /// The inital format.
+ public LogFormatBuilder(string value)
+ {
+ _ = stringBuilder.Append(value);
+ }
+
+ ///
+ /// Converts the />
+ ///
+ /// The to convert.
+ public static implicit operator string(LogFormatBuilder value)
+ {
+ return value.stringBuilder.ToString();
+ }
+
+ ///
+ /// Converts the />
+ ///
+ /// The to convert.
+ public static implicit operator LogFormatBuilder(string value)
+ {
+ return new LogFormatBuilder(value);
+ }
+
+ ///
+ /// Appends text to the log format.
+ ///
+ /// The text to append.
+ /// A reference to this instance.
+ public LogFormatBuilder Text(string value)
+ {
+ _ = stringBuilder.Append(value);
+ return this;
+ }
+
+ ///
+ /// Appends the log datie time to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder DateTime(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.DateTime},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the log severity to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder LogSeverity(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.LogSeverity},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the line number to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder LineNumber(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.LineNumber},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the file path to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder FilePath(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.FilePath},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the log source to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder MemberName(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.MemberName},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the log source to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder Source(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.Source},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ ///
+ /// Appends the log message to the log format.
+ ///
+ /// The format to apply.
+ /// The padding to apply.
+ /// A reference to this instance.
+ public LogFormatBuilder Message(string format = "", int padding = 0)
+ {
+ _ = stringBuilder.Append($"{{{LogFormatType.Message},{padding}{GetFormat(format)}}}");
+ return this;
+ }
+
+ private static string GetFormat(string format)
+ {
+ return string.IsNullOrWhiteSpace(format) ? string.Empty : $":{format}";
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/LogFormatType.cs b/src/CuteUtils/Logging/LogFormatType.cs
new file mode 100644
index 0000000..44c3e0a
--- /dev/null
+++ b/src/CuteUtils/Logging/LogFormatType.cs
@@ -0,0 +1,42 @@
+namespace CuteUtils.Logging;
+
+///
+/// Specifies the info type of the log message format.
+///
+public static class LogFormatType
+{
+ ///
+ /// The of the log message.
+ ///
+ public const string DateTime = "";
+
+ ///
+ /// The of the log message.
+ ///
+ public const string LogSeverity = "";
+
+ ///
+ /// The line number of the log message.
+ ///
+ public const string LineNumber = "";
+
+ ///
+ /// The file path of the log message.
+ ///
+ public const string FilePath = "";
+
+ ///
+ /// The member name of the log message.
+ ///
+ public const string MemberName = "";
+
+ ///
+ /// The source of the log message.
+ ///
+ public const string Source = "";
+
+ ///
+ /// The message of the log message.
+ ///
+ public const string Message = "";
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/LogSeverity.cs b/src/CuteUtils/Logging/LogSeverity.cs
new file mode 100644
index 0000000..db59e64
--- /dev/null
+++ b/src/CuteUtils/Logging/LogSeverity.cs
@@ -0,0 +1,32 @@
+namespace CuteUtils.Logging;
+
+///
+/// Specifies the severity of the log message.
+///
+public enum LogSeverity
+{
+ ///
+ /// Logs that contain the most detailed messages.
+ ///
+ Debug,
+
+ ///
+ /// Logs that track the general flow of the application.
+ ///
+ Info,
+
+ ///
+ /// Logs that highlight an abnormal activity in the flow of execution.
+ ///
+ Warn,
+
+ ///
+ /// Logs that highlight when the flow of execution is stopped due to a failure.
+ ///
+ Error,
+
+ ///
+ /// Logs that contain the most severe level of error. This type of error indicate that immediate attention may be required.
+ ///
+ Fatal
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/LogTarget.cs b/src/CuteUtils/Logging/LogTarget.cs
new file mode 100644
index 0000000..3ac1325
--- /dev/null
+++ b/src/CuteUtils/Logging/LogTarget.cs
@@ -0,0 +1,23 @@
+namespace CuteUtils.Logging;
+
+///
+/// Specifies the target of the log message.
+///
+[Flags]
+public enum LogTarget
+{
+ ///
+ /// Writes log to console
+ ///
+ Console = 1,
+
+ ///
+ /// Writes log to debug console
+ ///
+ DebugConsole = 2,
+
+ ///
+ /// Writes log to file
+ ///
+ File = 3
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/Logger.cs b/src/CuteUtils/Logging/Logger.cs
new file mode 100644
index 0000000..7ff58f9
--- /dev/null
+++ b/src/CuteUtils/Logging/Logger.cs
@@ -0,0 +1,278 @@
+using Stone_Red_C_Sharp_Utilities;
+
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace CuteUtils.Logging;
+
+///
+/// Class used for logging
+///
+public class Logger
+{
+ ///
+ /// The logging configuration.
+ ///
+ public LogConfig Config { get; init; } = new LogConfig();
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Log(string message, string source, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, logSeverity, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Log(string message, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, logSeverity, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogInfo(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, LogSeverity.Info, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogInfo(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, LogSeverity.Info, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogWarn(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, LogSeverity.Warn, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogWarn(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, LogSeverity.Warn, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogError(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, LogSeverity.Error, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogError(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, LogSeverity.Error, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogFatal(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, LogSeverity.Fatal, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogFatal(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, LogSeverity.Fatal, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogDebug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, string.Empty, LogSeverity.Debug, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogDebug(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ WriteLog(message, source, LogSeverity.Debug, memberName, sourceFilePath, sourceLineNumber);
+ }
+
+ ///
+ /// Log the message to the specified output if the condition is met
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogIf(bool condition, string message, string source, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ if (condition)
+ {
+ WriteLog(message, source, logSeverity, memberName, sourceFilePath, sourceLineNumber);
+ }
+ }
+
+ ///
+ /// Log the message to the specified output if the condition is met
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void LogIf(bool condition, string message, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
+ {
+ if (condition)
+ {
+ WriteLog(message, string.Empty, logSeverity, memberName, sourceFilePath, sourceLineNumber);
+ }
+ }
+
+ ///
+ /// Clears the log file
+ ///
+ public void ClearLogFile(LogSeverity logSeverity)
+ {
+ OutputConfig outputConfig = GetOutputConfig(logSeverity);
+
+ lock (outputConfig)
+ {
+ if (File.Exists(outputConfig.FilePath))
+ {
+ File.WriteAllText(outputConfig.FilePath, string.Empty);
+ }
+ }
+ }
+
+ private static string GetFormattedString(string format, LogSeverity logSeverity, string source, string message, string memberName, string sourceFilePath, int sourceLineNumber)
+ {
+ format = format
+ .Replace(LogFormatType.DateTime, "0")
+ .Replace(LogFormatType.LogSeverity, "1")
+ .Replace(LogFormatType.LineNumber, "2")
+ .Replace(LogFormatType.FilePath, "3")
+ .Replace(LogFormatType.MemberName, "4")
+ .Replace(LogFormatType.Source, "5")
+ .Replace(LogFormatType.Message, "6");
+
+ return string.Format(format, DateTime.Now, logSeverity.ToString().ToUpper(), sourceLineNumber, sourceFilePath, memberName, source, message);
+ }
+
+ private void WriteLog(string message, string source, LogSeverity logSeverity, string memberName = "", string sourceFilePath = "", int sourceLineNumber = 0)
+ {
+ string consoleOutput = GetFormattedString(Config.FormatConfig.ConsoleFormat, logSeverity, source, message, memberName, sourceFilePath, sourceLineNumber);
+ string debugOutput = GetFormattedString(Config.FormatConfig.DebugConsoleFormat, logSeverity, source, message, memberName, sourceFilePath, sourceLineNumber);
+ string fileOutput = GetFormattedString(Config.FormatConfig.FileFormat, logSeverity, source, message, memberName, sourceFilePath, sourceLineNumber);
+
+ OutputConfig outputConfig = GetOutputConfig(logSeverity);
+
+ if ((outputConfig.LogTarget & LogTarget.Console) == LogTarget.Console)
+ {
+ ConsoleExt.WriteLine(consoleOutput, outputConfig.ConsoleColor);
+ }
+
+ if ((outputConfig.LogTarget & LogTarget.DebugConsole) == LogTarget.DebugConsole)
+ {
+ Trace.WriteLine(debugOutput);
+ }
+
+ lock (outputConfig)
+ {
+ if ((outputConfig.LogTarget & LogTarget.File) == LogTarget.File)
+ {
+ if (!File.Exists(outputConfig.FilePath))
+ {
+ File.Create(outputConfig.FilePath).Close();
+ }
+
+ File.AppendAllLines(outputConfig.FilePath, [fileOutput]);
+ }
+ }
+ }
+
+ private OutputConfig GetOutputConfig(LogSeverity logSeverity)
+ {
+ return logSeverity switch
+ {
+ LogSeverity.Fatal => Config.FatalConfig,
+ LogSeverity.Error => Config.ErrorConfig,
+ LogSeverity.Warn => Config.WarnConfig,
+ LogSeverity.Info => Config.InfoConfig,
+ _ => Config.DebugConfig
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/RandomExtentions.cs b/src/CuteUtils/RandomExtentions.cs
new file mode 100644
index 0000000..c8922a6
--- /dev/null
+++ b/src/CuteUtils/RandomExtentions.cs
@@ -0,0 +1,30 @@
+namespace CuteUtils;
+
+///
+/// Extensions
+///
+public static class RandomExt
+{
+ public static T NextItem(this Random random, IEnumerable enumerable)
+ {
+ ArgumentNullException.ThrowIfNull(enumerable);
+
+ return enumerable.ElementAt(random.Next(enumerable.Count()));
+ }
+
+ public static bool NextBool(this Random random)
+ {
+ return random.Next(2) == 0;
+ }
+
+ public static T NextEnum(this Random random) where T : struct, Enum
+ {
+ T[] values = Enum.GetValues();
+ return values[random.Next(values.Length)];
+ }
+
+ public static T NextEnum(this Random random, T[] values) where T : struct, Enum
+ {
+ return values[random.Next(values.Length)];
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Reflection.cs b/src/CuteUtils/Reflection.cs
new file mode 100644
index 0000000..a0ab95d
--- /dev/null
+++ b/src/CuteUtils/Reflection.cs
@@ -0,0 +1,60 @@
+using System.Reflection;
+
+namespace CuteUtils;
+
+///
+/// Reflection class
+///
+public static class Reflection
+{
+ ///
+ /// Copies all properties of an object to a new one.
+ ///
+ ///
+ ///
+ ///
+ public static T CopyProperties(this object obj) where T : new()
+ {
+ T newObj = new T();
+
+ Type objType = obj.GetType();
+ Type newObjType = newObj.GetType();
+
+ foreach (PropertyInfo propertyInfo in objType.GetProperties())
+ {
+ PropertyInfo? newObjPropertyInfo = newObjType.GetProperty(propertyInfo.Name);
+ if (newObjPropertyInfo is not null && newObjPropertyInfo.PropertyType.IsAssignableFrom(propertyInfo.PropertyType))
+ {
+ newObjPropertyInfo.SetValue(newObj, propertyInfo.GetValue(obj));
+ }
+ }
+
+ return newObj;
+ }
+
+ ///
+ /// Copies all properties of an object to a different one.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static T CopyProperties(this object obj, T newObj)
+ {
+ ArgumentNullException.ThrowIfNull(newObj);
+
+ Type objType = obj.GetType();
+ Type newObjType = newObj.GetType();
+
+ foreach (PropertyInfo propertyInfo in objType.GetProperties())
+ {
+ PropertyInfo? newObjPropertyInfo = newObjType.GetProperty(propertyInfo.Name);
+ if (newObjPropertyInfo is not null && newObjPropertyInfo.PropertyType.IsAssignableFrom(propertyInfo.PropertyType))
+ {
+ newObjPropertyInfo.SetValue(newObj, propertyInfo.GetValue(obj));
+ }
+ }
+
+ return newObj;
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/StringExtentions.cs b/src/CuteUtils/StringExtentions.cs
new file mode 100644
index 0000000..ca82ea2
--- /dev/null
+++ b/src/CuteUtils/StringExtentions.cs
@@ -0,0 +1,169 @@
+using System.Globalization;
+using System.Text;
+
+namespace CuteUtils;
+
+///
+/// Extensions
+///
+public static class StringExt
+{
+ ///
+ /// Removes all invalid chars from the specified
+ ///
+ ///
+ ///
+ ///
+ public static string ToFileName(this string str, bool allowSpaces = false)
+ {
+ char[] invalidChars = Path.GetInvalidFileNameChars();
+
+ if (!allowSpaces)
+ {
+ str = str.Replace(" ", string.Empty);
+ }
+
+ foreach (char item in invalidChars)
+ {
+ str = str.Replace(item.ToString(), string.Empty);
+ }
+
+ string normalizedString = str.Normalize(NormalizationForm.FormD);
+ StringBuilder stringBuilder = new StringBuilder();
+
+ foreach (char c in normalizedString)
+ {
+ UnicodeCategory unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
+ if (unicodeCategory != UnicodeCategory.NonSpacingMark)
+ {
+ _ = stringBuilder.Append(c);
+ }
+ }
+
+ return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
+ }
+
+ ///
+ /// Removes all invalid chars from the specified
+ ///
+ ///
+ ///
+ ///
+ public static string ToPath(this string str, bool allowSpaces = false)
+ {
+ char[] invalidChars = Path.GetInvalidPathChars();
+
+ if (!allowSpaces)
+ {
+ str = str.Replace(" ", string.Empty);
+ }
+
+ foreach (char item in invalidChars)
+ {
+ str = str.Replace(item.ToString(), string.Empty);
+ }
+
+ string normalizedString = str.Normalize(NormalizationForm.FormD);
+ StringBuilder stringBuilder = new StringBuilder();
+
+ foreach (char c in normalizedString)
+ {
+ UnicodeCategory unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
+ if (unicodeCategory != UnicodeCategory.NonSpacingMark)
+ {
+ _ = stringBuilder.Append(c);
+ }
+ }
+
+ return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
+ }
+
+ ///
+ /// Truncates a to the specified length.
+ ///
+ ///
+ ///
+ ///
+ public static string Truncate(this string str, int length)
+ {
+ if (str.Length > length && length > 0)
+ {
+ return str[..length];
+ }
+
+ return str;
+ }
+
+ ///
+ /// Truncates a to the specified length.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string Truncate(this string str, int length, bool ellipsis)
+ {
+ if (str.Length > length && length > 0)
+ {
+ if (ellipsis && length > 3)
+ {
+ return $"{str[..(length - 3)]}...";
+ }
+ else
+ {
+ return str[..length];
+ }
+ }
+
+ return str;
+ }
+
+ ///
+ /// Uses the correct newline defined for this environment.
+ ///
+ ///
+ ///
+ public static string CorrectNewLine(this string str)
+ {
+ if (Environment.OSVersion.Platform == PlatformID.Unix)
+ {
+ str = str.Replace("\r\n", "\n");
+ }
+ else
+ {
+ str = str.Replace("\n", "\r\n"); //Ik that this can produce wrong results
+ }
+
+ return str;
+ }
+
+ ///
+ /// Removes all white spaces from the specified
+ ///
+ ///
+ ///
+ public static string RemoveWhitespaces(this string str)
+ {
+ StringBuilder result = new StringBuilder();
+ foreach (char c in str)
+ {
+ if (!char.IsWhiteSpace(c))
+ {
+ _ = result.Append(c);
+ }
+ }
+ return result.ToString();
+ }
+
+ ///
+ /// Reverses the specified
+ ///
+ ///
+ ///
+ public static string Reverse(this string str)
+ {
+ char[] array = str.ToCharArray();
+ Array.Reverse(array);
+ return new string(array);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Tasks/BlockingTaskQueue.cs b/src/CuteUtils/Tasks/BlockingTaskQueue.cs
new file mode 100644
index 0000000..5a2ce71
--- /dev/null
+++ b/src/CuteUtils/Tasks/BlockingTaskQueue.cs
@@ -0,0 +1,91 @@
+namespace CuteUtils.Tasks;
+
+///
+/// Represents a blocking task queue that allows enqueueing tasks and functions.
+///
+public class BlockingTaskQueue
+{
+ private readonly SemaphoreSlim semaphore;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public BlockingTaskQueue()
+ {
+ semaphore = new SemaphoreSlim(1);
+ }
+
+ ///
+ /// Enqueues a task that returns a value.
+ ///
+ /// The type of the return value.
+ /// The function to execute.
+ /// A task representing the asynchronous operation.
+ public async Task Enqueue(Func function)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ return await Task.Run(function);
+ }
+ finally
+ {
+ _ = semaphore.Release();
+ }
+ }
+
+ ///
+ /// Enqueues a task that does not return a value.
+ ///
+ /// The action to execute.
+ /// A task representing the asynchronous operation.
+ public async Task Enqueue(Action function)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ await Task.Run(function);
+ }
+ finally
+ {
+ _ = semaphore.Release();
+ }
+ }
+
+ ///
+ /// Enqueues a task.
+ ///
+ /// The task to enqueue.
+ /// A task representing the asynchronous operation.
+ public async Task Enqueue(Task task)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ await task;
+ }
+ finally
+ {
+ _ = semaphore.Release();
+ }
+ }
+
+ ///
+ /// Enqueues a task that returns a value.
+ ///
+ /// The type of the return value.
+ /// The task to enqueue.
+ /// A task representing the asynchronous operation.
+ public async Task Enqueue(Task task)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ return await task;
+ }
+ finally
+ {
+ _ = semaphore.Release();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Tasks/TaskQueue.cs b/src/CuteUtils/Tasks/TaskQueue.cs
new file mode 100644
index 0000000..919852b
--- /dev/null
+++ b/src/CuteUtils/Tasks/TaskQueue.cs
@@ -0,0 +1,134 @@
+using System.Collections.Concurrent;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+
+namespace CuteUtils.Tasks;
+
+///
+/// Represents a queue of tasks that can be enqueued and processed asynchronously.
+///
+public class TaskQueue : IDisposable
+{
+ private readonly BlockingCollection<(Task Task, Action Callback)> tasks = [];
+ private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
+ private bool processing = false;
+ private bool disposed;
+
+ ///
+ /// Enqueues a task that returns a value.
+ ///
+ /// The type of the value returned by the task.
+ /// The function representing the task.
+ /// An observable that emits the task when it completes.
+ public IObservable> Enqueue(Func function)
+ {
+ Subject> subject = new Subject>();
+ Task task = new Task(function);
+
+ tasks.Add((task, () => subject.OnNext(task)));
+
+ ProcessTasks();
+
+ return subject.AsObservable();
+ }
+
+ ///
+ /// Enqueues a task that does not return a value.
+ ///
+ /// The action representing the task.
+ /// An observable that emits the task when it completes.
+ public IObservable Enqueue(Action function)
+ {
+ Subject subject = new Subject();
+ Task task = new Task(function);
+
+ tasks.Add((task, () => subject.OnNext(task)));
+
+ ProcessTasks();
+
+ return subject.AsObservable();
+ }
+
+ ///
+ /// Enqueues a pre-created task.
+ ///
+ /// The task to enqueue.
+ /// An observable that emits the task when it completes.
+ public IObservable Enqueue(Task task)
+ {
+ Subject subject = new Subject();
+
+ tasks.Add((task, () => subject.OnNext(task)));
+
+ ProcessTasks();
+
+ return subject.AsObservable();
+ }
+
+ ///
+ /// Enqueues a pre-created task that returns a value.
+ ///
+ /// The type of the value returned by the task.
+ /// The task to enqueue.
+ /// An observable that emits the task when it completes.
+ public IObservable> Enqueue(Task task)
+ {
+ Subject> subject = new Subject>();
+
+ tasks.Add((task, () => subject.OnNext(task)));
+
+ ProcessTasks();
+
+ return subject.AsObservable();
+ }
+
+ ///
+ /// Disposes the task queue and cancels any pending tasks.
+ ///
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ cancellationTokenSource.Dispose();
+ tasks.Dispose();
+ }
+
+ disposed = true;
+ }
+ }
+
+ private void ProcessTasks()
+ {
+ if (processing)
+ {
+ return;
+ }
+
+ processing = true;
+
+ _ = new TaskFactory().StartNew(async () =>
+ {
+ while (!disposed)
+ {
+ (Task Task, Action Callback) container = tasks.Take(cancellationTokenSource.Token);
+
+ if (container.Task.Status == TaskStatus.Created)
+ {
+ container.Task.Start();
+ }
+
+ await container.Task.WaitAsync(cancellationTokenSource.Token);
+ container.Callback?.Invoke();
+ }
+ }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }
+}
\ No newline at end of file
From 09512ef6db3a3151349ceba961c8325fd2386d88 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Mon, 18 Mar 2024 12:22:36 +0100
Subject: [PATCH 02/12] Add DynDto and minor improvements
---
src/CuteUtils.Tests/CuteUtils.Tests.csproj | 27 +++++
src/CuteUtils.Tests/UnitTest1.cs | 65 +++++++++++
src/CuteUtils.sln | 8 +-
src/CuteUtils/BoolExtentions.cs | 16 +--
src/CuteUtils/CuteUtils.csproj | 4 +
src/CuteUtils/Logging/LogConfig.cs | 6 +-
src/CuteUtils/Logging/LogFormatBuilder.cs | 4 +-
src/CuteUtils/Logging/Logger.cs | 4 +-
src/CuteUtils/Reflection/DynDto.cs | 105 ++++++++++++++++++
.../Reflection/DynDtoNameAttribute.cs | 6 +
.../ReflectionExtentions.cs} | 4 +-
11 files changed, 227 insertions(+), 22 deletions(-)
create mode 100644 src/CuteUtils.Tests/CuteUtils.Tests.csproj
create mode 100644 src/CuteUtils.Tests/UnitTest1.cs
create mode 100644 src/CuteUtils/Reflection/DynDto.cs
create mode 100644 src/CuteUtils/Reflection/DynDtoNameAttribute.cs
rename src/CuteUtils/{Reflection.cs => Reflection/ReflectionExtentions.cs} (96%)
diff --git a/src/CuteUtils.Tests/CuteUtils.Tests.csproj b/src/CuteUtils.Tests/CuteUtils.Tests.csproj
new file mode 100644
index 0000000..95dadc8
--- /dev/null
+++ b/src/CuteUtils.Tests/CuteUtils.Tests.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CuteUtils.Tests/UnitTest1.cs b/src/CuteUtils.Tests/UnitTest1.cs
new file mode 100644
index 0000000..9207c72
--- /dev/null
+++ b/src/CuteUtils.Tests/UnitTest1.cs
@@ -0,0 +1,65 @@
+using CuteUtils.Reflection;
+
+using System.Dynamic;
+
+namespace CuteUtils.Tests;
+
+[TestClass]
+public class UnitTest1
+{
+ [TestMethod]
+ public void TestMethod1()
+ {
+ TestModel testModel = new()
+ {
+ Id = 13,
+ Name = "test",
+ Value = (15, "test"),
+ };
+
+ ExpandoObject dto = testModel.ToDto();
+
+ Assert.IsNotNull(dto);
+
+ Assert.IsFalse(dto.Any(p => p.Key == "Id"));
+ Assert.IsTrue(dto.Any(p => p.Key == "Name"));
+ Assert.IsTrue(dto.Any(p => p.Key == "Value"));
+ }
+
+ [TestMethod]
+ public void TestMethod2()
+ {
+ TestModel testModel = new()
+ {
+ Id = 13,
+ Name = "test",
+ Value = (15, "test"),
+ };
+
+ TestDto dto = testModel.ToDto();
+
+ Assert.IsNotNull(dto);
+
+ Assert.IsTrue(dto.Id != 0);
+ Assert.IsTrue(dto.Name is not null);
+ Assert.IsTrue(dto.Value is not null);
+ }
+
+ private class TestModel
+ {
+ public required int Id { get; set; }
+
+ [DynDtoName(nameof(Name))]
+ public required string Name { get; set; }
+
+ //[DynDtoName(nameof(Value))]
+ public required object Value { get; set; }
+ }
+
+ private class TestDto
+ {
+ public int Id { get; set; } = 0;
+ public string Name { get; set; } = string.Empty;
+ public object Value { get; set; } = (15, "test");
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils.sln b/src/CuteUtils.sln
index 5914960..53b2187 100644
--- a/src/CuteUtils.sln
+++ b/src/CuteUtils.sln
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34622.214
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CuteUtils", "CuteUtils\CuteUtils.csproj", "{D640F3B6-2B09-496D-88D6-3CF57559845D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CuteUtils", "CuteUtils\CuteUtils.csproj", "{D640F3B6-2B09-496D-88D6-3CF57559845D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CuteUtils.Tests", "CuteUtils.Tests\CuteUtils.Tests.csproj", "{1468822C-92E4-4C44-93F6-DE71930F7C96}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1468822C-92E4-4C44-93F6-DE71930F7C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1468822C-92E4-4C44-93F6-DE71930F7C96}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1468822C-92E4-4C44-93F6-DE71930F7C96}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1468822C-92E4-4C44-93F6-DE71930F7C96}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/CuteUtils/BoolExtentions.cs b/src/CuteUtils/BoolExtentions.cs
index 93a9d24..71e8819 100644
--- a/src/CuteUtils/BoolExtentions.cs
+++ b/src/CuteUtils/BoolExtentions.cs
@@ -8,26 +8,26 @@ public static class BoolExt
///
/// Sets value to true if input is true. If input is false the value will not change.
///
- ///
+ ///
///
- public static void OneWayTrue(this ref bool bol, bool input)
+ public static void OneWayTrue(this ref bool value, bool input)
{
- if (!bol && input)
+ if (!value && input)
{
- bol = true;
+ value = true;
}
}
///
/// Sets value to false if input is false. If input is true the value will not change.
///
- ///
+ ///
///
- public static void OneWayFalse(this ref bool bol, bool input)
+ public static void OneWayFalse(this ref bool value, bool input)
{
- if (bol && !input)
+ if (value && !input)
{
- bol = false;
+ value = false;
}
}
diff --git a/src/CuteUtils/CuteUtils.csproj b/src/CuteUtils/CuteUtils.csproj
index fa71b7a..b4ef780 100644
--- a/src/CuteUtils/CuteUtils.csproj
+++ b/src/CuteUtils/CuteUtils.csproj
@@ -6,4 +6,8 @@
enable
+
+
+
+
diff --git a/src/CuteUtils/Logging/LogConfig.cs b/src/CuteUtils/Logging/LogConfig.cs
index 67306e6..cb7276b 100644
--- a/src/CuteUtils/Logging/LogConfig.cs
+++ b/src/CuteUtils/Logging/LogConfig.cs
@@ -1,8 +1,4 @@
-using Stone_Red_C_Sharp_Utilities.Logging;
-
-using Stone_Red_Utilities.Logging;
-
-namespace CuteUtils.Logging;
+namespace CuteUtils.Logging;
///
/// Logging configuration.
diff --git a/src/CuteUtils/Logging/LogFormatBuilder.cs b/src/CuteUtils/Logging/LogFormatBuilder.cs
index cfb0cd3..5ae36b1 100644
--- a/src/CuteUtils/Logging/LogFormatBuilder.cs
+++ b/src/CuteUtils/Logging/LogFormatBuilder.cs
@@ -1,6 +1,4 @@
-using Stone_Red_C_Sharp_Utilities.Logging;
-
-using System.Text;
+using System.Text;
namespace CuteUtils.Logging;
diff --git a/src/CuteUtils/Logging/Logger.cs b/src/CuteUtils/Logging/Logger.cs
index 7ff58f9..73f13b3 100644
--- a/src/CuteUtils/Logging/Logger.cs
+++ b/src/CuteUtils/Logging/Logger.cs
@@ -1,6 +1,4 @@
-using Stone_Red_C_Sharp_Utilities;
-
-using System.Diagnostics;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace CuteUtils.Logging;
diff --git a/src/CuteUtils/Reflection/DynDto.cs b/src/CuteUtils/Reflection/DynDto.cs
new file mode 100644
index 0000000..606ce6a
--- /dev/null
+++ b/src/CuteUtils/Reflection/DynDto.cs
@@ -0,0 +1,105 @@
+using System.Dynamic;
+using System.Reflection;
+
+namespace CuteUtils.Reflection;
+public static class DynDto
+{
+ public static ExpandoObject ToDto(this object data)
+ {
+ ExpandoObject dto = new ExpandoObject();
+
+ PropertyInfo[] properties = data.GetType().GetProperties();
+
+ foreach (PropertyInfo property in properties)
+ {
+ DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute();
+
+ if (dynDtoNameAttribute is not null)
+ {
+ _ = dto.TryAdd(dynDtoNameAttribute.Name, property.GetValue(data));
+ }
+ }
+
+ return dto;
+ }
+
+ public static T ToDto(this object data, T dto)
+ {
+ PropertyInfo[] dataProperties = data.GetType().GetProperties();
+ PropertyInfo[] dtoProperties = data.GetType().GetProperties();
+
+ foreach (PropertyInfo dataProperty in dataProperties)
+ {
+ DynDtoNameAttribute? dynDtoNameAttribute = dataProperty.GetCustomAttribute();
+ PropertyInfo? dtoPropertyInfo = Array.Find(dtoProperties, p => p.Name == dynDtoNameAttribute?.Name);
+
+ if (dynDtoNameAttribute is not null && dtoPropertyInfo is not null)
+ {
+ object? value = dataProperty.GetValue(data);
+ dtoPropertyInfo.SetValue(dto, value);
+ }
+ }
+
+ return dto;
+ }
+
+ public static T ToDto(this object data) where T : new()
+ {
+ return ToDto(data, new T());
+ }
+
+ public static T FromDto(this object dto, T data)
+ {
+ ArgumentNullException.ThrowIfNull(data);
+
+ PropertyInfo[] dataProperties = data.GetType().GetProperties();
+ PropertyInfo[] dtoProperties = dto.GetType().GetProperties();
+
+ foreach (PropertyInfo property in dataProperties)
+ {
+ DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute();
+ if (dynDtoNameAttribute is not null)
+ {
+ PropertyInfo? propertyInfo = Array.Find(dtoProperties, x => x.Name == dynDtoNameAttribute.Name);
+
+ if (propertyInfo is not null)
+ {
+ property.SetValue(data, propertyInfo.GetValue(dto));
+ }
+ }
+ }
+
+ return data;
+ }
+
+ public static T FromDto(this ExpandoObject dto, T data)
+ {
+ ArgumentNullException.ThrowIfNull(dto);
+ ArgumentNullException.ThrowIfNull(data);
+
+ IDictionary dtoProperties = dto!;
+
+ PropertyInfo[] dataProperties = data.GetType().GetProperties();
+
+ foreach (PropertyInfo property in dataProperties)
+ {
+ DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute();
+ if (dynDtoNameAttribute is not null && dtoProperties.TryGetValue(dynDtoNameAttribute.Name, out object? value))
+ {
+ property.SetValue(data, value);
+ }
+ }
+
+ return data;
+ }
+
+ public static T FromDto(this object dto) where T : new()
+ {
+ return FromDto(dto, new T());
+ }
+
+ public static T FromDto(this ExpandoObject dto) where T : new()
+ {
+ return FromDto(dto, new T());
+ }
+}
diff --git a/src/CuteUtils/Reflection/DynDtoNameAttribute.cs b/src/CuteUtils/Reflection/DynDtoNameAttribute.cs
new file mode 100644
index 0000000..475350f
--- /dev/null
+++ b/src/CuteUtils/Reflection/DynDtoNameAttribute.cs
@@ -0,0 +1,6 @@
+namespace CuteUtils.Reflection;
+[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
+public class DynDtoNameAttribute(string name) : Attribute
+{
+ public string Name { get; set; } = name;
+}
diff --git a/src/CuteUtils/Reflection.cs b/src/CuteUtils/Reflection/ReflectionExtentions.cs
similarity index 96%
rename from src/CuteUtils/Reflection.cs
rename to src/CuteUtils/Reflection/ReflectionExtentions.cs
index a0ab95d..8459a45 100644
--- a/src/CuteUtils/Reflection.cs
+++ b/src/CuteUtils/Reflection/ReflectionExtentions.cs
@@ -1,11 +1,11 @@
using System.Reflection;
-namespace CuteUtils;
+namespace CuteUtils.Reflection;
///
/// Reflection class
///
-public static class Reflection
+public static class ReflectionExtentions
{
///
/// Copies all properties of an object to a new one.
From 5269a8d56de9884a824e7a4c84224e57f8255724 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Mon, 18 Mar 2024 18:05:27 +0100
Subject: [PATCH 03/12] Fix DynDto
---
.../{UnitTest1.cs => DynDtoTests.cs} | 18 +++++++++---------
src/CuteUtils/Reflection/DynDto.cs | 7 +++++--
2 files changed, 14 insertions(+), 11 deletions(-)
rename src/CuteUtils.Tests/{UnitTest1.cs => DynDtoTests.cs} (72%)
diff --git a/src/CuteUtils.Tests/UnitTest1.cs b/src/CuteUtils.Tests/DynDtoTests.cs
similarity index 72%
rename from src/CuteUtils.Tests/UnitTest1.cs
rename to src/CuteUtils.Tests/DynDtoTests.cs
index 9207c72..6140ffb 100644
--- a/src/CuteUtils.Tests/UnitTest1.cs
+++ b/src/CuteUtils.Tests/DynDtoTests.cs
@@ -5,10 +5,10 @@ using System.Dynamic;
namespace CuteUtils.Tests;
[TestClass]
-public class UnitTest1
+public class DynDtoTests
{
[TestMethod]
- public void TestMethod1()
+ public void Convert_ToDto_ReturnsExpandoObject()
{
TestModel testModel = new()
{
@@ -27,7 +27,7 @@ public class UnitTest1
}
[TestMethod]
- public void TestMethod2()
+ public void Convert_ToDto_ReturnsGeneric()
{
TestModel testModel = new()
{
@@ -40,9 +40,9 @@ public class UnitTest1
Assert.IsNotNull(dto);
- Assert.IsTrue(dto.Id != 0);
- Assert.IsTrue(dto.Name is not null);
- Assert.IsTrue(dto.Value is not null);
+ Assert.IsTrue(dto.Id == 0);
+ Assert.IsTrue(!string.IsNullOrWhiteSpace(dto.Name));
+ Assert.IsTrue(dto.Value is not (0, ""));
}
private class TestModel
@@ -52,14 +52,14 @@ public class UnitTest1
[DynDtoName(nameof(Name))]
public required string Name { get; set; }
- //[DynDtoName(nameof(Value))]
+ [DynDtoName(nameof(Value))]
public required object Value { get; set; }
}
private class TestDto
{
- public int Id { get; set; } = 0;
+ public int Id { get; init; } = 0;
public string Name { get; set; } = string.Empty;
- public object Value { get; set; } = (15, "test");
+ public object Value { get; init; } = (0, string.Empty);
}
}
\ No newline at end of file
diff --git a/src/CuteUtils/Reflection/DynDto.cs b/src/CuteUtils/Reflection/DynDto.cs
index 606ce6a..8f3c883 100644
--- a/src/CuteUtils/Reflection/DynDto.cs
+++ b/src/CuteUtils/Reflection/DynDto.cs
@@ -2,6 +2,7 @@
using System.Reflection;
namespace CuteUtils.Reflection;
+
public static class DynDto
{
public static ExpandoObject ToDto(this object data)
@@ -25,8 +26,10 @@ public static class DynDto
public static T ToDto(this object data, T dto)
{
+ ArgumentNullException.ThrowIfNull(dto);
+
PropertyInfo[] dataProperties = data.GetType().GetProperties();
- PropertyInfo[] dtoProperties = data.GetType().GetProperties();
+ PropertyInfo[] dtoProperties = dto.GetType().GetProperties();
foreach (PropertyInfo dataProperty in dataProperties)
{
@@ -102,4 +105,4 @@ public static class DynDto
{
return FromDto(dto, new T());
}
-}
+}
\ No newline at end of file
From 80b5cc51094661fc7c64905cb3140bffedfd2c31 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Mon, 18 Mar 2024 22:09:29 +0100
Subject: [PATCH 04/12] Add more shapes
---
src/CuteUtils/FluentMath/Shapes/Circle.cs | 12 +++++++
src/CuteUtils/FluentMath/Shapes/Ellipse.cs | 12 +++++++
src/CuteUtils/FluentMath/Shapes/Rectangle.cs | 27 ++++++++-------
src/CuteUtils/FluentMath/Shapes/Triangle.cs | 35 ++++++++++++++++++++
4 files changed, 72 insertions(+), 14 deletions(-)
create mode 100644 src/CuteUtils/FluentMath/Shapes/Circle.cs
create mode 100644 src/CuteUtils/FluentMath/Shapes/Ellipse.cs
create mode 100644 src/CuteUtils/FluentMath/Shapes/Triangle.cs
diff --git a/src/CuteUtils/FluentMath/Shapes/Circle.cs b/src/CuteUtils/FluentMath/Shapes/Circle.cs
new file mode 100644
index 0000000..bb9d3c3
--- /dev/null
+++ b/src/CuteUtils/FluentMath/Shapes/Circle.cs
@@ -0,0 +1,12 @@
+namespace CuteUtils.FluentMath.Shapes;
+
+public class Circle(double radius)
+{
+ public double Radius { get; set; } = radius;
+
+ public double Diameter => Radius * 2;
+
+ public double Circumference => 2 * Math.PI * Radius;
+
+ public double Area => Math.PI * Math.Pow(Radius, 2);
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Ellipse.cs b/src/CuteUtils/FluentMath/Shapes/Ellipse.cs
new file mode 100644
index 0000000..e4963ab
--- /dev/null
+++ b/src/CuteUtils/FluentMath/Shapes/Ellipse.cs
@@ -0,0 +1,12 @@
+namespace CuteUtils.FluentMath.Shapes;
+
+public class Ellipse(double majorAxis, double minorAxis)
+{
+ public double MajorAxis { get; set; } = majorAxis;
+ public double MinorAxis { get; set; } = minorAxis;
+
+ public double Area => Math.PI * MajorAxis * MinorAxis;
+ public double Circumference => Math.PI * ((3 * (MajorAxis + MinorAxis)) - Math.Sqrt(((3 * MajorAxis) + MinorAxis) * (MajorAxis + (3 * MinorAxis))));
+
+ public bool IsCircle => MajorAxis == MinorAxis;
+}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Rectangle.cs b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
index 424424b..d67a204 100644
--- a/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
+++ b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
@@ -3,17 +3,22 @@
///
/// Represents a rectangle
///
-public class Rectangle
+///
+/// Creates a new rectangle instance
+///
+/// The length of the rectangle
+/// The width of the rectangle
+public class Rectangle(double length, double width)
{
///
/// The length of the
///
- public double Length { get; set; }
+ public double Length { get; set; } = length;
///
/// The width of the
///
- public double Width { get; set; }
+ public double Width { get; set; } = width;
///
/// The diagonal of the
@@ -28,16 +33,10 @@ public class Rectangle
///
/// The perimeter of the
///
- public double Perimeter => Length * 2 + Width * 2;
+ public double Perimeter => (Length * 2) + (Width * 2);
- ///
- /// Creates a new rectangle instance
- ///
- /// The length of the rectangle
- /// The width of the rectangle
- public Rectangle(double length, double width)
- {
- Length = length;
- Width = width;
- }
+ public bool IsSquare => Length == Width;
+ public bool IsRectangle => !IsSquare;
+
+ public bool IsGolden => Length / Width == 1.61803398875;
}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Triangle.cs b/src/CuteUtils/FluentMath/Shapes/Triangle.cs
new file mode 100644
index 0000000..4a25927
--- /dev/null
+++ b/src/CuteUtils/FluentMath/Shapes/Triangle.cs
@@ -0,0 +1,35 @@
+namespace CuteUtils.FluentMath.Shapes;
+
+public class Triangle(double sideA, double sideB, double sideC)
+{
+ public double SideA { get; set; } = sideA;
+ public double SideB { get; set; } = sideB;
+ public double SideC { get; set; } = sideC;
+
+ public double Area
+ {
+ get
+ {
+ double s = (SideA + SideB + SideC) / 2;
+ return Math.Sqrt(s * (s - SideA) * (s - SideB) * (s - SideC));
+ }
+ }
+
+ public double Perimeter => SideA + SideB + SideC;
+
+ public bool IsRightAngled
+ {
+ get
+ {
+ double[] sides = [SideA, SideB, SideC];
+ Array.Sort(sides);
+ return Math.Pow(sides[0], 2) + Math.Pow(sides[1], 2) == Math.Pow(sides[2], 2);
+ }
+ }
+
+ public bool IsEquilateral => SideA == SideB && SideB == SideC;
+
+ public bool IsIsosceles => SideA == SideB || SideB == SideC || SideA == SideC;
+
+ public bool IsScalene => !IsEquilateral && !IsIsosceles;
+}
\ No newline at end of file
From 86b510faef119acc7e6599d8281096f94cac516d Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Tue, 19 Mar 2024 19:54:21 +0100
Subject: [PATCH 05/12] Add missing xml docs
---
src/CuteUtils/FluentMath/Shapes/Circle.cs | 19 ++++++++
src/CuteUtils/FluentMath/Shapes/Ellipse.cs | 25 ++++++++++
src/CuteUtils/FluentMath/Shapes/Rectangle.cs | 28 +++++++----
src/CuteUtils/FluentMath/Shapes/Triangle.cs | 38 +++++++++++++++
src/CuteUtils/Reflection/DynDto.cs | 47 +++++++++++++++++++
.../Reflection/DynDtoNameAttribute.cs | 13 ++++-
.../Reflection/ReflectionExtentions.cs | 21 +++++----
7 files changed, 171 insertions(+), 20 deletions(-)
diff --git a/src/CuteUtils/FluentMath/Shapes/Circle.cs b/src/CuteUtils/FluentMath/Shapes/Circle.cs
index bb9d3c3..151ff00 100644
--- a/src/CuteUtils/FluentMath/Shapes/Circle.cs
+++ b/src/CuteUtils/FluentMath/Shapes/Circle.cs
@@ -1,12 +1,31 @@
namespace CuteUtils.FluentMath.Shapes;
+///
+/// Represents a circle shape.
+///
+///
+/// Initializes a new instance of the class with the specified radius.
+///
+/// The radius of the circle.
public class Circle(double radius)
{
+ ///
+ /// Gets or sets the radius of the circle.
+ ///
public double Radius { get; set; } = radius;
+ ///
+ /// Gets the diameter of the circle.
+ ///
public double Diameter => Radius * 2;
+ ///
+ /// Gets the circumference of the circle.
+ ///
public double Circumference => 2 * Math.PI * Radius;
+ ///
+ /// Gets the area of the circle.
+ ///
public double Area => Math.PI * Math.Pow(Radius, 2);
}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Ellipse.cs b/src/CuteUtils/FluentMath/Shapes/Ellipse.cs
index e4963ab..f6df592 100644
--- a/src/CuteUtils/FluentMath/Shapes/Ellipse.cs
+++ b/src/CuteUtils/FluentMath/Shapes/Ellipse.cs
@@ -1,12 +1,37 @@
namespace CuteUtils.FluentMath.Shapes;
+///
+/// Represents an ellipse shape.
+///
+///
+/// Initializes a new instance of the class with the specified major and minor axes.
+///
+/// The length of the major axis.
+/// The length of the minor axis.
public class Ellipse(double majorAxis, double minorAxis)
{
+ ///
+ /// Gets or sets the length of the major axis.
+ ///
public double MajorAxis { get; set; } = majorAxis;
+
+ ///
+ /// Gets or sets the length of the minor axis.
+ ///
public double MinorAxis { get; set; } = minorAxis;
+ ///
+ /// Gets the area of the ellipse.
+ ///
public double Area => Math.PI * MajorAxis * MinorAxis;
+
+ ///
+ /// Gets the circumference of the ellipse.
+ ///
public double Circumference => Math.PI * ((3 * (MajorAxis + MinorAxis)) - Math.Sqrt(((3 * MajorAxis) + MinorAxis) * (MajorAxis + (3 * MinorAxis))));
+ ///
+ /// Gets a value indicating whether the ellipse is a circle.
+ ///
public bool IsCircle => MajorAxis == MinorAxis;
}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Rectangle.cs b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
index d67a204..d74abe7 100644
--- a/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
+++ b/src/CuteUtils/FluentMath/Shapes/Rectangle.cs
@@ -1,42 +1,52 @@
namespace CuteUtils.FluentMath.Shapes;
///
-/// Represents a rectangle
+/// Represents a rectangle shape.
///
///
-/// Creates a new rectangle instance
+/// Initializes a new instance of the class with the specified length and width.
///
-/// The length of the rectangle
-/// The width of the rectangle
+/// The length of the rectangle.
+/// The width of the rectangle.
public class Rectangle(double length, double width)
{
///
- /// The length of the
+ /// Gets or sets the length of the rectangle.
///
public double Length { get; set; } = length;
///
- /// The width of the
+ /// Gets or sets the width of the rectangle.
///
public double Width { get; set; } = width;
///
- /// The diagonal of the
+ /// Gets the diagonal length of the rectangle.
///
public double Diagonal => Math.Sqrt(Math.Pow(Length, 2) + Math.Pow(Width, 2));
///
- /// The area of the
+ /// Gets the area of the rectangle.
///
public double Area => Length * Width;
///
- /// The perimeter of the
+ /// Gets the perimeter of the rectangle.
///
public double Perimeter => (Length * 2) + (Width * 2);
+ ///
+ /// Gets a value indicating whether the rectangle is a square.
+ ///
public bool IsSquare => Length == Width;
+
+ ///
+ /// Gets a value indicating whether the rectangle is a rectangle (not a square).
+ ///
public bool IsRectangle => !IsSquare;
+ ///
+ /// Gets a value indicating whether the rectangle has a golden ratio.
+ ///
public bool IsGolden => Length / Width == 1.61803398875;
}
\ No newline at end of file
diff --git a/src/CuteUtils/FluentMath/Shapes/Triangle.cs b/src/CuteUtils/FluentMath/Shapes/Triangle.cs
index 4a25927..b7fbb74 100644
--- a/src/CuteUtils/FluentMath/Shapes/Triangle.cs
+++ b/src/CuteUtils/FluentMath/Shapes/Triangle.cs
@@ -1,11 +1,34 @@
namespace CuteUtils.FluentMath.Shapes;
+///
+/// Represents a triangle with three sides.
+///
+///
+/// Initializes a new instance of the class with the specified side lengths.
+///
+/// The length of side A.
+/// The length of side B.
+/// The length of side C.
public class Triangle(double sideA, double sideB, double sideC)
{
+ ///
+ /// Gets or sets the length of side A.
+ ///
public double SideA { get; set; } = sideA;
+
+ ///
+ /// Gets or sets the length of side B.
+ ///
public double SideB { get; set; } = sideB;
+
+ ///
+ /// Gets or sets the length of side C.
+ ///
public double SideC { get; set; } = sideC;
+ ///
+ /// Gets the area of the triangle.
+ ///
public double Area
{
get
@@ -15,8 +38,14 @@ public class Triangle(double sideA, double sideB, double sideC)
}
}
+ ///
+ /// Gets the perimeter of the triangle.
+ ///
public double Perimeter => SideA + SideB + SideC;
+ ///
+ /// Gets a value indicating whether the triangle is right-angled.
+ ///
public bool IsRightAngled
{
get
@@ -27,9 +56,18 @@ public class Triangle(double sideA, double sideB, double sideC)
}
}
+ ///
+ /// Gets a value indicating whether the triangle is equilateral.
+ ///
public bool IsEquilateral => SideA == SideB && SideB == SideC;
+ ///
+ /// Gets a value indicating whether the triangle is isosceles.
+ ///
public bool IsIsosceles => SideA == SideB || SideB == SideC || SideA == SideC;
+ ///
+ /// Gets a value indicating whether the triangle is scalene.
+ ///
public bool IsScalene => !IsEquilateral && !IsIsosceles;
}
\ No newline at end of file
diff --git a/src/CuteUtils/Reflection/DynDto.cs b/src/CuteUtils/Reflection/DynDto.cs
index 8f3c883..c9fe6db 100644
--- a/src/CuteUtils/Reflection/DynDto.cs
+++ b/src/CuteUtils/Reflection/DynDto.cs
@@ -3,8 +3,16 @@ using System.Reflection;
namespace CuteUtils.Reflection;
+///
+/// Provides utility methods for converting objects to and from dynamic DTOs.
+///
public static class DynDto
{
+ ///
+ /// Converts an object to a dynamic DTO.
+ ///
+ /// The object to convert.
+ /// The dynamic DTO.
public static ExpandoObject ToDto(this object data)
{
ExpandoObject dto = new ExpandoObject();
@@ -24,6 +32,13 @@ public static class DynDto
return dto;
}
+ ///
+ /// Converts an object to a specified type of DTO.
+ ///
+ /// The type of DTO.
+ /// The object to convert.
+ /// The DTO instance to populate.
+ /// The populated DTO.
public static T ToDto(this object data, T dto)
{
ArgumentNullException.ThrowIfNull(dto);
@@ -46,11 +61,24 @@ public static class DynDto
return dto;
}
+ ///
+ /// Converts an object to a new instance of a specified type of DTO.
+ ///
+ /// The type of DTO.
+ /// The object to convert.
+ /// The new instance of the DTO.
public static T ToDto(this object data) where T : new()
{
return ToDto(data, new T());
}
+ ///
+ /// Converts a dynamic DTO to an object.
+ ///
+ /// The type of object.
+ /// The dynamic DTO.
+ /// The object instance to populate.
+ /// The populated object.
public static T FromDto(this object dto, T data)
{
ArgumentNullException.ThrowIfNull(data);
@@ -75,6 +103,13 @@ public static class DynDto
return data;
}
+ ///
+ /// Converts a dynamic DTO to an object.
+ ///
+ /// The type of object.
+ /// The dynamic DTO.
+ /// The new instance of the object.
+ /// The populated object.
public static T FromDto(this ExpandoObject dto, T data)
{
ArgumentNullException.ThrowIfNull(dto);
@@ -96,11 +131,23 @@ public static class DynDto
return data;
}
+ ///
+ /// Converts a dynamic DTO to a new instance of an object.
+ ///
+ /// The type of object.
+ /// The dynamic DTO.
+ /// The new instance of the object.
public static T FromDto(this object dto) where T : new()
{
return FromDto(dto, new T());
}
+ ///
+ /// Converts a dynamic DTO to a new instance of an object.
+ ///
+ /// The type of object.
+ /// The dynamic DTO.
+ /// The new instance of the object.
public static T FromDto(this ExpandoObject dto) where T : new()
{
return FromDto(dto, new T());
diff --git a/src/CuteUtils/Reflection/DynDtoNameAttribute.cs b/src/CuteUtils/Reflection/DynDtoNameAttribute.cs
index 475350f..4e1a84e 100644
--- a/src/CuteUtils/Reflection/DynDtoNameAttribute.cs
+++ b/src/CuteUtils/Reflection/DynDtoNameAttribute.cs
@@ -1,6 +1,17 @@
namespace CuteUtils.Reflection;
+
+///
+/// Represents an attribute that specifies the dynamic DTO name for a property.
+///
+///
+/// Initializes a new instance of the class with the specified name.
+///
+/// The dynamic DTO name.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DynDtoNameAttribute(string name) : Attribute
{
+ ///
+ /// Gets or sets the dynamic DTO name.
+ ///
public string Name { get; set; } = name;
-}
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Reflection/ReflectionExtentions.cs b/src/CuteUtils/Reflection/ReflectionExtentions.cs
index 8459a45..4f7bb7e 100644
--- a/src/CuteUtils/Reflection/ReflectionExtentions.cs
+++ b/src/CuteUtils/Reflection/ReflectionExtentions.cs
@@ -3,16 +3,16 @@
namespace CuteUtils.Reflection;
///
-/// Reflection class
+/// Provides extension methods for reflection operations.
///
public static class ReflectionExtentions
{
///
- /// Copies all properties of an object to a new one.
+ /// Creates a new instance of the specified type and copies the properties from the source object to the new instance.
///
- ///
- ///
- ///
+ /// The type of the new instance.
+ /// The source object.
+ /// A new instance of the specified type with copied properties.
public static T CopyProperties(this object obj) where T : new()
{
T newObj = new T();
@@ -33,12 +33,13 @@ public static class ReflectionExtentions
}
///
- /// Copies all properties of an object to a different one.
+ /// Copies the properties from the source object to the specified target object.
///
- ///
- ///
- ///
- ///
+ /// The type of the target object.
+ /// The source object.
+ /// The target object.
+ /// The target object with copied properties.
+ /// Thrown when the target object is null.
public static T CopyProperties(this object obj, T newObj)
{
ArgumentNullException.ThrowIfNull(newObj);
From 3bd8a283041181f17c45bf9d44d37393ab48d3c5 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Tue, 19 Mar 2024 22:42:28 +0100
Subject: [PATCH 06/12] Add Vsxmd
---
src/CuteUtils/CuteUtils.csproj | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/CuteUtils/CuteUtils.csproj b/src/CuteUtils/CuteUtils.csproj
index b4ef780..30470d5 100644
--- a/src/CuteUtils/CuteUtils.csproj
+++ b/src/CuteUtils/CuteUtils.csproj
@@ -4,10 +4,19 @@
net8.0
enable
enable
+ True
+ CuteUtils
+ Stone_Red
+ https://github.com/Stone-Red-Code/CuteUtils
+ True
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
From e2c3e6e2af1907cc94b9481f024fd23f131b5531 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Thu, 21 Mar 2024 08:19:20 +0100
Subject: [PATCH 07/12] Update old xml docs
---
src/CuteUtils/CollectionExtentions.cs | 19 +--
src/CuteUtils/ConsoleExtentions.cs | 41 +++---
src/CuteUtils/CuteUtils.csproj | 47 ++++---
src/CuteUtils/Logging/Logger.cs | 175 +++++++++++++-------------
src/CuteUtils/RandomExtentions.cs | 27 +++-
5 files changed, 174 insertions(+), 135 deletions(-)
diff --git a/src/CuteUtils/CollectionExtentions.cs b/src/CuteUtils/CollectionExtentions.cs
index a9dcb84..a9cb784 100644
--- a/src/CuteUtils/CollectionExtentions.cs
+++ b/src/CuteUtils/CollectionExtentions.cs
@@ -34,11 +34,12 @@ public enum TableStyle
public static class CollectionExt
{
///
- /// Prints all items of an
+ /// Prints the elements of the collection.
///
- ///
- ///
- ///
+ /// The type of the elements in the collection.
+ /// The collection to print.
+ /// The delimiter character to use between elements. Default is ','.
+ /// Indicates whether to print to the debug console. Default is false.
public static void Print(this IEnumerable collection, char delimiter = ',', bool printToDebugConsole = false)
{
int i = 0;
@@ -63,11 +64,11 @@ public static class CollectionExt
}
///
- /// Creates and prints table from 2D array
+ /// Prints the elements of the 2D array in a table format.
///
- ///
- ///
- ///
+ /// The type of the elements in the array.
+ /// The 2D array to print.
+ /// The style of the table. Default is TableStyle.Default.
public static void PrintTable(this T[,] array, TableStyle tableStyle = TableStyle.Default)
{
int[] itemLength = new int[array.GetLength(1)];
@@ -126,4 +127,4 @@ public static class CollectionExt
}
Console.WriteLine();
}
-}
\ No newline at end of file
+}
diff --git a/src/CuteUtils/ConsoleExtentions.cs b/src/CuteUtils/ConsoleExtentions.cs
index 347a30d..5ca80d1 100644
--- a/src/CuteUtils/ConsoleExtentions.cs
+++ b/src/CuteUtils/ConsoleExtentions.cs
@@ -11,10 +11,10 @@ namespace CuteUtils;
public static class ConsoleExt
{
///
- /// Writes the text representation of the specified object to the standard output stream.
+ /// Writes the specified value to the console with the specified color.
///
- ///
- ///
+ /// The value to write.
+ /// The color of the text.
public static void Write(object value, ConsoleColor color)
{
lock (Console.Out)
@@ -27,10 +27,10 @@ public static class ConsoleExt
}
///
- /// Writes the text representation of the specified object, followed by the current line terminator, to the standard output stream.
+ /// Writes the specified value to the console with the specified color and appends a new line.
///
- ///
- ///
+ /// The value to write.
+ /// The color of the text.
public static void WriteLine(object value, ConsoleColor color)
{
lock (Console.Out)
@@ -45,9 +45,9 @@ public static class ConsoleExt
///
/// Reads the next line of characters from the standard input stream and tries to convert it to the specified type.
///
- ///
+ /// The type to convert the input string to.
/// The input string converted to the specified type.
- ///
+ /// Thrown if the conversion is not supported.
public static T ReadLine()
{
string attemptedValue = Console.ReadLine() ?? string.Empty;
@@ -60,9 +60,9 @@ public static class ConsoleExt
///
/// Reads the next line of characters from the standard input stream and tries to convert it to the specified type.
///
- ///
+ /// The type to convert the input string to.
/// The input string converted to the specified type.
- /// if the conversion was successful. Otherwise
+ /// if the conversion was successful. Otherwise .
public static bool TryReadLine([NotNullWhen(true)] out T? input)
{
string attemptedValue = Console.ReadLine() ?? string.Empty;
@@ -84,9 +84,9 @@ public static class ConsoleExt
/// Obtains the next character or function key pressed by the user and converts it to the specified type.
/// The pressed key is displayed in the console window.
///
- /// The type of the
+ /// The type to convert the input character to.
/// The input character converted to the specified type.
- ///
+ /// Thrown if the conversion is not supported.
public static T ReadKey()
{
string attemptedValue = Console.ReadKey().KeyChar.ToString();
@@ -101,15 +101,14 @@ public static class ConsoleExt
/// The pressed key is displayed in the console window.
///
/// The input character converted to the specified type.
- /// The type of the
- /// if the conversion was successful. Otherwise
+ /// The type to convert the input character to.
+ /// if the conversion was successful. Otherwise .
public static bool TryReadKey([NotNullWhen(true)] out T? input)
{
string attemptedValue = Console.ReadKey().KeyChar.ToString();
Type type = typeof(T);
TypeConverter converter = TypeDescriptor.GetConverter(type);
if (converter != null && converter.IsValid(attemptedValue))
-
{
input = (T)converter.ConvertFromString(attemptedValue)!;
return true;
@@ -122,10 +121,10 @@ public static class ConsoleExt
}
///
- /// Suspends execution of the current method until the user presses a key
+ /// Suspends execution of the current method until the user presses a key.
///
- /// The key that has to be pressed
- /// The message that will be displayed
+ /// The key that has to be pressed.
+ /// The message that will be displayed.
public static void Pause(ConsoleKey key, string? message = null)
{
Console.WriteLine(message ?? $"Press {key} to continue...");
@@ -137,12 +136,12 @@ public static class ConsoleExt
}
///
- /// Suspends execution of the current method until the user presses a key
+ /// Suspends execution of the current method until the user presses a key.
///
- /// The message that will be displayed
+ /// The message that will be displayed.
public static void Pause(string message = "Press any key to continue...")
{
Console.WriteLine(message);
_ = Console.ReadKey(true);
}
-}
\ No newline at end of file
+}
diff --git a/src/CuteUtils/CuteUtils.csproj b/src/CuteUtils/CuteUtils.csproj
index 30470d5..804a56e 100644
--- a/src/CuteUtils/CuteUtils.csproj
+++ b/src/CuteUtils/CuteUtils.csproj
@@ -1,22 +1,35 @@
-
- net8.0
- enable
- enable
- True
- CuteUtils
- Stone_Red
- https://github.com/Stone-Red-Code/CuteUtils
- True
-
+
+ net8.0
+ enable
+ enable
+ True
+ CuteUtils
+ Stone_Red
+ https://github.com/Stone-Red-Code/CuteUtils
+ True
+ README.md
+
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+ False
+ False
+
+
+
+
+ True
+ \
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/src/CuteUtils/Logging/Logger.cs b/src/CuteUtils/Logging/Logger.cs
index 73f13b3..ce43d68 100644
--- a/src/CuteUtils/Logging/Logger.cs
+++ b/src/CuteUtils/Logging/Logger.cs
@@ -9,172 +9,172 @@ namespace CuteUtils.Logging;
public class Logger
{
///
- /// The logging configuration.
+ /// Gets or sets the log configuration.
///
public LogConfig Config { get; init; } = new LogConfig();
///
- /// Log the message to the specified output
+ /// Logs a message with the specified source, log severity, and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The severity level of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void Log(string message, string source, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, logSeverity, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a message with the specified log severity and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The severity level of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void Log(string message, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, logSeverity, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs an informational message with the specified source and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogInfo(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, LogSeverity.Info, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs an informational message with additional caller information.
///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogInfo(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, LogSeverity.Info, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a warning message with the specified source and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogWarn(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, LogSeverity.Warn, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a warning message with additional caller information.
///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogWarn(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, LogSeverity.Warn, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs an error message with additional caller information.
///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogError(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, LogSeverity.Error, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs an error message with the specified source and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogError(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, LogSeverity.Error, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a fatal error message with additional caller information.
///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogFatal(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, LogSeverity.Fatal, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a fatal error message with the specified source and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogFatal(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, LogSeverity.Fatal, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a debug message with additional caller information.
///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogDebug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, string.Empty, LogSeverity.Debug, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output
+ /// Logs a debug message with the specified source and additional caller information.
///
- ///
- ///
- ///
- ///
- ///
+ /// The message to log.
+ /// The source of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogDebug(string message, string source, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
WriteLog(message, source, LogSeverity.Debug, memberName, sourceFilePath, sourceLineNumber);
}
///
- /// Log the message to the specified output if the condition is met
+ /// Logs a message with the specified source, log severity, and additional caller information if the condition is met.
///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// The condition to check.
+ /// The message to log.
+ /// The source of the log message.
+ /// The severity level of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogIf(bool condition, string message, string source, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (condition)
@@ -184,14 +184,14 @@ public class Logger
}
///
- /// Log the message to the specified output if the condition is met
+ /// Logs a message with the specified log severity and additional caller information if the condition is met.
///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// The condition to check.
+ /// The message to log.
+ /// The severity level of the log message.
+ /// The name of the calling member.
+ /// The path of the source file.
+ /// The line number in the source file.
public void LogIf(bool condition, string message, LogSeverity logSeverity, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
if (condition)
@@ -201,8 +201,9 @@ public class Logger
}
///
- /// Clears the log file
+ /// Clears the log file for the specified log severity.
///
+ /// The severity level of the log messages to clear.
public void ClearLogFile(LogSeverity logSeverity)
{
OutputConfig outputConfig = GetOutputConfig(logSeverity);
@@ -257,7 +258,7 @@ public class Logger
File.Create(outputConfig.FilePath).Close();
}
- File.AppendAllLines(outputConfig.FilePath, [fileOutput]);
+ File.AppendAllLines(outputConfig.FilePath, new[] { fileOutput });
}
}
}
@@ -273,4 +274,4 @@ public class Logger
_ => Config.DebugConfig
};
}
-}
\ No newline at end of file
+}
diff --git a/src/CuteUtils/RandomExtentions.cs b/src/CuteUtils/RandomExtentions.cs
index c8922a6..36fc0d8 100644
--- a/src/CuteUtils/RandomExtentions.cs
+++ b/src/CuteUtils/RandomExtentions.cs
@@ -5,6 +5,13 @@
///
public static class RandomExt
{
+ ///
+ /// Returns a random item from the specified enumerable.
+ ///
+ /// The type of the items in the enumerable.
+ /// The random number generator.
+ /// The enumerable to select a random item from.
+ /// A random item from the enumerable.
public static T NextItem(this Random random, IEnumerable enumerable)
{
ArgumentNullException.ThrowIfNull(enumerable);
@@ -12,19 +19,37 @@ public static class RandomExt
return enumerable.ElementAt(random.Next(enumerable.Count()));
}
+ ///
+ /// Returns a random boolean value.
+ ///
+ /// The random number generator.
+ /// A random boolean value.
public static bool NextBool(this Random random)
{
return random.Next(2) == 0;
}
+ ///
+ /// Returns a random value from the specified enum type.
+ ///
+ /// The enum type.
+ /// The random number generator.
+ /// A random value from the enum type.
public static T NextEnum(this Random random) where T : struct, Enum
{
T[] values = Enum.GetValues();
return values[random.Next(values.Length)];
}
+ ///
+ /// Returns a random value from the specified array of enum values.
+ ///
+ /// The enum type.
+ /// The random number generator.
+ /// The array of enum values.
+ /// A random value from the array of enum values.
public static T NextEnum(this Random random, T[] values) where T : struct, Enum
{
return values[random.Next(values.Length)];
}
-}
\ No newline at end of file
+}
From 9e1d9098a74e3de34f69ccf31847b0bc8ee2bd82 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Thu, 4 Apr 2024 23:58:53 +0200
Subject: [PATCH 08/12] Fix xml docs mistakes
---
src/CuteUtils/Logging/LogFormatBuilder.cs | 4 ++--
src/CuteUtils/Tasks/TaskQueue.cs | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/CuteUtils/Logging/LogFormatBuilder.cs b/src/CuteUtils/Logging/LogFormatBuilder.cs
index 5ae36b1..7ce6888 100644
--- a/src/CuteUtils/Logging/LogFormatBuilder.cs
+++ b/src/CuteUtils/Logging/LogFormatBuilder.cs
@@ -26,7 +26,7 @@ public class LogFormatBuilder
}
///
- /// Converts the />
+ /// Converts the to
///
/// The to convert.
public static implicit operator string(LogFormatBuilder value)
@@ -35,7 +35,7 @@ public class LogFormatBuilder
}
///
- /// Converts the />
+ /// Converts the to
///
/// The to convert.
public static implicit operator LogFormatBuilder(string value)
diff --git a/src/CuteUtils/Tasks/TaskQueue.cs b/src/CuteUtils/Tasks/TaskQueue.cs
index 919852b..9a78cae 100644
--- a/src/CuteUtils/Tasks/TaskQueue.cs
+++ b/src/CuteUtils/Tasks/TaskQueue.cs
@@ -92,6 +92,7 @@ public class TaskQueue : IDisposable
GC.SuppressFinalize(this);
}
+ ///
protected virtual void Dispose(bool disposing)
{
if (!disposed)
From a759e09c6715c033a2524bbf47077ff5284d3e79 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Thu, 4 Apr 2024 23:59:24 +0200
Subject: [PATCH 09/12] Fix vsxmd error
---
src/CuteUtils/CuteUtils.csproj | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/src/CuteUtils/CuteUtils.csproj b/src/CuteUtils/CuteUtils.csproj
index 804a56e..fe76f91 100644
--- a/src/CuteUtils/CuteUtils.csproj
+++ b/src/CuteUtils/CuteUtils.csproj
@@ -18,6 +18,10 @@
+
+ True
+ \
+
True
\
@@ -27,9 +31,32 @@
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ $([System.IO.Path]::GetTempPath())
+ 1.0.0.0
+ A "cute" utility library for C#
+ https://github.com/Stone-Red-Code/CuteUtils
+ Utility, Helper
+ LICENSE
+
+
+
+
+
+
+
+
+
+
From fde63845f51cad4d8291169f43ee601ecea612c7 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Thu, 4 Apr 2024 23:59:37 +0200
Subject: [PATCH 10/12] Finalize DynDto tests
---
src/CuteUtils.Tests/DynDtoTests.cs | 146 +++++++++++++++++++++++------
1 file changed, 115 insertions(+), 31 deletions(-)
diff --git a/src/CuteUtils.Tests/DynDtoTests.cs b/src/CuteUtils.Tests/DynDtoTests.cs
index 6140ffb..7ed1394 100644
--- a/src/CuteUtils.Tests/DynDtoTests.cs
+++ b/src/CuteUtils.Tests/DynDtoTests.cs
@@ -8,58 +8,142 @@ namespace CuteUtils.Tests;
public class DynDtoTests
{
[TestMethod]
- public void Convert_ToDto_ReturnsExpandoObject()
+ public void ToDto_ShouldConvertObjectToDynamicDto()
{
- TestModel testModel = new()
+ // Arrange
+ TestData data = new TestData
{
- Id = 13,
- Name = "test",
- Value = (15, "test"),
+ Name = "John",
+ Age = 30
};
- ExpandoObject dto = testModel.ToDto();
+ // Act
+ dynamic dto = data.ToDto();
- Assert.IsNotNull(dto);
-
- Assert.IsFalse(dto.Any(p => p.Key == "Id"));
- Assert.IsTrue(dto.Any(p => p.Key == "Name"));
- Assert.IsTrue(dto.Any(p => p.Key == "Value"));
+ // Assert
+ Assert.AreEqual("John", dto.Name);
+ Assert.AreEqual(30, dto.Age);
}
[TestMethod]
- public void Convert_ToDto_ReturnsGeneric()
+ public void ToDto_ShouldConvertObjectToSpecifiedDtoType()
{
- TestModel testModel = new()
+ // Arrange
+ TestData data = new TestData
{
- Id = 13,
- Name = "test",
- Value = (15, "test"),
+ Name = "John",
+ Age = 30
+ };
+ TestDataDto dto = new TestDataDto();
+
+ // Act
+ dto = data.ToDto(dto);
+
+ // Assert
+ Assert.AreEqual("John", dto.Name);
+ Assert.AreEqual(30, dto.Age);
+ }
+
+ [TestMethod]
+ public void ToDto_ShouldConvertObjectToNewInstanceDto()
+ {
+ // Arrange
+ TestData data = new TestData
+ {
+ Name = "John",
+ Age = 30
};
- TestDto dto = testModel.ToDto();
+ // Act
+ TestDataDto dto = data.ToDto();
- Assert.IsNotNull(dto);
-
- Assert.IsTrue(dto.Id == 0);
- Assert.IsTrue(!string.IsNullOrWhiteSpace(dto.Name));
- Assert.IsTrue(dto.Value is not (0, ""));
+ // Assert
+ Assert.AreEqual("John", dto.Name);
+ Assert.AreEqual(30, dto.Age);
}
- private class TestModel
+ [TestMethod]
+ public void FromDto_ShouldConvertDynamicDtoToObject()
{
- public required int Id { get; set; }
+ // Arrange
+ ExpandoObject dto = new ExpandoObject();
+ _ = dto.TryAdd("Name", "John");
+ _ = dto.TryAdd("Age", 30);
+ TestData data = new TestData();
- [DynDtoName(nameof(Name))]
- public required string Name { get; set; }
+ // Act
+ data = dto.FromDto(data);
- [DynDtoName(nameof(Value))]
- public required object Value { get; set; }
+ // Assert
+ Assert.AreEqual("John", data.Name);
+ Assert.AreEqual(30, data.Age);
}
- private class TestDto
+ [TestMethod]
+ public void FromDto_ShouldConvertDynamicDtoToNewInstanceObject()
{
- public int Id { get; init; } = 0;
+ // Arrange
+ ExpandoObject dto = new ExpandoObject();
+ _ = dto.TryAdd("Name", "John");
+ _ = dto.TryAdd("Age", 30);
+
+ // Act
+ TestData data = dto.FromDto();
+
+ // Assert
+ Assert.AreEqual("John", data.Name);
+ Assert.AreEqual(30, data.Age);
+ }
+
+ [TestMethod]
+ public void FromDto_ShouldConvertDtoToObject()
+ {
+ // Arrange
+ TestDataDto dto = new TestDataDto
+ {
+ Name = "John",
+ Age = 30
+ };
+ TestData data = new TestData();
+
+ // Act
+ data = dto.FromDto(data);
+
+ // Assert
+ Assert.AreEqual("John", data.Name);
+ Assert.AreEqual(30, data.Age);
+ }
+
+ [TestMethod]
+ public void FromDto_ShouldConvertDtoToNewInstanceObject()
+ {
+ // Arrange
+ TestDataDto dto = new TestDataDto
+ {
+ Name = "John",
+ Age = 30
+ };
+
+ // Act
+ TestData data = dto.FromDto();
+
+ // Assert
+ Assert.AreEqual("John", data.Name);
+ Assert.AreEqual(30, data.Age);
+ }
+
+ public class TestData
+ {
+ [DynDtoName("Name")]
public string Name { get; set; } = string.Empty;
- public object Value { get; init; } = (0, string.Empty);
+
+ [DynDtoName("Age")]
+ public int Age { get; set; }
+ }
+
+ public class TestDataDto
+ {
+ public string Name { get; set; } = string.Empty;
+ public int Age { get; set; }
}
}
\ No newline at end of file
From f0f727117abcfa82aca7ce53a96921655e1d01b2 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Fri, 5 Apr 2024 18:23:24 +0200
Subject: [PATCH 11/12] Add more unit tests and improve existing ones
---
.../{ => DynDto}/DynDtoTests.cs | 0
.../Misc/BoolExtentionsTests.cs | 117 +++++++++++++++
.../Misc/CollectionExtentionsTests.cs | 133 ++++++++++++++++++
src/CuteUtils/Logging/Logger.cs | 8 +-
src/CuteUtils/{ => Misc}/BoolExtentions.cs | 2 +-
.../{ => Misc}/CollectionExtentions.cs | 2 +-
src/CuteUtils/{ => Misc}/ConsoleExtentions.cs | 2 +-
src/CuteUtils/{ => Misc}/RandomExtentions.cs | 2 +-
8 files changed, 259 insertions(+), 7 deletions(-)
rename src/CuteUtils.Tests/{ => DynDto}/DynDtoTests.cs (100%)
create mode 100644 src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
create mode 100644 src/CuteUtils.Tests/Misc/CollectionExtentionsTests.cs
rename src/CuteUtils/{ => Misc}/BoolExtentions.cs (97%)
rename src/CuteUtils/{ => Misc}/CollectionExtentions.cs (99%)
rename src/CuteUtils/{ => Misc}/ConsoleExtentions.cs (99%)
rename src/CuteUtils/{ => Misc}/RandomExtentions.cs (98%)
diff --git a/src/CuteUtils.Tests/DynDtoTests.cs b/src/CuteUtils.Tests/DynDto/DynDtoTests.cs
similarity index 100%
rename from src/CuteUtils.Tests/DynDtoTests.cs
rename to src/CuteUtils.Tests/DynDto/DynDtoTests.cs
diff --git a/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs b/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
new file mode 100644
index 0000000..f2e0302
--- /dev/null
+++ b/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
@@ -0,0 +1,117 @@
+using CuteUtils.Misc;
+
+namespace CuteUtils.Tests;
+
+[TestClass]
+public class BoolExtentionsTests
+{
+ [TestMethod]
+ public void OneWayTrue_ShouldSetValueToTrue_WhenInputIsTrue()
+ {
+ // Arrange
+ bool value = false;
+ bool input = true;
+
+ // Act
+ value.OneWayTrue(input);
+
+ // Assert
+ Assert.IsTrue(value);
+ }
+
+ [TestMethod]
+ public void OneWayTrue_ShouldNotChangeValue_WhenInputIsFalse()
+ {
+ // Arrange
+ bool value = true;
+ bool input = false;
+
+ // Act
+ value.OneWayTrue(input);
+
+ // Assert
+ Assert.IsTrue(value);
+ }
+
+ [TestMethod]
+ public void OneWayFalse_ShouldSetValueToFalse_WhenInputIsFalse()
+ {
+ // Arrange
+ bool value = true;
+ bool input = false;
+
+ // Act
+ value.OneWayFalse(input);
+
+ // Assert
+ Assert.IsFalse(value);
+ }
+
+ [TestMethod]
+ public void OneWayFalse_ShouldNotChangeValue_WhenInputIsTrue()
+ {
+ // Arrange
+ bool value = false;
+ bool input = true;
+
+ // Act
+ value.OneWayFalse(input);
+
+ // Assert
+ Assert.IsFalse(value);
+ }
+
+ [TestMethod]
+ public void ToInt_ShouldReturn1_WhenInputIsTrue()
+ {
+ // Arrange
+ bool input = true;
+
+ // Act
+ int result = input.ToInt();
+
+ // Assert
+ Assert.AreEqual(1, result);
+ }
+
+ [TestMethod]
+ public void ToInt_ShouldReturn0_WhenInputIsFalse()
+ {
+ // Arrange
+ bool input = false;
+
+ // Act
+ int result = input.ToInt();
+
+ // Assert
+ Assert.AreEqual(0, result);
+ }
+
+ [TestMethod]
+ public void FromInt_ShouldSetValueToTrue_WhenInputIs1()
+ {
+ // Arrange
+ bool value = false;
+ int input = 1;
+
+ // Act
+ value.FromInt(input);
+
+ // Assert
+ Assert.IsTrue(value);
+ }
+
+ [TestMethod]
+ public void FromInt_ShouldSetValueToFalse_WhenInputIs0()
+ {
+ // Arrange
+ bool value = true;
+ int input = 0;
+
+ // Act
+ value.FromInt(input);
+
+ // Assert
+ Assert.IsFalse(value);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils.Tests/Misc/CollectionExtentionsTests.cs b/src/CuteUtils.Tests/Misc/CollectionExtentionsTests.cs
new file mode 100644
index 0000000..9a3aff8
--- /dev/null
+++ b/src/CuteUtils.Tests/Misc/CollectionExtentionsTests.cs
@@ -0,0 +1,133 @@
+using CuteUtils.Misc;
+
+using System.Text;
+
+namespace CuteUtils.Tests.Misc;
+
+[TestClass]
+public class CollectionExtentionsTests
+{
+ private StringBuilder consoleOutput = null!;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ consoleOutput = new StringBuilder();
+ Console.SetOut(new StringWriter(consoleOutput));
+ }
+
+ [TestMethod]
+ public void Print_ShouldPrintCollectionElements()
+ {
+ // Arrange
+ List collection = [1, 2, 3, 4, 5];
+ string expectedOutput = "1, 2, 3, 4, 5";
+
+ // Act
+ collection.Print();
+ string actualOutput = consoleOutput.ToString();
+
+ // Assert
+ Assert.AreEqual(expectedOutput, actualOutput);
+ }
+
+ [TestMethod]
+ public void Print_ShouldPrintCollectionElementsWithCustomDelimiter()
+ {
+ // Arrange
+ List collection = ["apple", "banana", "cherry"];
+ string expectedOutput = "apple, banana, cherry";
+
+ // Act
+ collection.Print(',');
+ string actualOutput = consoleOutput.ToString();
+
+ // Assert
+ Assert.AreEqual(expectedOutput, actualOutput);
+ }
+
+ [TestMethod]
+ public void Print_ShouldPrintCollectionElementsToDebugConsole()
+ {
+ Assert.Inconclusive("Need to find a way to test this.");
+ }
+
+ [TestMethod]
+ public void PrintTable_ShouldPrint2DArrayInTableFormat()
+ {
+ // Arrange
+ int[,] array = new int[,]
+ {
+ { 1, 2, 3 },
+ { 4, 5, 6 },
+ { 7, 8, 9 }
+ };
+ string expectedOutput = Environment.NewLine +
+ $"-------------{Environment.NewLine}" +
+ $"| 1 | 2 | 3 |{Environment.NewLine}" +
+ $"-------------{Environment.NewLine}" +
+ $"| 4 | 5 | 6 |{Environment.NewLine}" +
+ $"-------------{Environment.NewLine}" +
+ $"| 7 | 8 | 9 |{Environment.NewLine}" +
+ $"-------------{Environment.NewLine}";
+
+ // Act
+ array.PrintTable();
+ string actualOutput = consoleOutput.ToString();
+
+ // Assert
+ Assert.AreEqual(expectedOutput, actualOutput);
+ }
+
+ [TestMethod]
+ public void PrintTable_ShouldPrint2DArrayInTableFormatWithAlternativeStyle()
+ {
+ // Arrange
+ int[,] array = new int[,]
+ {
+ { 1, 2, 3 },
+ { 4, 5, 6 },
+ { 7, 8, 9 }
+ };
+ string expectedOutput = Environment.NewLine +
+ $"+---+---+---+{Environment.NewLine}" +
+ $"| 1 | 2 | 3 |{Environment.NewLine}" +
+ $"+---+---+---+{Environment.NewLine}" +
+ $"| 4 | 5 | 6 |{Environment.NewLine}" +
+ $"+---+---+---+{Environment.NewLine}" +
+ $"| 7 | 8 | 9 |{Environment.NewLine}" +
+ $"+---+---+---+{Environment.NewLine}";
+
+ // Act
+ array.PrintTable(TableStyle.Alternative);
+ string actualOutput = consoleOutput.ToString();
+
+ // Assert
+ Assert.AreEqual(expectedOutput, actualOutput);
+ }
+
+ [TestMethod]
+ public void PrintTable_ShouldPrint2DArrayInTableFormatWithListStyle()
+ {
+ // Arrange
+ int[,] array = new int[,]
+ {
+ { 1, 2, 3 },
+ { 4, 5, 6 },
+ { 7, 8, 9 }
+ };
+ string expectedOutput = Environment.NewLine +
+ $"+---+---+---+{Environment.NewLine}" +
+ $"| 1 | 2 | 3 |{Environment.NewLine}" +
+ $"+---+---+---+{Environment.NewLine}" +
+ $"| 4 | 5 | 6 |{Environment.NewLine}" +
+ $"| 7 | 8 | 9 |{Environment.NewLine}";
+
+ // Act
+ array.PrintTable(TableStyle.List);
+ string actualOutput = consoleOutput.ToString();
+
+ // Assert
+ Assert.AreEqual(expectedOutput, actualOutput);
+ }
+}
\ No newline at end of file
diff --git a/src/CuteUtils/Logging/Logger.cs b/src/CuteUtils/Logging/Logger.cs
index ce43d68..37da229 100644
--- a/src/CuteUtils/Logging/Logger.cs
+++ b/src/CuteUtils/Logging/Logger.cs
@@ -1,4 +1,6 @@
-using System.Diagnostics;
+using CuteUtils.Misc;
+
+using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace CuteUtils.Logging;
@@ -258,7 +260,7 @@ public class Logger
File.Create(outputConfig.FilePath).Close();
}
- File.AppendAllLines(outputConfig.FilePath, new[] { fileOutput });
+ File.AppendAllLines(outputConfig.FilePath, [fileOutput]);
}
}
}
@@ -274,4 +276,4 @@ public class Logger
_ => Config.DebugConfig
};
}
-}
+}
\ No newline at end of file
diff --git a/src/CuteUtils/BoolExtentions.cs b/src/CuteUtils/Misc/BoolExtentions.cs
similarity index 97%
rename from src/CuteUtils/BoolExtentions.cs
rename to src/CuteUtils/Misc/BoolExtentions.cs
index 71e8819..cc9f3a9 100644
--- a/src/CuteUtils/BoolExtentions.cs
+++ b/src/CuteUtils/Misc/BoolExtentions.cs
@@ -1,4 +1,4 @@
-namespace CuteUtils;
+namespace CuteUtils.Misc;
///
/// Extensions
diff --git a/src/CuteUtils/CollectionExtentions.cs b/src/CuteUtils/Misc/CollectionExtentions.cs
similarity index 99%
rename from src/CuteUtils/CollectionExtentions.cs
rename to src/CuteUtils/Misc/CollectionExtentions.cs
index a9cb784..b418f12 100644
--- a/src/CuteUtils/CollectionExtentions.cs
+++ b/src/CuteUtils/Misc/CollectionExtentions.cs
@@ -1,6 +1,6 @@
using System.Diagnostics;
-namespace CuteUtils;
+namespace CuteUtils.Misc;
///
/// Table Style
diff --git a/src/CuteUtils/ConsoleExtentions.cs b/src/CuteUtils/Misc/ConsoleExtentions.cs
similarity index 99%
rename from src/CuteUtils/ConsoleExtentions.cs
rename to src/CuteUtils/Misc/ConsoleExtentions.cs
index 5ca80d1..683b5bc 100644
--- a/src/CuteUtils/ConsoleExtentions.cs
+++ b/src/CuteUtils/Misc/ConsoleExtentions.cs
@@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis;
#pragma warning disable S3998 // Threads should not lock on objects with weak identity
-namespace CuteUtils;
+namespace CuteUtils.Misc;
///
/// Extensions
diff --git a/src/CuteUtils/RandomExtentions.cs b/src/CuteUtils/Misc/RandomExtentions.cs
similarity index 98%
rename from src/CuteUtils/RandomExtentions.cs
rename to src/CuteUtils/Misc/RandomExtentions.cs
index 36fc0d8..22337f9 100644
--- a/src/CuteUtils/RandomExtentions.cs
+++ b/src/CuteUtils/Misc/RandomExtentions.cs
@@ -1,4 +1,4 @@
-namespace CuteUtils;
+namespace CuteUtils.Misc;
///
/// Extensions
From 9a8725564fab2939cf8774a12ff62997ac9bc2ef Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Fri, 5 Apr 2024 18:27:06 +0200
Subject: [PATCH 12/12] Move unit tests to their respective directory
---
src/CuteUtils.Tests/DynDto/DynDtoTests.cs | 2 +-
src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/CuteUtils.Tests/DynDto/DynDtoTests.cs b/src/CuteUtils.Tests/DynDto/DynDtoTests.cs
index 7ed1394..c21fb29 100644
--- a/src/CuteUtils.Tests/DynDto/DynDtoTests.cs
+++ b/src/CuteUtils.Tests/DynDto/DynDtoTests.cs
@@ -2,7 +2,7 @@ using CuteUtils.Reflection;
using System.Dynamic;
-namespace CuteUtils.Tests;
+namespace CuteUtils.Tests.DynDto;
[TestClass]
public class DynDtoTests
diff --git a/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs b/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
index f2e0302..566895a 100644
--- a/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
+++ b/src/CuteUtils.Tests/Misc/BoolExtentionsTests.cs
@@ -1,6 +1,6 @@
using CuteUtils.Misc;
-namespace CuteUtils.Tests;
+namespace CuteUtils.Tests.Misc;
[TestClass]
public class BoolExtentionsTests