mirror of
https://github.com/ICDSystems/ICD.Common.Utils.git
synced 2026-02-17 13:45:05 +00:00
Fixing bug with strict enum flags parsing not correctly handling composite values
This commit is contained in:
@@ -71,6 +71,9 @@ namespace ICD.Common.Utils.Tests
|
|||||||
{
|
{
|
||||||
Assert.IsFalse(EnumUtils.IsDefined((eTestEnum)20));
|
Assert.IsFalse(EnumUtils.IsDefined((eTestEnum)20));
|
||||||
Assert.IsTrue(EnumUtils.IsDefined((eTestEnum)2));
|
Assert.IsTrue(EnumUtils.IsDefined((eTestEnum)2));
|
||||||
|
|
||||||
|
Assert.IsFalse(EnumUtils.IsDefined((eTestFlagsEnum)8));
|
||||||
|
Assert.IsTrue(EnumUtils.IsDefined((eTestFlagsEnum)3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Values
|
#region Values
|
||||||
@@ -262,18 +265,29 @@ namespace ICD.Common.Utils.Tests
|
|||||||
{
|
{
|
||||||
Assert.AreEqual(eTestEnum.A, EnumUtils.ParseStrict<eTestEnum>("1", false));
|
Assert.AreEqual(eTestEnum.A, EnumUtils.ParseStrict<eTestEnum>("1", false));
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => EnumUtils.ParseStrict<eTestEnum>("4", false));
|
Assert.Throws<ArgumentOutOfRangeException>(() => EnumUtils.ParseStrict<eTestEnum>("4", false));
|
||||||
|
|
||||||
|
Assert.AreEqual(eTestFlagsEnum.A | eTestFlagsEnum.B, EnumUtils.ParseStrict<eTestFlagsEnum>("3", false));
|
||||||
|
Assert.Throws<ArgumentOutOfRangeException>(() => EnumUtils.ParseStrict<eTestFlagsEnum>("8", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryParseStrictGenericTest()
|
public void TryParseStrictGenericTest()
|
||||||
{
|
{
|
||||||
eTestEnum output;
|
eTestEnum outputA;
|
||||||
|
|
||||||
Assert.AreEqual(true, EnumUtils.TryParseStrict("1", false, out output));
|
Assert.AreEqual(true, EnumUtils.TryParseStrict("1", false, out outputA));
|
||||||
Assert.AreEqual(eTestEnum.A, output);
|
Assert.AreEqual(eTestEnum.A, outputA);
|
||||||
|
|
||||||
Assert.AreEqual(false, EnumUtils.TryParseStrict("4", false, out output));
|
Assert.AreEqual(false, EnumUtils.TryParseStrict("4", false, out outputA));
|
||||||
Assert.AreEqual(eTestEnum.None, output);
|
Assert.AreEqual(eTestEnum.None, outputA);
|
||||||
|
|
||||||
|
eTestFlagsEnum outputB;
|
||||||
|
|
||||||
|
Assert.AreEqual(true, EnumUtils.TryParseStrict("3", false, out outputB));
|
||||||
|
Assert.AreEqual(eTestFlagsEnum.A | eTestFlagsEnum.B, outputB);
|
||||||
|
|
||||||
|
Assert.AreEqual(false, EnumUtils.TryParseStrict("8", false, out outputB));
|
||||||
|
Assert.AreEqual(eTestFlagsEnum.None, outputB);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -52,19 +52,31 @@ namespace ICD.Common.Utils
|
|||||||
return value != null && IsEnumType(value.GetType());
|
return value != null && IsEnumType(value.GetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the given value is defined as part of the given enum type.
|
/// Returns true if the given value is defined as part of the given enum type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool IsDefined<T>(T value)
|
public static bool IsDefined<T>(T value)
|
||||||
{
|
{
|
||||||
if (!IsEnumType(typeof(T)))
|
if (!IsEnumType(typeof(T)))
|
||||||
throw new InvalidOperationException(string.Format("{0} is not an enum", typeof(T).Name));
|
throw new InvalidOperationException(string.Format("{0} is not an enum", typeof(T).Name));
|
||||||
|
|
||||||
return GetValues<T>().Any(v => v.Equals(value));
|
if (!IsFlagsEnum<T>())
|
||||||
}
|
return GetValues<T>().Any(v => v.Equals(value));
|
||||||
|
|
||||||
|
int valueInt = (int)GetUnderlyingValue(value);
|
||||||
|
|
||||||
|
// Check if all of the flag values are defined
|
||||||
|
foreach (T flag in GetFlags(value))
|
||||||
|
{
|
||||||
|
int flagInt = (int)GetUnderlyingValue(flag);
|
||||||
|
valueInt = valueInt - flagInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueInt == 0;
|
||||||
|
}
|
||||||
|
|
||||||
#region Values
|
#region Values
|
||||||
|
|
||||||
@@ -384,27 +396,24 @@ namespace ICD.Common.Utils
|
|||||||
|
|
||||||
#region Conversion
|
#region Conversion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shorthand for parsing string to enum.
|
/// Shorthand for parsing string to enum.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="ignoreCase"></param>
|
/// <param name="ignoreCase"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T Parse<T>(string data, bool ignoreCase)
|
public static T Parse<T>(string data, bool ignoreCase)
|
||||||
{
|
{
|
||||||
if (!IsEnumType<T>())
|
if (!IsEnumType<T>())
|
||||||
throw new ArgumentException(string.Format("{0} is not an enum", typeof(T).Name));
|
throw new ArgumentException(string.Format("{0} is not an enum", typeof(T).Name));
|
||||||
|
|
||||||
try
|
T output;
|
||||||
{
|
if (TryParse(data, ignoreCase, out output))
|
||||||
return (T)Enum.Parse(typeof(T), data, ignoreCase);
|
return output;
|
||||||
}
|
|
||||||
catch (Exception e)
|
string message = string.Format("Failed to parse {0} as {1}", StringUtils.ToRepresentation(data), typeof(T).Name);
|
||||||
{
|
throw new FormatException(message);
|
||||||
throw new FormatException(
|
|
||||||
string.Format("Failed to parse {0} as {1}", StringUtils.ToRepresentation(data), typeof(T).Name), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -424,7 +433,7 @@ namespace ICD.Common.Utils
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = Parse<T>(data, ignoreCase);
|
result = (T)Enum.Parse(typeof(T), data, ignoreCase);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
Reference in New Issue
Block a user