<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 style="color:rgb(0,0,0)">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 style="color:rgb(0,0,0)">Function</span><<span style="color:rgb(0,126,138)">R</span>, <span style="color:rgb(0,126,138)">RR</span>> <span style="color:rgb(0,0,0)">finisher</span>) {<br>    <span style="color:rgb(0,0,0)">Objects</span>.<span style="font-style:italic">requireNonNull</span>(<span style="color:rgb(0,0,0)">finisher</span>);<br>    <span style="color:rgb(0,66,140);font-weight:bold">return </span><span style="color:rgb(0,0,0)">st </span>-> <span style="color:rgb(25,72,166)">finisher</span>.apply(process(<span style="color:rgb(0,0,0)">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 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(18,19,20)">withToString</span>(<span style="color:rgb(0,0,0)">Function</span><<span style="color:rgb(0,0,0)">Object</span>, <span style="color:rgb(0,0,0)">String</span>> <span style="color:rgb(0,0,0)">toStringFunction</span>) {<br>    <span style="color:rgb(0,0,0)">Objects</span>.<span style="font-style:italic">requireNonNull</span>(<span style="color:rgb(0,0,0)">toStringFunction</span>);<br>    <span style="color:rgb(0,66,140);font-weight:bold">return </span><span style="color:rgb(0,0,0)">st </span>-> {<br>        <span style="color:rgb(0,0,0)">StringBuilder sb </span>= <span style="color:rgb(0,66,140);font-weight:bold">new </span>StringBuilder();<br>        <span style="color:rgb(0,0,0)">Iterator</span><<span style="color:rgb(0,0,0)">String</span>> <span style="color:rgb(0,0,0)">fragIter </span>= <span style="color:rgb(0,0,0)">st</span>.fragments().iterator();<br><br>        <span style="color:rgb(0,66,140);font-weight:bold">for </span>(<span style="color:rgb(0,0,0)">Object value </span>: <span style="color:rgb(0,0,0)">st</span>.values()) {<br>            <span style="color:rgb(0,0,0)">sb</span>.append(<span style="color:rgb(0,0,0)">fragIter</span>.next());<br>            <span style="color:rgb(0,0,0)">sb</span>.append(<span style="color:rgb(25,72,166)">toStringFunction</span>.apply(<span style="color:rgb(0,0,0)">value</span>));<br>        }<br><br>        <span style="color:rgb(0,0,0)">sb</span>.append(<span style="color:rgb(0,0,0)">fragIter</span>.next());<br>        <span style="color:rgb(0,66,140);font-weight:bold">return </span><span style="color:rgb(0,0,0)">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 style="color:rgb(0,0,0)">StringTemplate</span>.<span style="color:rgb(0,0,0)">Processor</span><<span style="color:rgb(0,0,0)">Pattern</span>, <span style="color:rgb(0,0,0)">RuntimeException</span>> <span style="color:rgb(0,75,159);font-style:italic">REGEXP </span>= <br>   <span style="font-style:italic">withToString</span>(<span style="color:rgb(0,0,0)">obj </span>-> <span style="color:rgb(0,0,0)">Pattern</span>.<span style="font-style:italic">quote</span>(<span style="color:rgb(0,0,0)">obj</span>.toString())).andThen(<span style="color:rgb(0,0,0)">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>