1 module dud.pkgdescription.helper; 2 3 import std.format; 4 import dud.pkgdescription : PackageDescription; 5 6 @safe: 7 8 template PreprocessKey(string key) { 9 import std.algorithm.searching : endsWith; 10 static if(key.endsWith("_")) { 11 enum PreprocessKey = key[0 .. $ - 1]; 12 } else { 13 enum PreprocessKey = key; 14 } 15 } 16 17 string pkgCompare(const PackageDescription a, const PackageDescription b) 18 @trusted 19 { 20 import std.typecons : Nullable; 21 import std.array : appender; 22 import std.traits : isArray, FieldNameTuple; 23 24 auto app = appender!string(); 25 formattedWrite(app, "PackageDescription difference {\n"); 26 static foreach(mem; FieldNameTuple!PackageDescription) {{ 27 auto aMem = __traits(getMember, a, mem); 28 auto bMem = __traits(getMember, b, mem); 29 30 if(aMem != bMem) { 31 static if(is(typeof(aMem) : Nullable!Args, Args...)) { 32 if(aMem.isNull() != bMem.isNull()) { 33 formattedWrite(app, "\ta.%1$s %s b.%1$s %s\n", 34 mem, 35 aMem.isNull() ? "null" : "notNull", 36 bMem.isNull() ? "null" : "notNull" 37 ); 38 } else { 39 assert(false, "This can not happen"); 40 } 41 } else static if(isArray!(typeof(aMem))) { 42 if(aMem.length != bMem.length) { 43 formattedWrite(app, "a.length(%s) != b.length(%s)\n", 44 aMem.length, bMem.length); 45 } else { 46 formattedWrite(app, "\t%s {\n", mem); 47 foreach(idx; 0 .. aMem.length) { 48 if(aMem[idx] != bMem[idx]) { 49 formattedWrite(app, 50 "\t\ta[%s] = %s\n\t\tb[%s] = %s\n", 51 idx, aMem[idx], idx, bMem[idx]); 52 } 53 } 54 formattedWrite(app, "\t}\n"); 55 } 56 } else { 57 formattedWrite(app, "\ta.%s = %s\nb.%s = %s\n", 58 mem, aMem, mem, bMem); 59 } 60 } 61 }} 62 formattedWrite(app, "}\n"); 63 return app.data; 64 } 65 66 template isMem(string name) { 67 static if(__traits(hasMember, PackageDescription, name)) { 68 enum isMem = name; 69 } else { 70 static assert(false, 71 format("'%s' is not a member of PackageDescription", name)); 72 } 73 } 74 75 unittest { 76 static assert(!__traits(compiles, isMem!"foo")); 77 static assert( __traits(compiles, isMem!"name")); 78 }