1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| unit System.Generics.TypeEnum;
interface
uses
System.SysUtils, System.Generics.Collections, System.TypInfo, System.StrUtils,
System.Classes;
type
TEnumHelper<T: record> = record
private
class var FLowerCaseEnumNames: TDictionary<string, T>;
class constructor Create;
class destructor Destroy;
public
class function ToString(Value: T): string; static;
class function FromString(const Value: string): T; static;
class function ToArray(CaseRespect: Boolean = False): TArray<string>; static;
end;
implementation
{ TEnumHelper<T> }
class constructor TEnumHelper<T>.Create;
var
EnumType: PTypeInfo;
EnumData: PTypeData;
EnumValue: Integer;
begin
EnumType := TypeInfo(T);
if EnumType^.Kind <> tkEnumeration then
raise EInvalidOperation.Create('TEnumHelper can only be used with enumeration types');
EnumData := GetTypeData(EnumType);
FLowerCaseEnumNames := TDictionary<string, T>.Create;
for EnumValue := EnumData^.MinValue to EnumData^.MaxValue do
begin
var EnumName := GetEnumName(EnumType, EnumValue);
var Enum: T;
Move(EnumValue, Enum, SizeOf(T));
FLowerCaseEnumNames.AddOrSetValue(AnsiLowerCase(EnumName), Enum);
end;
end;
class destructor TEnumHelper<T>.Destroy;
begin
FLowerCaseEnumNames.Free;
end;
class function TEnumHelper<T>.ToString(Value: T): string;
begin
Result := GetEnumName(TypeInfo(T), Integer(PByte(@Value)^));
end;
class function TEnumHelper<T>.FromString(const Value: string): T;
begin
if not FLowerCaseEnumNames.TryGetValue(AnsiLowerCase(Value), Result) then
raise EArgumentException.CreateFmt('%s : Non-existent enumerated type', [Value]);
end;
class function TEnumHelper<T>.ToArray(CaseRespect: Boolean): TArray<string>;
var
EnumType: PTypeInfo;
EnumData: PTypeData;
EnumValue: Integer;
begin
EnumType := TypeInfo(T);
EnumData := GetTypeData(EnumType);
SetLength(Result, EnumData^.MaxValue - EnumData^.MinValue + 1);
for EnumValue := EnumData^.MinValue to EnumData^.MaxValue do
begin
if CaseRespect then
Result[EnumValue - EnumData^.MinValue] := GetEnumName(EnumType, EnumValue)
else
Result[EnumValue - EnumData^.MinValue] := AnsiLowerCase(GetEnumName(EnumType, EnumValue));
end;
end;
end. |
Partager