Start adding enum helpers

This commit is contained in:
Matt Nadareski
2023-04-19 17:35:20 -04:00
parent 728b5d6b27
commit 8921a09118
3 changed files with 152 additions and 5 deletions

View File

@@ -0,0 +1,24 @@
using System;
namespace SabreTools.Core
{
/// <summary>
/// Maps a set of strings to an enum value
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class MappingAttribute : Attribute
{
/// <summary>
/// Set of mapping strings
/// </summary>
public string[] Mappings { get; private set; }
/// <summary>
/// Constructor
/// </summary>
public MappingAttribute(params string[] mappings)
{
this.Mappings = mappings;
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Linq;
namespace SabreTools.Core.Tools
{
public static class AttributeHelper<T>
{
/// <summary>
/// Get the MappingAttribute from a supported value
/// </summary>
/// <param name="value">Value to use</param>
/// <returns>MappingAttribute attached to the value</returns>
public static MappingAttribute GetAttribute(T value)
{
// Null value in, null value out
if (value == null)
return null;
// Current enumeration type
var enumType = typeof(T);
if (Nullable.GetUnderlyingType(enumType) != null)
enumType = Nullable.GetUnderlyingType(enumType);
// If the value returns a null on ToString, just return null
string valueStr = value.ToString();
if (string.IsNullOrWhiteSpace(valueStr))
return null;
// Get the member info array
var memberInfos = enumType?.GetMember(valueStr);
if (memberInfos == null)
return null;
// Get the enum value info from the array, if possible
var enumValueMemberInfo = memberInfos.FirstOrDefault(m => m.DeclaringType == enumType);
if (enumValueMemberInfo == null)
return null;
// Try to get the relevant attribute
var attributes = enumValueMemberInfo.GetCustomAttributes(typeof(MappingAttribute), true);
if (attributes == null)
return null;
// Return the first attribute, if possible
return (MappingAttribute)attributes.FirstOrDefault();
}
}
}

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace SabreTools.Core.Tools
@@ -1030,13 +1032,13 @@ namespace SabreTools.Core.Tools
"sampleof" => MachineField.SampleOf,
"sample_of" => MachineField.SampleOf,
"type" => MachineField.Type,
#endregion
#region AttractMode
"players" => MachineField.Players,
"rotation" => MachineField.Rotation,
@@ -1127,13 +1129,13 @@ namespace SabreTools.Core.Tools
"system" => MachineField.System,
"msxsystem" => MachineField.System,
"msx_system" => MachineField.System,
"country" => MachineField.Country,
#endregion
#region SoftwareList
"supported" => MachineField.Supported,
#endregion
@@ -1340,6 +1342,44 @@ namespace SabreTools.Core.Tools
_ => null,
};
}
/// <summary>
/// Get a set of mappings from strings to enum values
/// </summary>
/// <param name="type">Enum type to generate from</param>
/// <returns>Dictionary of string to enum values</returns>
private static Dictionary<string, T> GenerateToEnum<T>(Type type)
{
try
{
// Get all of the values for the enum type
var values = Enum.GetValues(type);
// Build the output dictionary
Dictionary<string, T> mappings = new();
foreach (T value in values)
{
// Try to get the mapping attribute
MappingAttribute attr = AttributeHelper<T>.GetAttribute(value);
if (attr?.Mappings == null || !attr.Mappings.Any())
continue;
// Loop through the mappings and add each
foreach (string mapString in attr.Mappings)
{
mappings[mapString] = value;
}
}
// Return the output dictionary
return mappings;
}
catch
{
// This should not happen, only if the type was not an enum
return new Dictionary<string, T>();
}
}
#endregion
@@ -1780,6 +1820,41 @@ namespace SabreTools.Core.Tools
};
}
/// <summary>
/// Get a set of mappings from enum values to string
/// </summary>
/// <param name="type">Enum type to generate from</param>
/// <returns>Dictionary of enum to string values</returns>
private static Dictionary<T, string> GenerateToString<T>(Type type)
{
try
{
// Get all of the values for the enum type
var values = Enum.GetValues(type);
// Build the output dictionary
Dictionary<T, string> mappings = new();
foreach (T value in values)
{
// Try to get the mapping attribute
MappingAttribute attr = AttributeHelper<T>.GetAttribute(value);
if (attr?.Mappings == null || !attr.Mappings.Any())
continue;
// Always use the first value in the list
mappings[value] = attr.Mappings[0];
}
// Return the output dictionary
return mappings;
}
catch
{
// This should not happen, only if the type was not an enum
return new Dictionary<T, string>();
}
}
#endregion
}
}