<div dir="auto">Hello, Jim!<div dir="auto"><br></div><div dir="auto">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.</div><div dir="auto"><br></div><div dir="auto">With best regards,</div><div dir="auto">Tagir Valeev </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 27, 2023, 18:40 Jim Laskey <<a href="mailto:james.laskey@oracle.com">james.laskey@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div style="line-break:after-white-space">
I’d recommend using the two argument <span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">StringTemplate</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);background-color:rgb(255,255,255)">.</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);font-style:italic">interpolate</span> for
 this sort of use case. Process values as a stream and then feed to <span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">StringTemplate</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);background-color:rgb(255,255,255)">.</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);font-style:italic">interpolate</span><span style="color:rgb(8,8,8);font-family:"JetBrains Mono",monospace;font-size:9.8pt;background-color:rgb(255,255,255)">(</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);background-color:rgb(255,255,255)">fragments,
</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">values</span><span style="font-family:"JetBrains Mono",monospace;font-size:9.8pt;color:rgb(8,8,8);background-color:rgb(255,255,255)">).</span>
<div>
<div style="background-color:rgb(255,255,255);color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(0,51,179)">static final </span><span style="color:rgb(0,0,0)">StringTemplate</span>.<span style="color:rgb(0,0,0)">Processor</span><<span style="color:rgb(0,0,0)">String</span>, <span style="color:rgb(0,0,0)">RuntimeException</span>> <span style="color:rgb(135,16,148);font-style:italic">HEXER </span>= st -> {<br>    <span style="color:rgb(0,0,0)">List</span><<span style="color:rgb(0,0,0)">String</span>> <span style="color:rgb(0,0,0)">values </span>= st.values()<br>            .stream()<br>            .map(v -> v <span style="color:rgb(0,51,179)">instanceof </span><span style="color:rgb(0,0,0)">Integer </span>i ? <span style="color:rgb(6,125,23)">"0x" </span>+ <span style="color:rgb(0,0,0)">Integer</span>.<span style="font-style:italic">toHexString</span>(i)<br>                                             : <span style="color:rgb(0,0,0)">String</span>.<span style="font-style:italic">valueOf</span>(v))<br>            .toList();<br>    <span style="color:rgb(0,51,179)">return  </span><span style="color:rgb(0,0,0)">StringTemplate</span>.<span style="font-style:italic">interpolate</span>(st.fragments(), <span style="color:rgb(0,0,0)">values</span>);<br> };<br><br><span style="color:rgb(0,51,179)">public static void </span><span style="color:rgb(0,98,122)">main</span>(<span style="color:rgb(0,0,0)">String</span>... args) {<br>    <span style="color:rgb(0,51,179)">int </span><span style="color:rgb(0,0,0)">x </span>= <span style="color:rgb(23,80,235)">10</span>, <span style="color:rgb(0,0,0)">y </span>= <span style="color:rgb(23,80,235)">20</span>;<br>    <span style="color:rgb(0,0,0)">System</span>.<span style="color:rgb(135,16,148);font-style:italic">out</span>.println(<span style="color:rgb(135,16,148);font-style:italic">HEXER</span>.<span style="color:rgb(6,125,23)">"\{</span><span style="color:rgb(0,0,0)">x</span><span style="color:rgb(6,125,23)">} + \{</span><span style="color:rgb(0,0,0)">y</span><span style="color:rgb(6,125,23)">} = \{</span><span style="color:rgb(0,0,0)">x </span>+ <span style="color:rgb(0,0,0)">y</span><span style="color:rgb(6,125,23)">}"</span>);<br>}<br></pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><br></pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt">0xa + 0x14 = 0x1e</pre>
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><br></pre>
</div>
<div><br>
<blockquote type="cite">
<div>On Nov 27, 2023, at 1:00 PM, Tagir Valeev <<a href="mailto:amaembo@gmail.com" target="_blank" rel="noreferrer">amaembo@gmail.com</a>> wrote:</div>
<br>
<div>
<div dir="ltr">Hello!<br>
<div><br>
</div>
<div>As we expect that people will create custom template processors, we can simplify their lives.</div>
<div><br>
</div>
<div>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:</div>
<div><br>
</div>
<div>
<div style="color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace"><span style="color:rgb(0,66,140);font-weight:bold">default </span><<span style="color:rgb(0,126,138)">RR</span>> <span>Processor</span><<span style="color:rgb(0,126,138)">RR</span>, <span style="color:rgb(0,126,138)">E</span>> <span style="color:rgb(18,19,20)">andThen</span>(<span>Function</span><<span style="color:rgb(0,126,138)">R</span>, <span style="color:rgb(0,126,138)">RR</span>> <span>finisher</span>) {<br>    <span>Objects</span>.<span style="font-style:italic">requireNonNull</span>(<span>finisher</span>);<br>    <span style="color:rgb(0,66,140);font-weight:bold">return </span><span>st </span>-> <span style="color:rgb(25,72,166)">finisher</span>.apply(process(<span>st</span>));<br>}<br></pre>
</div>
</div>
<div>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:</div>
<div><br>
</div>
<div>
<div style="color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace"><span style="color:rgb(0,66,140);font-weight:bold">static </span><span>StringTemplate</span>.<span>Processor</span><<span>String</span>, <span>RuntimeException</span>> <span style="color:rgb(18,19,20)">withToString</span>(<span>Function</span><<span>Object</span>, <span>String</span>> <span>toStringFunction</span>) {<br>    <span>Objects</span>.<span style="font-style:italic">requireNonNull</span>(<span>toStringFunction</span>);<br>    <span style="color:rgb(0,66,140);font-weight:bold">return </span><span>st </span>-> {<br>        <span>StringBuilder sb </span>= <span style="color:rgb(0,66,140);font-weight:bold">new </span>StringBuilder();<br>        <span>Iterator</span><<span>String</span>> <span>fragIter </span>= <span>st</span>.fragments().iterator();<br><br>        <span style="color:rgb(0,66,140);font-weight:bold">for </span>(<span>Object value </span>: <span>st</span>.values()) {<br>            <span>sb</span>.append(<span>fragIter</span>.next());<br>            <span>sb</span>.append(<span style="color:rgb(25,72,166)">toStringFunction</span>.apply(<span>value</span>));<br>        }<br><br>        <span>sb</span>.append(<span>fragIter</span>.next());<br>        <span style="color:rgb(0,66,140);font-weight:bold">return </span><span>sb</span>.toString();<br>    };<br>}<br></pre>
</div>
</div>
<div>withToString(String::valueOf) should be equivalent to the STR template (in functionality, not in performance)<br>
</div>
<div><br>
</div>
<div>Now, one can easily build interesting things like:</div>
<div><br>
</div>
<div>
<div style="color:rgb(8,8,8)">
<pre style="font-family:"JetBrains Mono",monospace"><span>StringTemplate</span>.<span>Processor</span><<span>Pattern</span>, <span>RuntimeException</span>> <span style="color:rgb(0,75,159);font-style:italic">REGEXP </span>= <br>   <span style="font-style:italic">withToString</span>(<span>obj </span>-> <span>Pattern</span>.<span style="font-style:italic">quote</span>(<span>obj</span>.toString())).andThen(<span>Pattern</span>::<span style="font-style:italic">compile</span>);<br></pre>
</div>
</div>
<div><br>
</div>
<div>What do you think?</div>
<div><br>
</div>
<div>With best regards,</div>
<div>Tagir Valeev</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>

</blockquote></div>