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