Skip to content

Commit ad21c5d

Browse files
authored
new: added Postparser to OptCfg (#7)
1 parent ac2f3cc commit ad21c5d

File tree

5 files changed

+450
-22
lines changed

5 files changed

+450
-22
lines changed

src/main/java/com/github/sttk/cliargs/CliArgs.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,6 @@ public Result parse() {
194194
* <p>
195195
* This method basically allows only options declared in option
196196
* configurations.
197-
* An option configuration has fields: {@code storeKey}, {@code names},
198-
* {@code hasArg}, {@code isArray}, {@code type}, {@code defaults},
199-
* {@code desc}, {@code argInHelp}, and {@code converter}.
200197
* When an option in command line arguments matches one of the {@code names}
201198
* in an option configuration, the option is registered into {@code Cmd} with
202199
* {@code storeKey}.
@@ -212,6 +209,8 @@ public Result parse() {
212209
* converted with the {@code converter}.
213210
* If {@code type} is specified but {@code converter} is not specified,
214211
* a converter which converts a string to the specified type value is set.
212+
* If {@code postparser} is specified, it processes option arguments
213+
* (including those set from default values) after parsing.
215214
* <p>
216215
* If options not declared in option configurations are given in command line
217216
* arguments, this method basically throws a {@link ReasonedException} with

src/main/java/com/github/sttk/cliargs/OptCfg.java

+55-11
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ public class OptCfg {
9595
*/
9696
public final Converter<?> converter;
9797

98+
/**
99+
* Is the function interface that is executed after parsing command line
100+
* arguments.
101+
*/
102+
public final Postparser<?> postparser;
103+
98104
/**
99105
* Is the constructor that takes the all field values as parameters.
100106
* <p>
@@ -120,8 +126,10 @@ public class OptCfg {
120126
* @param defaults The default value(s).
121127
* @param desc The description of the option.
122128
* @param argInHelp The display of the option argument.
123-
* @param converter The converter to convert the option argument string to
124-
* the specified type value.
129+
* @param converter The {@link Converter} object to convert the option
130+
* argument string to the specified type value.
131+
* @param postparser The {@link Postparser} object that is executed after
132+
* parsing command line arguments.
125133
*/
126134
public <T> OptCfg(
127135
String storeKey,
@@ -132,7 +140,8 @@ public <T> OptCfg(
132140
List<T> defaults,
133141
String desc,
134142
String argInHelp,
135-
Converter<T> converter
143+
Converter<T> converter,
144+
Postparser<T> postparser
136145
) {
137146
var init = new Init<T>();
138147
init.storeKey = storeKey;
@@ -144,6 +153,7 @@ public <T> OptCfg(
144153
init.desc = desc;
145154
init.argInHelp = argInHelp;
146155
init.converter = converter;
156+
init.postparser = postparser;
147157

148158
fillmissing(init);
149159

@@ -156,6 +166,7 @@ public <T> OptCfg(
156166
this.desc = init.desc;
157167
this.argInHelp = init.argInHelp;
158168
this.converter = init.converter;
169+
this.postparser = init.postparser;
159170
}
160171

161172
/**
@@ -194,6 +205,7 @@ public <T> OptCfg(NamedParam<T> ...params) {
194205
this.desc = init.desc;
195206
this.argInHelp = init.argInHelp;
196207
this.converter = init.converter;
208+
this.postparser = init.postparser;
197209
}
198210

199211
@SuppressWarnings("unchecked")
@@ -217,21 +229,22 @@ private void fillmissing(Init<?> init) {
217229
}
218230

219231
if (init.type != null && init.converter == null) {
220-
if (init.type.equals(Integer.class)) {
232+
var type = init.type;
233+
if (type.equals(int.class) || type.equals(Integer.class)) {
221234
init.converter = (Converter)new IntConverter();
222-
} else if (init.type.equals(Double.class)) {
235+
} else if (type.equals(double.class) || type.equals(Double.class)) {
223236
init.converter = (Converter)new DoubleConverter();
224-
} else if (init.type.equals(Long.class)) {
237+
} else if (type.equals(long.class) || type.equals(Long.class)) {
225238
init.converter = (Converter)new LongConverter();
226-
} else if (init.type.equals(BigDecimal.class)) {
239+
} else if (type.equals(BigDecimal.class)) {
227240
init.converter = (Converter)new BigDecimalConverter();
228-
} else if (init.type.equals(BigInteger.class)) {
241+
} else if (type.equals(BigInteger.class)) {
229242
init.converter = (Converter)new BigIntConverter();
230-
} else if (init.type.equals(Float.class)) {
243+
} else if (type.equals(float.class) || type.equals(Float.class)) {
231244
init.converter = (Converter)new FloatConverter();
232-
} else if (init.type.equals(Short.class)) {
245+
} else if (type.equals(short.class) || type.equals(Short.class)) {
233246
init.converter = (Converter)new ShortConverter();
234-
} else if (init.type.equals(Byte.class)) {
247+
} else if (type.equals(byte.class) || type.equals(Byte.class)) {
235248
init.converter = (Converter)new ByteConverter();
236249
}
237250
}
@@ -247,6 +260,7 @@ private static class Init<T> {
247260
String desc;
248261
String argInHelp;
249262
Converter<T> converter;
263+
Postparser<T> postparser;
250264
}
251265

252266
/**
@@ -412,5 +426,35 @@ static <T> NamedParam<T> argInHelp(String argInHelp) {
412426
static <T> NamedParam<T> converter(Converter<T> converter) {
413427
return init -> ((Init<T>)init).converter = converter;
414428
}
429+
430+
/**
431+
* Is the static method to set the {@code postparser} field like a named
432+
* parameter.
433+
*
434+
* @param <T> The type of the option argument value.
435+
*
436+
* @param postparser The value of the {@code postparser} field.
437+
* @return The {@link NamedParam} object for {@code postparser} field.
438+
*/
439+
static <T> NamedParam<T> postparser(Postparser<T> postparser) {
440+
return init -> ((Init<T>)init).postparser = postparser;
441+
}
442+
}
443+
444+
/**
445+
* Is the functional interface to process option arguments after parsing
446+
* command line arguments.
447+
*
448+
* @param <T> The type of the option argument value.
449+
*/
450+
@FunctionalInterface
451+
public interface Postparser<T> {
452+
/**
453+
* Processes the option arguments.
454+
*
455+
* @param optArgs The variadic parameters of the option arguments.
456+
* @throws ReasonedException If an abnormality occurs during processing.
457+
*/
458+
void process(List<T> optArgs) throws ReasonedException;
415459
}
416460
}

src/main/java/com/github/sttk/cliargs/ParseWith.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ static Result parse(OptCfg[] optCfgs, String cmdName, String ...cliArgs) {
102102
CmdArgCollector collectArgs = str -> {
103103
args.add(str);
104104
};
105+
105106
OptArgCollector collectOpts = (name, arg) -> {
106107
var i = cfgMap.get(name);
107108
if (i == null) {
@@ -175,9 +176,10 @@ static Result parse(OptCfg[] optCfgs, String cmdName, String ...cliArgs) {
175176
}
176177

177178
for (var cfg : optCfgs) {
179+
@SuppressWarnings("unchecked")
180+
var list = (List<Object>)opts.get(cfg.storeKey);
181+
178182
if (! isEmpty(cfg.defaults)) {
179-
@SuppressWarnings("unchecked")
180-
var list = (List<Object>)opts.get(cfg.storeKey);
181183
if (list == null) {
182184
list = new ArrayList<>();
183185
opts.put(cfg.storeKey, list);
@@ -186,9 +188,24 @@ static Result parse(OptCfg[] optCfgs, String cmdName, String ...cliArgs) {
186188
list.addAll(cfg.defaults);
187189
}
188190
}
191+
192+
if (cfg.postparser != null && list != null) {
193+
try {
194+
postprocess(cfg, list);
195+
} catch (ReasonedException e) {
196+
if (exc == null) {
197+
exc = e;
198+
}
199+
}
200+
}
189201
}
190202

191203
var cmd = new Cmd(cmdName, args, opts);
192204
return new Result(cmd, optCfgs, exc);
193205
}
206+
207+
@SuppressWarnings({"unchecked", "rawtypes"})
208+
static void postprocess(OptCfg c, List<Object> l) throws ReasonedException {
209+
c.postparser.process((List)l);
210+
}
194211
}

0 commit comments

Comments
 (0)