[string-templates] Simplify custom processor creation
Brian Goetz
brian.goetz at oracle.com
Mon Nov 27 17:24:14 UTC 2023
I’d like to up-level this discussion a bit from the specific API suggestions, which are of course meant to be evocative examples.
The examples here are obviously useful; I can imagine use cases for all of them. I’m a little concerned about adding them as “point” solutions, though, because I’d have concerns about whether they will work together. Which makes me think that the withToString example might prefer to be an abstract class rather than a combinator, so that if users want to override various things, those will work together.
On Nov 27, 2023, at 12:00 PM, Tagir Valeev <amaembo at gmail.com<mailto:amaembo at gmail.com>> wrote:
Hello!
As we expect that people will create custom template processors, we can simplify their lives.
First, it could be common to add a finisher transformation to an existing processor. I think that for many purposes it would be enough to use STR processor as a starter, and then create a custom domain object from the resulting string. This could be simplified if we add a method 'andThen' to the Processor interface:
default <RR> Processor<RR, E> andThen(Function<R, RR> finisher) {
Objects.requireNonNull(finisher);
return st -> finisher.apply(process(st));
}
Second, I think that many processors may want to keep string parts intact but handle embedded expressions in a special way, effectively replacing the default 'String.valueOf' behavior of the standard STR processor. We can provide a way doing this, encapsulating all the ceremony. Something like this:
static StringTemplate.Processor<String, RuntimeException> withToString(Function<Object, String> toStringFunction) {
Objects.requireNonNull(toStringFunction);
return st -> {
StringBuilder sb = new StringBuilder();
Iterator<String> fragIter = st.fragments().iterator();
for (Object value : st.values()) {
sb.append(fragIter.next());
sb.append(toStringFunction.apply(value));
}
sb.append(fragIter.next());
return sb.toString();
};
}
withToString(String::valueOf) should be equivalent to the STR template (in functionality, not in performance)
Now, one can easily build interesting things like:
StringTemplate.Processor<Pattern, RuntimeException> REGEXP =
withToString(obj -> Pattern.quote(obj.toString())).andThen(Pattern::compile);
What do you think?
With best regards,
Tagir Valeev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20231127/4d241464/attachment-0001.htm>
More information about the amber-spec-observers
mailing list