diff --git a/ICD.Common.Utils.Tests/EnumUtilsTest.cs b/ICD.Common.Utils.Tests/EnumUtilsTest.cs index 1b9a607..2325f7a 100644 --- a/ICD.Common.Utils.Tests/EnumUtilsTest.cs +++ b/ICD.Common.Utils.Tests/EnumUtilsTest.cs @@ -66,9 +66,16 @@ namespace ICD.Common.Utils.Tests Assert.IsFalse(EnumUtils.IsEnum("")); } - #region Values + [Test] + public void IsDefinedTest() + { + Assert.IsFalse(EnumUtils.IsDefined((eTestEnum)20)); + Assert.IsTrue(EnumUtils.IsDefined((eTestEnum)2)); + } - [Test] + #region Values + + [Test] public void GetUnderlyingValueTest() { Assert.AreEqual(0, EnumUtils.GetUnderlyingValue(eTestEnum.None)); @@ -250,7 +257,26 @@ namespace ICD.Common.Utils.Tests Assert.AreEqual(default(eTestEnum), output); } - [Test] + [Test] + public void ParseStrictGenericTest() + { + Assert.AreEqual(eTestEnum.A, EnumUtils.ParseStrict("1", false)); + Assert.Throws(() => EnumUtils.ParseStrict("4", false)); + } + + [Test] + public void TryParseStrictGenericTest() + { + eTestEnum output; + + Assert.AreEqual(true, EnumUtils.TryParseStrict("1", false, out output)); + Assert.AreEqual(eTestEnum.A, output); + + Assert.AreEqual(false, EnumUtils.TryParseStrict("4", false, out output)); + Assert.AreEqual(eTestEnum.None, output); + } + + [Test] public void ToEnumGenericTest() { Assert.AreEqual(eTestEnum.A, EnumUtils.ToEnum(eTestEnum.A)); diff --git a/ICD.Common.Utils/EnumUtils.cs b/ICD.Common.Utils/EnumUtils.cs index 5512985..1a07de3 100644 --- a/ICD.Common.Utils/EnumUtils.cs +++ b/ICD.Common.Utils/EnumUtils.cs @@ -52,6 +52,20 @@ namespace ICD.Common.Utils return value != null && IsEnumType(value.GetType()); } + /// + /// Returns true if the given value is defined as part of the given enum type. + /// + /// + /// + /// + public static bool IsDefined(T value) + { + if (!IsEnumType(typeof(T))) + throw new InvalidOperationException(string.Format("{0} is not an enum", typeof(T).Name)); + + return GetValues().Any(v => v.Equals(value)); + } + #region Values /// @@ -62,7 +76,7 @@ namespace ICD.Common.Utils public static object GetUnderlyingValue(T value) { if (!IsEnumType(typeof(T))) - throw new InvalidOperationException(string.Format("{0} is not an enum", value.GetType().Name)); + throw new InvalidOperationException(string.Format("{0} is not an enum", typeof(T).Name)); #if SIMPLSHARP return Convert.ChangeType(value, ToEnum(value).GetTypeCode(), CultureInfo.InvariantCulture); @@ -419,13 +433,71 @@ namespace ICD.Common.Utils } } - /// - /// Converts the given enum value to an Enum. - /// - /// - /// - /// - public static Enum ToEnum(T value) + /// + /// Shorthand for parsing string to enum. + /// Will fail if the resulting value is not defined as part of the enum. + /// + /// + /// + /// + /// + public static T ParseStrict(string data, bool ignoreCase) + { + if (!IsEnumType()) + throw new ArgumentException(string.Format("{0} is not an enum", typeof(T).Name)); + + T output; + + try + { + output = Parse(data, ignoreCase); + } + catch (Exception e) + { + throw new FormatException( + string.Format("Failed to parse {0} as {1}", StringUtils.ToRepresentation(data), typeof(T).Name), e); + } + + if (!IsDefined(output)) + throw new ArgumentOutOfRangeException(string.Format("{0} is not a valid {1}", output, typeof(T).Name)); + + return output; + } + + /// + /// Shorthand for parsing a string to enum. Returns false if the parse failed. + /// Will fail if the resulting value is not defined as part of the enum. + /// + /// + /// + /// + /// + /// + public static bool TryParseStrict(string data, bool ignoreCase, out T result) + { + if (!IsEnumType()) + throw new ArgumentException(string.Format("{0} is not an enum", typeof(T).Name)); + + result = default(T); + + try + { + result = ParseStrict(data, ignoreCase); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// Converts the given enum value to an Enum. + /// + /// + /// + /// + public static Enum ToEnum(T value) { if (!IsEnum(value)) // ReSharper disable once CompareNonConstrainedGenericWithNull