Files
MycLib/Src/Data/Myc.Data.Types.Enum.pas
T
Michael Schimmel 947060566d Data Types
2025-08-25 18:00:15 +02:00

143 lines
3.6 KiB
ObjectPascal

unit Myc.Data.Types.Enum;
interface
uses
System.SysUtils,
System.Generics.Collections,
Myc.Data.Types;
type
TDataEnumType = class(TInterfacedObject, IDataEnumType)
private
FName: string;
FIdentifiers: TArray<string>;
FIdentifierMap: TDictionary<string, Integer>;
function GetName: String;
function GetKind: TDataKind;
function GetIdentifier(Idx: Integer): string;
function GetIdentifierCount: Integer;
function IndexOf(const AIdentifier: string): Integer;
function CreateValue(const AValue: Integer): IDataEnumValue; overload;
function CreateValue(const AIdentifier: string): IDataEnumValue; overload;
public
constructor Create(const AName: string; const AIdentifiers: array of string);
destructor Destroy; override;
end;
implementation
uses
System.Rtti;
type
TDataEnumValue = class(TInterfacedObject, IDataEnumValue)
private
FDataType: IDataEnumType;
FValue: Integer;
function GetDataType: IDataType;
function GetAsString: string;
function GetValue: Integer;
function AsTValue: TValue;
public
constructor Create(const ADataType: IDataEnumType; const AValue: Integer);
end;
{ TDataEnumType }
constructor TDataEnumType.Create(const AName: string; const AIdentifiers: array of string);
var
i: Integer;
begin
inherited Create;
FName := AName;
FIdentifierMap := TDictionary<string, Integer>.Create;
SetLength(FIdentifiers, Length(AIdentifiers));
for i := 0 to High(AIdentifiers) do
begin
if FIdentifierMap.ContainsKey(AIdentifiers[i]) then
raise EArgumentException.CreateFmt('Duplicate identifier: %s', [AIdentifiers[i]]);
FIdentifiers[i] := AIdentifiers[i];
FIdentifierMap.Add(AIdentifiers[i], i);
end;
end;
destructor TDataEnumType.Destroy;
begin
FIdentifierMap.Free;
inherited;
end;
function TDataEnumType.GetName: String;
begin
Result := FName;
end;
function TDataEnumType.GetKind: TDataKind;
begin
Result := dkEnum;
end;
function TDataEnumType.GetIdentifier(Idx: Integer): string;
begin
Result := FIdentifiers[Idx];
end;
function TDataEnumType.GetIdentifierCount: Integer;
begin
Result := Length(FIdentifiers);
end;
function TDataEnumType.IndexOf(const AIdentifier: string): Integer;
begin
if not FIdentifierMap.TryGetValue(AIdentifier, Result) then
Result := -1;
end;
function TDataEnumType.CreateValue(const AValue: Integer): IDataEnumValue;
begin
if (AValue < 0) or (AValue >= Length(FIdentifiers)) then
raise EArgumentException.Create('Invalid enum value');
Result := TDataEnumValue.Create(Self, AValue);
end;
function TDataEnumType.CreateValue(const AIdentifier: string): IDataEnumValue;
var
idx: Integer;
begin
idx := IndexOf(AIdentifier);
if idx < 0 then
raise EArgumentException.CreateFmt('Unknown identifier: %s', [AIdentifier]);
Result := CreateValue(idx);
end;
{ TDataEnumValue }
constructor TDataEnumValue.Create(const ADataType: IDataEnumType; const AValue: Integer);
begin
FDataType := ADataType;
FValue := AValue;
end;
function TDataEnumValue.GetDataType: IDataType;
begin
Result := FDataType;
end;
function TDataEnumValue.GetAsString: string;
begin
Result := FDataType.Identifiers[FValue];
end;
function TDataEnumValue.GetValue: Integer;
begin
Result := FValue;
end;
function TDataEnumValue.AsTValue: TValue;
begin
Result := TValue.From<Integer>(FValue);
end;
end.