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 <[email protected]> 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 <[email protected]> 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 > > >
