143 lines
3.6 KiB
ObjectPascal
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.
|