1 /// Simple mixin property getter/setter generator 2 module sily.property; 3 4 import std.traits; 5 6 /** 7 Generates mixin for automatic property injection. All properties 8 are created as `public final @property`. 9 10 Important! If symbol with same name, as property going to be, is present 11 then D will completely override property with that symbol 12 13 Example: 14 --- 15 // Generates property for "_data" with name "data" 16 mixin property!_data; 17 // Generates only getter for "_data" with name "data" 18 mixin getter!_data; 19 // Generates only setter for "_data" with name "data" 20 mixin setter!_data; 21 22 // Prefix manipulation, works with getter! and setter! too 23 // _data -> data (removes "_" prefix, default behaviour) 24 mixin property!_data; 25 // __data -> data (removes supplied prefix) 26 mixin property!(__data, "__"); 27 // __data -> gdata (replaces supplied prefix) 28 mixin property!(__data, "__", "g"); 29 // _data -> c_data (adds new prefix) 30 mixin property!(_data, "", "c"); 31 // _data -> _data (can't match prefix, keeping as is) 32 mixin property!(_data, "A"); 33 mixin property!(_data, "A", "B"); 34 // _data -> propertyData (replaces entire name) 35 mixin property!(_data, "propertyData", true); 36 --- 37 */ 38 mixin template property(alias symbol, string prefixRem = "_", string prefixAdd = "") { 39 mixin( ___silyPropertyGenGetter!(symbol, prefixRem, prefixAdd, false) ); 40 mixin( ___silyPropertyGenSetter!(symbol, prefixRem, prefixAdd, false) ); 41 } 42 43 /// Ditto 44 mixin template setter(alias symbol, string prefixRem = "_", string prefixAdd = "") { 45 mixin( ___silyPropertyGenSetter!(symbol, prefixRem, prefixAdd, false) ); 46 } 47 48 /// Ditto 49 mixin template getter(alias symbol, string prefixRem = "_", string prefixAdd = "") { 50 mixin( ___silyPropertyGenGetter!(symbol, prefixRem, prefixAdd, false) ); 51 } 52 53 /// Ditto 54 mixin template property(alias symbol, string symbolRename, bool B) if (B == true) { 55 mixin( ___silyPropertyGenGetter!(symbol, "", symbolRename, true) ); 56 mixin( ___silyPropertyGenSetter!(symbol, "", symbolRename, true) ); 57 } 58 59 /// Ditto 60 mixin template setter(alias symbol, string symbolRename, bool B) if (B == true) { 61 mixin( ___silyPropertyGenSetter!(symbol, "", symbolRename, true) ); 62 } 63 64 /// Ditto 65 mixin template getter(alias symbol, string symbolRename, bool B) if (B == true) { 66 mixin( ___silyPropertyGenGetter!(symbol, "", symbolRename, true) ); 67 } 68 69 static string ___silyPropertyGenGetter(alias symbol, string prefixStringRem, 70 string prefixStringAdd, bool prefixAsRename = false)() { 71 import std.algorithm.searching: countUntil; 72 import std.string: format; 73 import std.array: replaceFirst; 74 string _symname = __traits(identifier, symbol); 75 string _getname = __traits(identifier, symbol); 76 string _type = typeof(symbol).stringof; 77 if (prefixAsRename) { 78 _getname = prefixStringAdd; 79 } else { 80 if (_symname.countUntil(prefixStringRem) == 0) { 81 _getname = _symname.replaceFirst(prefixStringRem, prefixStringAdd); 82 } 83 if (prefixStringRem == "") _getname = prefixStringAdd ~ _symname; 84 } 85 return "public final %s %s() @property { return %s; }".format( 86 _type, _getname, _symname 87 ); 88 } 89 90 static string ___silyPropertyGenSetter(alias symbol, string prefixStringRem, 91 string prefixStringAdd, bool prefixAsRename = false)() { 92 import std.algorithm.searching: countUntil; 93 import std.string: format; 94 import std.array: replaceFirst; 95 string _symname = __traits(identifier, symbol); 96 string _setname = __traits(identifier, symbol); 97 string _type = typeof(symbol).stringof; 98 if (prefixAsRename) { 99 _setname = prefixStringAdd; 100 } else { 101 if (_symname.countUntil(prefixStringRem) == 0) { 102 _setname = _symname.replaceFirst(prefixStringRem, prefixStringAdd); 103 } 104 if (prefixStringRem == "") _setname = prefixStringAdd ~ _symname; 105 } 106 return "public final %s %s(%s p_val) @property { return (%s = p_val); }".format( 107 _type, _setname, _type, _symname 108 ); 109 } 110 111 /* -------------------------- String mixin version -------------------------- */ 112 113 /** 114 Generates string for automatic property injection with string mixin. 115 All properties are created as `public final @property` 116 Example: 117 --- 118 // Generates property for "_data" with name "data" 119 mixin(property!_data); 120 // Generates only getter for "_data" with name "data" 121 mixin(getter!_data); 122 // Generates only setter for "_data" with name "data" 123 mixin(setter!_data); 124 125 // Prefix manipulation, works with getter! and setter! too 126 // _data -> data (removes "_" prefix, default behaviour) 127 mixin(property!_data); 128 // __data -> data (removes supplied prefix) 129 mixin(property!(__data, "__")); 130 // __data -> gdata (replaces supplied prefix) 131 mixin(property!(__data, "__", "g")); 132 // _data -> c_data (adds new prefix) 133 mixin(property!(_data, "", "c")); 134 // _data -> _data (can't match prefix, keeping as is) 135 mixin(property!(_data, "A")); 136 mixin(property!(_data, "A", "B")); 137 // _data -> propertyData (replaces entire name) 138 mixin(property!(_data, "propertyData", true)); 139 --- 140 */ 141 // static string property(alias symbol, string prefixRem = "_", string prefixAdd = "")() { 142 // return ___silyPropertyGenGetter!(symbol, prefixRem, prefixAdd, false) ~ "\n" ~ 143 // ___silyPropertyGenSetter!(symbol, prefixRem, prefixAdd, false); 144 // } 145 146 // /// Ditto 147 // static string setter(alias symbol, string prefixRem = "_", string prefixAdd = "")() { 148 // return ___silyPropertyGenSetter!(symbol, prefixRem, prefixAdd, false); 149 // } 150 151 // /// Ditto 152 // static string getter(alias symbol, string prefixRem = "_", string prefixAdd = "")() { 153 // return ___silyPropertyGenGetter!(symbol, prefixRem, prefixAdd, false); 154 // } 155 156 // /// Ditto 157 // static string property(alias symbol, string symbolRename, bool B)() if (B == true) { 158 // return ___silyPropertyGenGetter!(symbol, "", symbolRename, true) ~ "\n" ~ 159 // ___silyPropertyGenSetter!(symbol, "", symbolRename, true); 160 // } 161 162 // /// Ditto 163 // static string setter(alias symbol, string symbolRename, bool B)() if (B == true) { 164 // return ___silyPropertyGenSetter!(symbol, "", symbolRename, true); 165 // } 166 167 // /// Ditto 168 // static string getter(alias symbol, string symbolRename, bool B)() if (B == true) { 169 // return ___silyPropertyGenGetter!(symbol, "", symbolRename, true); 170 // }