Advertisement
GeneralGDA

Compile time checking builder.

Oct 2nd, 2015
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 2.28 KB | None | 0 0
  1. import std.stdio : writeln;
  2.  
  3. private class Ware
  4. {
  5.     void say()
  6.     {
  7.         writeln("hello!");
  8.     }
  9. }
  10.  
  11. private final class Builder(string[] MethodsToCall)
  12. {
  13.     private enum Optional;
  14.     private enum Ignore;
  15.  
  16.     private static string[] listRequiredToCallMethods(T...)()
  17.     {
  18.         import std.traits;
  19.         import std.meta;
  20.  
  21.         alias BuilderType = Builder!([""]);
  22.  
  23.         string[] requiredToCallFunctions = [];
  24.         foreach(member; __traits(allMembers, BuilderType))
  25.         {
  26.             alias is_method = AliasSeq!(MemberFunctionsTuple!(BuilderType, member));
  27.             alias is_system = AliasSeq!(MemberFunctionsTuple!(Object, member));
  28.  
  29.             static if ("prepare" != member && is_method.length > 0 && is_system.length == 0)
  30.             {
  31.                 bool skip = false;
  32.  
  33.                 alias attributes = AliasSeq!(__traits(getAttributes, mixin("BuilderType." ~ member)));
  34.  
  35.                 foreach(attribute; attributes)
  36.                 {
  37.                     static if (__traits(isSame, attribute, BuilderType.Optional)
  38.                         || __traits(isSame, attribute, BuilderType.Ignore))
  39.                     {
  40.                         skip = true;
  41.                     }
  42.                 }
  43.  
  44.                 if (false == skip)
  45.                 {
  46.                     requiredToCallFunctions ~= member;
  47.                 }
  48.             }
  49.         }
  50.  
  51.         return requiredToCallFunctions;
  52.     }
  53.  
  54.     public static auto prepare()
  55.     {
  56.         return new Builder!(listRequiredToCallMethods());
  57.     }
  58.  
  59.     import std.algorithm : remove;
  60.  
  61.     public auto stepOne()
  62.     {
  63.         writeln("step 1 (optional)");
  64.         return new Builder!(remove!(s => s == "stepOne")(MethodsToCall));
  65.     }
  66.  
  67.     public auto stepTwo()
  68.     {
  69.         writeln("step 2 (optional)");
  70.         return new Builder!(remove!(s => s == "stepTwo")(MethodsToCall));
  71.     }
  72.  
  73.     @Ignore
  74.     public void someWiredStuff()
  75.     {
  76.     }
  77.  
  78.     @Optional
  79.     public auto stepThreeOptional()
  80.     {
  81.         writeln("step 3 (optional)");
  82.         return new Builder!(MethodsToCall);
  83.     }
  84.  
  85.     private mixin template MakeWare()
  86.     {
  87.         public Ware build()
  88.         {
  89.             return new Ware();
  90.         }
  91.     }
  92.  
  93.     mixin(0 == MethodsToCall.length ? "mixin MakeWare;" : "");
  94.  
  95.     private int someStrangeField = 0;
  96. }
  97.  
  98. class Test(string[] parameters)
  99. {
  100.     void doTheStuff()
  101.     {
  102.         foreach (i; parameters)
  103.         {
  104.             writeln(i);
  105.         }
  106.     }
  107. }
  108.  
  109. int main(string[] argv)
  110. {
  111.     writeln("Hello D-World!");
  112.  
  113.     auto variable = new Test!(["one", "two"]);
  114.    
  115.     variable.doTheStuff();
  116.  
  117.     auto builder = Builder!([]).prepare();
  118.  
  119.     auto ware = builder
  120.         .stepTwo()
  121.         .stepOne()
  122.         .build();
  123.  
  124.     return 0;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement