Recent

Author Topic: [SOLVED] Getting a string representation of an enum value  (Read 9966 times)

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
[SOLVED] Getting a string representation of an enum value
« on: August 25, 2016, 04:03:54 pm »
Searching for the answer to this question has thrown up loads of answers, all of which have left me even more confused...

Some of the answers seems quite old, and its seems that later versions of FPC may well have provided a quick and easy way to do this, but I still can;t figure out what would appear to be a simple thing.

If I have an enum such as:

Code: Pascal  [Select][+][-]
  1. type
  2.   TthreeColors = (red,green,blue);

and I create a a variable of that type to contain one of those colors:
Code: Pascal  [Select][+][-]
  1. var myFavouriteColor: TthreeColors;

I can set myFavourite color with:

Code: Pascal  [Select][+][-]
  1. myFavoriteColor:=blue;

If I then want to get a string representation of this (to save to an XML config file in my case, but could be used for many things) how would I do this?

Code: Pascal  [Select][+][-]
  1.   settingsXML.WriteString('favouriteColor',myFavouriteColor);

doesn't work as WriteString is expecting a type String but getting a type TthreeColors.

I've found references to GetEnumName and GetEnumValue in typinfo but can't work out if these are the right functions to do this...

-FM
« Last Edit: August 25, 2016, 04:19:59 pm by fatmonk »

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: Getting a string representation of an enum value
« Reply #1 on: August 25, 2016, 04:08:43 pm »
I put you some code and try to understand it, simply replace with your type:

Code: Pascal  [Select][+][-]
  1. type
  2.   TFadingMode = (fmSuspended, fmFadeIn, fmFadeOut, fmFadeInCycle, fmFadeOutCycle, fmFadeInOut, fmFadeOutIn);
  3.  
  4. const
  5.   FadingModeStr: array[TFadingMode] of string = ('Suspended', 'Fade In', 'Fade Out', 'Fade In Cycle','Fade Out Cycle', 'Fade In Out', 'Fade Out In');
  6.  
  7. function StrToTFadingMode(const s: ansistring): TFadingMode;
  8. procedure FadingModeStrList(s: TStrings);    
  9.  
  10. function StrToTFadingMode(const s: ansistring): TFadingMode;
  11. var
  12.   fm: TFadingMode;
  13.   ls: ansistring;
  14. begin
  15.   ls := UTF8LowerCase(s);
  16.   for fm := low(TFadingMode) to high(TFadingMode) do
  17.     if ls = UTF8LowerCase(FadingModeStr[fm]) then
  18.     begin
  19.       Result := fm;
  20.       break;
  21.     end;
  22.   Result := fm;
  23. end;
  24.  
  25. procedure FadingModeStrList(s: TStrings);
  26. var
  27.   fm: TFadingMode;
  28. begin
  29.   for fm := low(TFadingMode) to high(TFadingMode) do
  30.     s.Add(FadingModeStr[fm]);
  31. end;

Maybe you don't need FadingModeStrList but just the other code.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Getting a string representation of an enum value
« Reply #2 on: August 25, 2016, 04:14:40 pm »
You can use WriteStr() to convert a enum to a string.

Like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TThreeColors = (red, green, blue);
  3.  
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. var
  6.   myFavouriteColor: TThreeColors;
  7.   Value: string;
  8. begin
  9.   myFavouriteColor := green;
  10.   WriteStr(Value, myFavouriteColor); // converts TThreeColors to string
  11.   Showmessage(Value);
  12. end;

So this should work in your example:
Code: Pascal  [Select][+][-]
  1. var
  2.   Value: String;
  3. begin
  4.   //...
  5.   WriteStr(Value, myFavouriteColor); // converts TThreeColors to string
  6.   settingsXML.WriteString('favouriteColor', Value);

And yes... you could also use typinfo:
Code: Pascal  [Select][+][-]
  1. uses typinfo;
  2. //...
  3. settingsXML.WriteString('favouriteColor', GetEnumName(TypeInfo(TThreeColors), ord(myFavouriteColor)));
« Last Edit: August 25, 2016, 04:18:54 pm by rvk »

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: Getting a string representation of an enum value
« Reply #3 on: August 25, 2016, 04:19:36 pm »
@rvk - beautiful!

