[External] : Re: [string-templates] Simplify custom processor creation
Jim Laskey
james.laskey at oracle.com
Mon Nov 27 18:11:17 UTC 2023
Okay maybe we just need a mapList method.
static <S, T> List<S> mapList(List<T> list, Function<T, S> mapper) {
return list.stream()
.map(mapper)
.toList();
}
interface AndThenProcessor<R, E extends Throwable> extends StringTemplate.Processor<R, E> {
default <RR> StringTemplate.Processor<RR, E> andThen(Function<R, RR> finisher) {
Objects.requireNonNull(finisher);
return st -> finisher.apply(process(st));
}
}
static AndThenProcessor<String, RuntimeException> withToString(Function<Object, String> toStringFunction) {
Objects.requireNonNull(toStringFunction);
return st -> StringTemplate.interpolate(st.fragments(), mapList(st.values(), toStringFunction));
}
static final StringTemplate.Processor<Pattern, RuntimeException> REGEXP =
withToString(obj -> Pattern.quote(obj.toString())).andThen(Pattern::compile);
public static void main(String... args) {
String name = "Jim";
String surname = "Laskey";
System.out.println(REGEXP."\{surname},\s+\{name}|\{name}\s+\{surname}");
}
\QLaskey\E, +\QJim\E|\QJim\E +\QLaskey\E
On Nov 27, 2023, at 1:44 PM, Tagir Valeev <amaembo at gmail.com> wrote:
Hello, Jim!
It's still a lot of ceremony, so if I need this functionality, I would not use it directly and rather create a function like withToString shown above. I'm not sure that there could be another moving part in common applications, other than object->string conversion. Please correct me if I'm wrong.
With best regards,
Tagir Valeev
On Mon, Nov 27, 2023, 18:40 Jim Laskey <james.laskey at oracle.com<mailto:james.laskey at oracle.com>> wrote:
I’d recommend using the two argument StringTemplate.interpolate for this sort of use case. Process values as a stream and then feed to StringTemplate.interpolate(fragments, values).
static final StringTemplate.Processor<String, RuntimeException> HEXER = st -> {
List<String> values = st.values()
.stream()
.map(v -> v instanceof Integer i ? "0x" + Integer.toHexString(i)
: String.valueOf(v))
.toList();
return StringTemplate.interpolate(st.fragments(), values);
};
public static void main(String... args) {
int x = 10, y = 20;
System.out.println(HEXER."\{x} + \{y} = \{x + y}");
}
0xa + 0x14 = 0x1e
On Nov 27, 2023, at 1: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/55589328/attachment-0001.htm>
More information about the amber-spec-observers
mailing list