Open samekmichal opened 8 years ago
Durations seem very common in config files (timeouts, intervals, etc.) while I think this is the first feature request for dates and times. We can leave the issue open and see how often it comes up.
We do need to limit the size of our API at some point... to the extent that these would do a Config.getString
and then pass the string to a parser from the JDK and no more, it may not be worth it to include these. Aside from frequency of use, durations are a bit different because we have to implement that parser/syntax ourselves.
But, let's leave the issue here to think about and for people to comment on. Thanks for bringing it up.
How about introducing some kind of plugin mechanism for parsers/codecs as is implemented for example in com.fasterxml.jackson.datatype
and for the most common api have different artefacts.
Or simpler, just introducing a way how to "define" custom parsers.
What would that do though? It couldn't add methods to the Config interface could it? There's no need for anything special in the library other than to add methods there. The types like Duration aren't present on the parser level, they are interpretations of the already-parsed values. We only parse JSON types.
No, I probably didn't express myself correctly. I don't have any particular implementation in mind, but what I meant could be accomplished for example in a manner demonstrated in the following simplistic snippet.
//Instantiated on a global level, filled with the modules/plugins
final Map<Class<?>, Function<String, Object>> TYPE_FACTORIES = new HashMap<>();
TYPE_FACTORIES.put(LocalDate.class, (Function<String, Object>) LocalDate::parse);
public <T> T getOther(String path, Class<T> type) {
final ConfigValue v = find(path, ConfigValueType.STRING);
final Function<String, Object> valueFactory = TYPE_FACTORIES.get(type);
if (valueFactory == null) {
throw new ConfigException.WrongType(v.origin(), "Unregistered value");
}
final Object value = valueFactory.apply((String) v.unwrapped());
return (T) value;
}
The factories would be registered during runtime. Basically, they would not influence parsing in any way, only ease the construction of the desired value with a specific type (LocalDate, URI, ...), so the user in the end does not need to take care of this.
Got it. I would recommend writing functions that don't need the runtime registry; like
static Day getDay(Config config, String path)
.
MyParsers.getDay(config, "/foo")
looks prettier than config.getOther("/foo", Day.class)
I thinkMaybe I'm missing some benefits of the registry though.
A benefit of a registry would be that things can be registered and unregistered and reregistered at runtime. Not only can what Function is used to parse the value be changed at any point, but a value can be passed around from class to class, of some miscellaneous type, and parsed at the end, without any of the classes even knowing what type it is.
I'd second the request to allow direct parsing of dates and times. Think about cron style configuration values on when to run a certain job.
The biggest problem I see is the myriad of date/time formats. You'd either have to limit yourself to specific formats or you'd have to be able to define the format. Both options aren't really "nice".
Currently, only parsing of
Duration
values is implemented. However, in the new javatime
API there are many more classes that would be nice to have parsed from the config files; such asLocalDate
LocalTime
LocalDateTime
Day
Month