1 module graphql.uda; 2 3 import std.traits : isBuiltinType; 4 5 @safe: 6 7 enum TypeKind { 8 UNDEFINED, 9 SCALAR, 10 OBJECT, 11 INTERFACE, 12 UNION, 13 ENUM, 14 INPUT_OBJECT, 15 LIST, 16 NON_NULL 17 } 18 19 struct GQLDUdaData { 20 TypeKind typeKind; 21 GQLDDeprecatedData deprecationInfo; 22 GQLDDescription description; 23 } 24 25 enum IsDeprecated { 26 undefined, 27 yes, 28 no 29 } 30 31 struct GQLDDeprecatedData { 32 IsDeprecated isDeprecated; 33 string deprecationReason; 34 } 35 36 struct GQLDDescription { 37 string text; 38 } 39 40 GQLDDeprecatedData GQLDDeprecated(IsDeprecated isDeprecated) { 41 return GQLDDeprecatedData(isDeprecated, ""); 42 } 43 44 GQLDDeprecatedData GQLDDeprecated(IsDeprecated isDeprecated, 45 string deprecationReason) 46 { 47 return GQLDDeprecatedData(isDeprecated, deprecationReason); 48 } 49 50 GQLDUdaData GQLDUda(Args...)(Args args) { 51 GQLDUdaData ret; 52 static foreach(mem; __traits(allMembers, GQLDUdaData)) { 53 static foreach(arg; args) { 54 static if(is(typeof(__traits(getMember, ret, mem)) == 55 typeof(arg))) 56 { 57 __traits(getMember, ret, mem) = arg; 58 } 59 } 60 } 61 return ret; 62 } 63 64 template isGQLDUdaData(alias Type) { 65 enum isGQLDUdaData = is(typeof(Type) == GQLDUdaData); 66 } 67 68 template getGQLDUdaData(Type, string mem) { 69 import std.meta : Filter; 70 alias getGQLDUdaData = 71 Filter!(isGQLDUdaData, 72 __traits(getAttributes, __traits(getMember, Type, mem))); 73 } 74 75 template getGQLDUdaData(Type) { 76 import std.meta : Filter; 77 alias getGQLDUdaData = 78 Filter!(isGQLDUdaData, __traits(getAttributes, Type)); 79 } 80 81 template getUdaData(Type) { 82 static if(isBuiltinType!Type) { 83 enum getUdaData = GQLDUdaData.init; 84 } else { 85 alias GQLDUdaDataAS = getGQLDUdaData!Type; 86 static if(GQLDUdaDataAS.length > 0) { 87 enum getUdaData = GQLDUdaDataAS[0]; 88 } else { 89 enum getUdaData = GQLDUdaData.init; 90 } 91 } 92 } 93 94 template getUdaData(Type, string mem) { 95 //static if(isBuiltinType!(typeof(__traits(getMember, Type, mem)))) { 96 // enum getUdaData = GQLDUdaData.init; 97 //} else { 98 alias GQLDUdaDataAS = getGQLDUdaData!(Type, mem); 99 static if(GQLDUdaDataAS.length > 0) { 100 enum getUdaData = GQLDUdaDataAS[0]; 101 } else { 102 enum getUdaData = GQLDUdaData.init; 103 } 104 //} 105 } 106 107 unittest { 108 @GQLDUda( 109 GQLDDeprecated(IsDeprecated.yes, "Stupid name"), 110 GQLDDescription("You normal test struct") 111 ) 112 struct Foo { 113 @GQLDUda( 114 GQLDDeprecated(IsDeprecated.no, "Very good name"), 115 GQLDDescription("Contains something") 116 ) 117 int bar; 118 119 int args; 120 } 121 122 enum GQLDUdaData fd = getUdaData!Foo; 123 static assert(fd.deprecationInfo.isDeprecated == IsDeprecated.yes); 124 static assert(fd.deprecationInfo.deprecationReason == "Stupid name"); 125 static assert(fd.description.text == "You normal test struct"); 126 127 enum GQLDUdaData bd = getUdaData!(Foo, "bar"); 128 static assert(bd.deprecationInfo.isDeprecated == IsDeprecated.no); 129 static assert(bd.deprecationInfo.deprecationReason == "Very good name"); 130 static assert(bd.description.text == "Contains something"); 131 132 enum GQLDUdaData ad = getUdaData!(Foo, "args"); 133 static assert(ad.deprecationInfo.isDeprecated == IsDeprecated.undefined); 134 static assert(ad.deprecationInfo.deprecationReason == ""); 135 static assert(ad.description.text == ""); 136 }