I did look at WriteStr() but missed that the result gets sent to the first argument...

Al good, and nice and simple as well.

-FM


rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Getting a string representation of an enum value
« Reply #4 on: August 25, 2016, 04:20:17 pm »
I did look at WriteStr() but missed that the result gets sent to the first argument...
I also edited my post to include the GetEnumName-example which is what WriteStr() uses internally.

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: [SOLVED] Getting a string representation of an enum value
« Reply #5 on: August 25, 2016, 04:23:33 pm »
Ooooh, a choice now... I actually like the syntax of the GetEnumName version as it seems more 'pure'...

-FM

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: [SOLVED] Getting a string representation of an enum value
« Reply #6 on: August 25, 2016, 04:27:41 pm »
Am I allowed a follow up question  ;) ?

How would I convert back the other way?

So, when I do my .ReadString from my XML config I need to turn the string back into the correct Enum value.

I could achieve it with a case statement, but that seems a bit long winded.

-FM

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: [SOLVED] Getting a string representation of an enum value
« Reply #7 on: August 25, 2016, 04:32:53 pm »
How would I convert back the other way?
That would be with the GetEnumValue();

Code: Pascal  [Select][+][-]
  1. myFavouriteColor := TThreeColors(GetEnumValue(TypeInfo(TThreeColors), 'blue'));

Or of you use this a lot in code you can use some functions:
Code: Pascal  [Select][+][-]
  1. type
  2.   TThreeColors = (red, green, blue);
  3.  
  4. function TThreeColorsToString(Value: TThreeColors): string;
  5. begin
  6.   Result := GetEnumName(typeInfo(TThreeColors), Ord(Value));
  7. end;
  8.  
  9. function StringToTThreeColors(const Value: string): TThreeColors;
  10. begin
  11.   Result := TThreeColors(GetEnumValue(Typeinfo(TThreeColors), Value));
  12. end;
« Last Edit: August 25, 2016, 04:37:03 pm by rvk »

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: [SOLVED] Getting a string representation of an enum value
« Reply #8 on: August 25, 2016, 04:39:28 pm »
I hate that rtti so here's another one based on rvk's code ;)
Code: Pascal  [Select][+][-]
  1. program untitled;
  2. {$ifdef fpc}{$mode objfpc}{$endif}
  3. type
  4.   TThreeColors = (red, green, blue);
  5. var
  6.   myFavouriteColor: TThreeColors;
  7.   Value: string;
  8. begin
  9.   myFavouriteColor := green;
  10.   Writeln(myFavouriteColor); // converts TThreeColors to string ;)
  11. end.

If you don't need a gui, that's the better solution...
Specialize a type, not a var.

derek.john.evans

  • Guest
Re: [SOLVED] Getting a string representation of an enum value
« Reply #9 on: August 25, 2016, 04:58:51 pm »
Cool. Thats going straight to my code bank. With generics I have:

Code: Pascal  [Select][+][-]
  1. uses TypInfo;
  2.  
  3. type
  4.  
  5.   generic DEnumOf<_TType> = object
  6.   public
  7.     type TType = _TType;
  8.   public
  9.     class function ToString(A: TType): string; static;
  10.     class function FromString(A: string): TType; static;
  11.   end;
  12.  
  13. class function DEnumOf.ToString(A: TType): string;
  14. begin
  15.   Result := GetEnumName(TypeInfo(TType), integer(A));
  16. end;
  17.  
  18. class function DEnumOf.FromString(A: string): TType;
  19. begin
  20.   Result := TType(GetEnumValue(Typeinfo(TType), A));
  21. end;  
  22.  

Usage:

Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   TThreeColors = (red, green, blue);
  4.   DThreeColors = specialize DEnumOf<TThreeColors>;
  5.  
  6. procedure TForm1.Button2Click(Sender: TObject);
  7. var
  8.   A: DThreeColors.TType;
  9. begin
  10.   A := red;
  11.   ShowMessage(DThreeColors.ToString(A));
  12.   ShowMessage(DThreeColors.ToString(Succ(DThreeColors.FromString('red'))));
  13. end;  
  14.  

Note: I use the prefix 'D' for descriptor objects.

 

TinyPortal © 2005-2018