如何使用picocli处理具有多种类型的选项

brccelvz  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(435)

我正在将现有的应用程序转换为使用picocli。现有选项之一如下所示:

-t, --threads           [1, n] for fixed thread pool, 'cpus' for number of cpus, 'cached' for cached

这允许选项为正整数或两个特殊字符串中的一个。现有代码将其视为字符串,如果它不是特殊字符串之一,则将其传递给 Integer.parseInt .
当然,我可以对皮科利做同样的事情,但我想知道是否有更好的方法来处理这个问题。e、 例如,允许对同一个选项使用多个字段,并根据传递的内容填写相应的字段?这可能还允许我对可能的字符串选项使用枚举。

new9mtju

new9mtju1#

一个想法是为这个创建一个类,比如,也许 ThreadPoolSize ,它封装了固定数值或动态值的枚举。您需要为此数据类型创建一个自定义转换器。
然后可以按如下方式定义选项:

@Option(names = { "-t", "--threads" }, converter = ThreadPoolSizeConverter.class,
  description = "[1, n] for fixed thread pool, 'cpus' for number of cpus, 'cached' for cached")
ThreadPoolSize threadPoolSize;

线程池大小和转换器的自定义数据类型可以如下所示:

class ThreadPoolSize {
    enum Dynamic { cpus, cached }

    int fixed = -1;  // if -1, then use the dynamic value
    Dynamic dynamic; // if null, then use the fixed value
}

class ThreadPoolSizeConverter implements CommandLine.ITypeConverter<ThreadPoolSize> {

    @Override
    public ThreadPoolSize convert(String value) throws Exception {
        ThreadPoolSize result = new ThreadPoolSize();
        try {
            result.fixed = Integer.parseInt(value);
            if (result.fixed < 1) {
                throw new CommandLine.TypeConversionException("Invalid value " +
                        value + ": must be 1 or more.");
            }
        } catch (NumberFormatException nan) {
            try {
                result.dynamic = ThreadPoolSize.Dynamic.valueOf(
                        value.toLowerCase(Locale.ENGLISH));
            } catch (IllegalArgumentException ex) {
                throw new CommandLine.TypeConversionException("Invalid value " +
                        value + ": must be one of " + 
                        Arrays.toString(ThreadPoolSize.Dynamic.values()));
            }
        }
        return result;
    }
}

相关问题