View mode: basic / threaded / horizontal-split · Log in · Help
February 29, 2012
Pretty fields string
I've done this a couple of times before but I always had issues, e.g.
functions and property calls would be mixed in. But I think I have a
good go-to function now:

import std.algorithm;
import std.conv;
import std.string;
import std.stdio;
import std.range;

struct Foo
{
   int one = 1;
   @property int test() { return 1; }
   int three = 3;
   string[string] aa;
   string toString() { return prettyFieldsString(this); }
}

string prettyFieldsString(T)(T t)
   if (is(T == struct) || is(T == class))
{
   Appender!string result;
   Appender!(string[]) fields;
   Appender!(string[]) values;

   foreach (member; __traits(allMembers, T))
   {
       mixin("
       static if (!is( FunctionTypeOf!(t." ~ member ~ ") ))
       {
           static if (member != " ~ `"toString"` ~ ")
           {
               fields.put(member);
               values.put(to!string(__traits(getMember, t, " ~ `"` ~
member ~ `"` ~ ")));
           }
       }
       ");
   }

   size_t spaceLen = 1;
   foreach (field; fields.data)  // should use reduce!() here..
       spaceLen = max(spaceLen, field.length);

   alias std.array.replicate replicate;
   string spaceString = replicate(" ", spaceLen);

   foreach (field, value; lockstep(fields.data, values.data))
       result.put(format("%s: %s%s\n", field, replicate(" ", spaceLen
- field.length), value));

   return result.data;
}

void main()
{
   Foo foo;
   foo.aa["foo"] = "bar";
   writeln(foo);
}

Sample output: http://paste.pocoo.org/show/558492/

I've had to put everything into one foreach loop since there are still
some CTFE bugs I run into. I also had to add a check against toString,
otherwise I get an infinite loop in the toString() call.

Anyway, feel free to use/improve this function.
February 29, 2012
Re: Pretty fields string
On 2012-02-29 10:58, Andrej Mitrovic wrote:
> I've done this a couple of times before but I always had issues, e.g.
> functions and property calls would be mixed in. But I think I have a
> good go-to function now:
>
> import std.algorithm;
> import std.conv;
> import std.string;
> import std.stdio;
> import std.range;
>
> struct Foo
> {
>      int one = 1;
>      @property int test() { return 1; }
>      int three = 3;
>      string[string] aa;
>      string toString() { return prettyFieldsString(this); }
> }
>
> string prettyFieldsString(T)(T t)
>      if (is(T == struct) || is(T == class))
> {
>      Appender!string result;
>      Appender!(string[]) fields;
>      Appender!(string[]) values;
>
>      foreach (member; __traits(allMembers, T))
>      {
>          mixin("
>          static if (!is( FunctionTypeOf!(t." ~ member ~ ") ))
>          {
>              static if (member != " ~ `"toString"` ~ ")
>              {
>                  fields.put(member);
>                  values.put(to!string(__traits(getMember, t, " ~ `"` ~
> member ~ `"` ~ ")));
>              }
>          }
>          ");
>      }
>
>      size_t spaceLen = 1;
>      foreach (field; fields.data)  // should use reduce!() here..
>          spaceLen = max(spaceLen, field.length);
>
>      alias std.array.replicate replicate;
>      string spaceString = replicate(" ", spaceLen);
>
>      foreach (field, value; lockstep(fields.data, values.data))
>          result.put(format("%s: %s%s\n", field, replicate(" ", spaceLen
> - field.length), value));
>
>      return result.data;
> }
>
> void main()
> {
>      Foo foo;
>      foo.aa["foo"] = "bar";
>      writeln(foo);
> }
>
> Sample output: http://paste.pocoo.org/show/558492/
>
> I've had to put everything into one foreach loop since there are still
> some CTFE bugs I run into. I also had to add a check against toString,
> otherwise I get an infinite loop in the toString() call.
>
> Anyway, feel free to use/improve this function.

Seems like what I have in my serialization library Orange:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d

"fieldsOf" and "getValueOfField". These work only on instance variables 
and don't care if the variable is public or not.

-- 
/Jacob Carlborg
February 29, 2012
Re: Pretty fields string
On 2/29/12, Jacob Carlborg <doob@me.com> wrote:
> Seems like what I have in my serialization library Orange:

Sweet. I was gonna take a look at Orange for just this purpose. Thanks.
Top | Discussion index | About this forum | D home