using System; using System.Linq; using UnityEngine; namespace DTT.Utils.Extensions { /// /// Provides extensions methods for working with enumerations. /// public static class EnumExtensions { /// /// Returns the inspector name of an enum value. This method uses /// reflection internally so make sure to cache its result. /// /// The enum value to get the inspector name of. /// The enum type. /// The inspector name. public static string GetInspectorName(this T enumValue) where T : Enum { if (enumValue == null) throw new ArgumentNullException(nameof(enumValue)); // Get the attributes of the enum value. Type enumType = typeof(T); object[] attributes = enumType.GetMember(enumValue.ToString()) .First(info => info.DeclaringType == enumType) .GetCustomAttributes(typeof(InspectorNameAttribute), false); if (attributes.Length == 0) throw new InvalidOperationException($"No attributes where found on the enum value {enumValue}."); // Return the display name stored by the first inspector name found on the enum value. return attributes.Cast().First().displayName; } /// /// Returns the next value in the enum value sequence. /// Will loop back to the first value if the value is /// the last. /// /// The type of enum. /// The enum value. /// The next value in the enum value sequence. public static T Next(this T enumValue) where T : Enum { T[] array = (T[])Enum.GetValues(typeof(T)); int i = Array.IndexOf(array, enumValue) + 1; return (i >= array.Length) ? array[0] : array[i]; } /// /// Returns the previous value in the enum value sequence. /// Will loop to the last value if the value is the first. /// /// The type of enum. /// The enum value. /// The previous value in the enum value sequence. public static T Previous(this T enumValue) where T : Enum { T[] array = (T[])Enum.GetValues(typeof(T)); int i = Array.IndexOf(array, enumValue) - 1; return (i < 0) ? array[array.Length - 1] : array[i]; } /// /// Returns the underlying character value. /// /// The enum value to get the underlying character value of. /// The enum type. /// The underlying character value. public static char ToChar(this T enumValue) where T : Enum { if (enumValue == null) throw new ArgumentNullException(nameof(enumValue)); if (!typeof(char).IsAssignableFrom(Enum.GetUnderlyingType(typeof(T)))) throw new ArgumentException("Underlying type of enum value isn't char."); return (char)(object)enumValue; } /// /// Returns the underlying byte value. /// /// The enum value to get the underlying byte value of. /// The enum type. /// The underlying byte value. public static byte ToByte(this T enumValue) where T : Enum { if (enumValue == null) throw new ArgumentNullException(nameof(enumValue)); if (!typeof(byte).IsAssignableFrom(Enum.GetUnderlyingType(typeof(T)))) throw new ArgumentException("Underlying type of enum value isn't byte."); return (byte)(object)enumValue; } /// /// Returns the underlying integer value. /// /// The enum value to get the underlying integer value of. /// The enum type. /// The underlying integer value. public static int ToInt(this T enumValue) where T : Enum { if (enumValue == null) throw new ArgumentNullException(nameof(enumValue)); if (!typeof(int).IsAssignableFrom(Enum.GetUnderlyingType(typeof(T)))) throw new ArgumentException("Underlying type of enum value isn't int."); return (int)(object)enumValue; } } }