1 module examples.strutil; 2 3 import std.stdio; 4 import std.string; 5 import std.regex; 6 import std.range; 7 import std.array : array; 8 import std.format; 9 import std.process; 10 import cmdline; 11 12 mixin template ConfigCmd() { 13 mixin BEGIN; 14 mixin DESC!("CLI to some string utilities"); 15 mixin VERSION!("0.0.1"); 16 17 mixin CONFIG; 18 mixin PASS_THROUGH; 19 20 mixin SUB_CMD!(JoinResult, SplitResult, ReplaceResult); 21 22 mixin DEF!( 23 "flag", bool, 24 Flag_d!"-f", 25 Desc_d!"the global flag" 26 ); 27 28 mixin DEF!( 29 "greet", string, 30 Flag_d!"-g [greeting]", 31 Desc_d!"set the greeting string", 32 Default_d!"hi!", 33 Preset_d!"hello!", 34 Negate_d!("-G", "opposite to `--greet`"), 35 Export_d!("-x", "-y", "-z", "--xyz"), 36 N_Export_d!("-X", "-Y", "-Z", "--XYZ") 37 ); 38 39 mixin END; 40 } 41 42 mixin template ConfigSplitCmd() { 43 mixin BEGIN; 44 mixin ALIAS!("spl"); 45 mixin DESC!("Split a string into substrings and display as an array."); 46 47 mixin DEF!( 48 "str", string, 49 Desc_d!"string to split" 50 ); 51 52 mixin DEF!( 53 "separator", string, 54 Flag_d!"-s <char>", 55 Desc_d!"separator character", 56 Default_d!",", 57 ToArg_d, 58 ); 59 60 mixin END; 61 62 void action() { 63 StrutilResult* parent = this.getParent!StrutilResult; 64 writeln(parent.flag ? true : false); 65 writeln(parent.greet ? parent.greet.get : "no greeting"); 66 string s = str.get; 67 string sp = separator.get; 68 writeln(split(s, sp)); 69 } 70 } 71 72 mixin template ConfigJoinCmd() { 73 mixin BEGIN; 74 mixin ALIAS!("jr"); 75 mixin DESC!("Join the command-arguments into a single string."); 76 77 mixin DEF!( 78 "strs", string[], 79 Desc_d!"one or more string" 80 ); 81 82 mixin DEF!( 83 "separator", string, 84 Flag_d!"-s <char>", 85 Desc_d!"separator character", 86 Default_d!"," 87 ); 88 89 mixin END; 90 91 void action() { 92 StrutilResult* parent = this.getParent!StrutilResult; 93 writeln(parent.flag ? true : false); 94 writeln(parent.greet ? parent.greet.get : "no greeting"); 95 auto ss = strs.get; 96 auto sp = separator.get; 97 writeln(ss.join(sp)); 98 } 99 } 100 101 mixin template ConfigReplaceCmd() { 102 mixin BEGIN; 103 mixin ALIAS!("rpl"); 104 mixin DESC!("Replace the specified string with new string on a string"); 105 106 mixin DEF_ARG!( 107 "str", string, 108 Desc_d!"the string that would be mutated" 109 ); 110 111 mixin DEF_OPT!( 112 "ptr", string, "-p <ptr>", 113 Desc_d!"the pattern to search for", 114 ToArg_d 115 ); 116 117 mixin DEF_OPT!( 118 "rpl", string, "-r <replacent>", 119 Desc_d!"the replacent string", 120 ToArg_d 121 ); 122 123 OptVal!(bool, "-i") igc; 124 mixin DESC_OPT!(igc, "ignore the lower and upper cases"); 125 126 OptVal!(bool, "-g") glb; 127 mixin DESC_OPT!(glb, "global search all the satisfied string"); 128 129 OptVal!(bool, "-m") mlt; 130 mixin DESC_OPT!(mlt, "allow multipule line search"); 131 132 OptVal!(bool, "-c") cmp; 133 mixin DESC_OPT!(cmp, "show the comparision"); 134 135 mixin END; 136 137 void action() { 138 StrutilResult* parent = this.getParent!StrutilResult; 139 writeln(parent.flag ? true : false); 140 writeln(parent.greet ? parent.greet.get : "no greeting"); 141 string _str = this.str.get; 142 string _ptr = this.ptr.get; 143 string _rstr = this.rpl.get; 144 string _igc = this.igc ? "i" : ""; 145 string _glb = this.glb ? "g" : ""; 146 string _mlt = this.mlt ? "m" : ""; 147 version (Windows) { 148 enum os_num = 0; 149 } 150 else version (Posix) { 151 enum os_num = 1; 152 } 153 bool is_cmp = this.cmp && os_num; 154 auto fmt = `\033[36m%s\033[0m`; 155 auto fn = (Captures!string m) { 156 string tmp = '_'.repeat.take(m.hit.length).array; 157 return _rstr.length 158 ? (is_cmp ? format(fmt, _rstr) : _rstr) : (is_cmp ? format(fmt, tmp) : tmp); 159 }; 160 auto pattern = regex(_ptr, join([_igc, _glb, _mlt], "")); 161 string new_str = replace!(fn)(_str, pattern); 162 auto ostr = is_cmp ? format("echo -e \"%s\"", new_str) : format("echo \"%s\"", new_str); 163 auto result = executeShell(ostr); 164 write(result.output); 165 } 166 } 167 168 struct SplitResult { 169 mixin ConfigSplitCmd; 170 } 171 172 struct JoinResult { 173 mixin ConfigJoinCmd; 174 } 175 176 struct ReplaceResult { 177 mixin ConfigReplaceCmd; 178 } 179 180 struct StrutilResult { 181 mixin ConfigCmd; 182 } 183 184 void main(in string[] argv) { 185 argv.run!StrutilResult; 186 }