unit Myc.Data.Types.Enum; interface uses System.SysUtils, System.Generics.Collections, Myc.Data.Types; type TImplDataEnumType = class(TInterfacedObject, IDataEnumType) private FName: string; FIdentifiers: TArray; FIdentifierMap: TDictionary; function GetName: String; function GetKind: TDataKind; function GetIdentifier(Idx: Integer): string; function GetIdentifierCount: Integer; public constructor Create(const AName: string; const AIdentifiers: array of string); destructor Destroy; override; function IndexOf(const AIdentifier: string): Integer; function CreateValue(const AValue: Integer): IDataEnumValue; end; implementation type TImplDataEnumValue = class(TInterfacedObject, IDataEnumValue) private FDataType: IDataEnumType; FValue: Integer; function GetDataType: IDataType; function GetAsString: string; function GetValue: Integer; public constructor Create(const ADataType: IDataEnumType; const AValue: Integer); end; { TImplDataEnumType } constructor TImplDataEnumType.Create(const AName: string; const AIdentifiers: array of string); var i: Integer; begin inherited Create; FName := AName; FIdentifierMap := TDictionary.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 TImplDataEnumType.Destroy; begin FIdentifierMap.Free; inherited; end; function TImplDataEnumType.GetName: String; begin Result := FName; end; function TImplDataEnumType.GetKind: TDataKind; begin Result := dkEnum; end; function TImplDataEnumType.GetIdentifier(Idx: Integer): string; begin Result := FIdentifiers[Idx]; end; function TImplDataEnumType.GetIdentifierCount: Integer; begin Result := Length(FIdentifiers); end; function TImplDataEnumType.IndexOf(const AIdentifier: string): Integer; begin if not FIdentifierMap.TryGetValue(AIdentifier, Result) then Result := -1; end; function TImplDataEnumType.CreateValue(const AValue: Integer): IDataEnumValue; begin if (AValue < 0) or (AValue >= Length(FIdentifiers)) then raise EArgumentException.Create('Invalid enum value'); Result := TImplDataEnumValue.Create(Self, AValue); end; { TImplDataEnumValue } constructor TImplDataEnumValue.Create(const ADataType: IDataEnumType; const AValue: Integer); begin FDataType := ADataType; FValue := AValue; end; function TImplDataEnumValue.GetDataType: IDataType; begin Result := FDataType; end; function TImplDataEnumValue.GetAsString: string; begin Result := FDataType.Identifiers[FValue]; end; function TImplDataEnumValue.GetValue: Integer; begin Result := FValue; end; end.