using System.Diagnostics.CodeAnalysis;
namespace AIStudio.Settings;
///
/// Reads the name of an enum member, and nothing else.
///
///
/// For values somebody wrote by hand, such as those of a configuration plugin. Enum.TryParse
/// accepts more than a name: a number, which becomes whichever member has that value or a value
/// no member has, and several names separated by commas, which it combines bit by bit as if the
/// enum were a set of flags. The enums read from a configuration are no such sets, so
/// "SEMANTIC_SEARCH, EVERY_MESSAGE" would quietly become EVERY_MESSAGE, and "HIGH, MEDIUM" a
/// confidence level which no provider reaches. Only a single name counts here, ignoring case and
/// surrounding white space as Enum.TryParse does.
///
public static class EnumNames
{
///
/// Reads the name of a member of the given enum.
///
/// The text to read.
/// The member named, or the default when the text names none.
/// The enum to read a member of.
/// True when the text names exactly one member.
public static bool TryParse(string? text, out TEnum value) where TEnum : struct, Enum
{
if (TryParse(typeof(TEnum), text, out var member))
{
value = (TEnum)member;
return true;
}
value = default;
return false;
}
///
/// Reads the name of a member of the given enum type.
///
/// The enum type to read a member of.
/// The text to read.
/// The member named, or null when the text names none.
/// True when the text names exactly one member.
public static bool TryParse(Type enumType, string? text, [NotNullWhen(true)] out object? value)
{
value = null;
if (string.IsNullOrWhiteSpace(text))
return false;
var trimmedText = text.Trim();
var name = Enum.GetNames(enumType).FirstOrDefault(candidate => candidate.Equals(trimmedText, StringComparison.OrdinalIgnoreCase));
if (name is null)
return false;
value = Enum.Parse(enumType, name);
return true;
}
}