blob: c3a192608bc040cfbce090d15933c7602ddc2684 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `/root/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-syntax-0.7.2/src/hir/literal.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>literal.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../source-script.js"></script><script defer src="../../../source-files.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><a class="sidebar-logo" href="../../../regex_syntax/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><nav class="sub"><a class="sub-logo-container" href="../../../regex_syntax/index.html"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></a><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></div></form></nav><section id="main-content" class="content"><div class="example-wrap"><pre class="src-line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
<span id="536">536</span>
<span id="537">537</span>
<span id="538">538</span>
<span id="539">539</span>
<span id="540">540</span>
<span id="541">541</span>
<span id="542">542</span>
<span id="543">543</span>
<span id="544">544</span>
<span id="545">545</span>
<span id="546">546</span>
<span id="547">547</span>
<span id="548">548</span>
<span id="549">549</span>
<span id="550">550</span>
<span id="551">551</span>
<span id="552">552</span>
<span id="553">553</span>
<span id="554">554</span>
<span id="555">555</span>
<span id="556">556</span>
<span id="557">557</span>
<span id="558">558</span>
<span id="559">559</span>
<span id="560">560</span>
<span id="561">561</span>
<span id="562">562</span>
<span id="563">563</span>
<span id="564">564</span>
<span id="565">565</span>
<span id="566">566</span>
<span id="567">567</span>
<span id="568">568</span>
<span id="569">569</span>
<span id="570">570</span>
<span id="571">571</span>
<span id="572">572</span>
<span id="573">573</span>
<span id="574">574</span>
<span id="575">575</span>
<span id="576">576</span>
<span id="577">577</span>
<span id="578">578</span>
<span id="579">579</span>
<span id="580">580</span>
<span id="581">581</span>
<span id="582">582</span>
<span id="583">583</span>
<span id="584">584</span>
<span id="585">585</span>
<span id="586">586</span>
<span id="587">587</span>
<span id="588">588</span>
<span id="589">589</span>
<span id="590">590</span>
<span id="591">591</span>
<span id="592">592</span>
<span id="593">593</span>
<span id="594">594</span>
<span id="595">595</span>
<span id="596">596</span>
<span id="597">597</span>
<span id="598">598</span>
<span id="599">599</span>
<span id="600">600</span>
<span id="601">601</span>
<span id="602">602</span>
<span id="603">603</span>
<span id="604">604</span>
<span id="605">605</span>
<span id="606">606</span>
<span id="607">607</span>
<span id="608">608</span>
<span id="609">609</span>
<span id="610">610</span>
<span id="611">611</span>
<span id="612">612</span>
<span id="613">613</span>
<span id="614">614</span>
<span id="615">615</span>
<span id="616">616</span>
<span id="617">617</span>
<span id="618">618</span>
<span id="619">619</span>
<span id="620">620</span>
<span id="621">621</span>
<span id="622">622</span>
<span id="623">623</span>
<span id="624">624</span>
<span id="625">625</span>
<span id="626">626</span>
<span id="627">627</span>
<span id="628">628</span>
<span id="629">629</span>
<span id="630">630</span>
<span id="631">631</span>
<span id="632">632</span>
<span id="633">633</span>
<span id="634">634</span>
<span id="635">635</span>
<span id="636">636</span>
<span id="637">637</span>
<span id="638">638</span>
<span id="639">639</span>
<span id="640">640</span>
<span id="641">641</span>
<span id="642">642</span>
<span id="643">643</span>
<span id="644">644</span>
<span id="645">645</span>
<span id="646">646</span>
<span id="647">647</span>
<span id="648">648</span>
<span id="649">649</span>
<span id="650">650</span>
<span id="651">651</span>
<span id="652">652</span>
<span id="653">653</span>
<span id="654">654</span>
<span id="655">655</span>
<span id="656">656</span>
<span id="657">657</span>
<span id="658">658</span>
<span id="659">659</span>
<span id="660">660</span>
<span id="661">661</span>
<span id="662">662</span>
<span id="663">663</span>
<span id="664">664</span>
<span id="665">665</span>
<span id="666">666</span>
<span id="667">667</span>
<span id="668">668</span>
<span id="669">669</span>
<span id="670">670</span>
<span id="671">671</span>
<span id="672">672</span>
<span id="673">673</span>
<span id="674">674</span>
<span id="675">675</span>
<span id="676">676</span>
<span id="677">677</span>
<span id="678">678</span>
<span id="679">679</span>
<span id="680">680</span>
<span id="681">681</span>
<span id="682">682</span>
<span id="683">683</span>
<span id="684">684</span>
<span id="685">685</span>
<span id="686">686</span>
<span id="687">687</span>
<span id="688">688</span>
<span id="689">689</span>
<span id="690">690</span>
<span id="691">691</span>
<span id="692">692</span>
<span id="693">693</span>
<span id="694">694</span>
<span id="695">695</span>
<span id="696">696</span>
<span id="697">697</span>
<span id="698">698</span>
<span id="699">699</span>
<span id="700">700</span>
<span id="701">701</span>
<span id="702">702</span>
<span id="703">703</span>
<span id="704">704</span>
<span id="705">705</span>
<span id="706">706</span>
<span id="707">707</span>
<span id="708">708</span>
<span id="709">709</span>
<span id="710">710</span>
<span id="711">711</span>
<span id="712">712</span>
<span id="713">713</span>
<span id="714">714</span>
<span id="715">715</span>
<span id="716">716</span>
<span id="717">717</span>
<span id="718">718</span>
<span id="719">719</span>
<span id="720">720</span>
<span id="721">721</span>
<span id="722">722</span>
<span id="723">723</span>
<span id="724">724</span>
<span id="725">725</span>
<span id="726">726</span>
<span id="727">727</span>
<span id="728">728</span>
<span id="729">729</span>
<span id="730">730</span>
<span id="731">731</span>
<span id="732">732</span>
<span id="733">733</span>
<span id="734">734</span>
<span id="735">735</span>
<span id="736">736</span>
<span id="737">737</span>
<span id="738">738</span>
<span id="739">739</span>
<span id="740">740</span>
<span id="741">741</span>
<span id="742">742</span>
<span id="743">743</span>
<span id="744">744</span>
<span id="745">745</span>
<span id="746">746</span>
<span id="747">747</span>
<span id="748">748</span>
<span id="749">749</span>
<span id="750">750</span>
<span id="751">751</span>
<span id="752">752</span>
<span id="753">753</span>
<span id="754">754</span>
<span id="755">755</span>
<span id="756">756</span>
<span id="757">757</span>
<span id="758">758</span>
<span id="759">759</span>
<span id="760">760</span>
<span id="761">761</span>
<span id="762">762</span>
<span id="763">763</span>
<span id="764">764</span>
<span id="765">765</span>
<span id="766">766</span>
<span id="767">767</span>
<span id="768">768</span>
<span id="769">769</span>
<span id="770">770</span>
<span id="771">771</span>
<span id="772">772</span>
<span id="773">773</span>
<span id="774">774</span>
<span id="775">775</span>
<span id="776">776</span>
<span id="777">777</span>
<span id="778">778</span>
<span id="779">779</span>
<span id="780">780</span>
<span id="781">781</span>
<span id="782">782</span>
<span id="783">783</span>
<span id="784">784</span>
<span id="785">785</span>
<span id="786">786</span>
<span id="787">787</span>
<span id="788">788</span>
<span id="789">789</span>
<span id="790">790</span>
<span id="791">791</span>
<span id="792">792</span>
<span id="793">793</span>
<span id="794">794</span>
<span id="795">795</span>
<span id="796">796</span>
<span id="797">797</span>
<span id="798">798</span>
<span id="799">799</span>
<span id="800">800</span>
<span id="801">801</span>
<span id="802">802</span>
<span id="803">803</span>
<span id="804">804</span>
<span id="805">805</span>
<span id="806">806</span>
<span id="807">807</span>
<span id="808">808</span>
<span id="809">809</span>
<span id="810">810</span>
<span id="811">811</span>
<span id="812">812</span>
<span id="813">813</span>
<span id="814">814</span>
<span id="815">815</span>
<span id="816">816</span>
<span id="817">817</span>
<span id="818">818</span>
<span id="819">819</span>
<span id="820">820</span>
<span id="821">821</span>
<span id="822">822</span>
<span id="823">823</span>
<span id="824">824</span>
<span id="825">825</span>
<span id="826">826</span>
<span id="827">827</span>
<span id="828">828</span>
<span id="829">829</span>
<span id="830">830</span>
<span id="831">831</span>
<span id="832">832</span>
<span id="833">833</span>
<span id="834">834</span>
<span id="835">835</span>
<span id="836">836</span>
<span id="837">837</span>
<span id="838">838</span>
<span id="839">839</span>
<span id="840">840</span>
<span id="841">841</span>
<span id="842">842</span>
<span id="843">843</span>
<span id="844">844</span>
<span id="845">845</span>
<span id="846">846</span>
<span id="847">847</span>
<span id="848">848</span>
<span id="849">849</span>
<span id="850">850</span>
<span id="851">851</span>
<span id="852">852</span>
<span id="853">853</span>
<span id="854">854</span>
<span id="855">855</span>
<span id="856">856</span>
<span id="857">857</span>
<span id="858">858</span>
<span id="859">859</span>
<span id="860">860</span>
<span id="861">861</span>
<span id="862">862</span>
<span id="863">863</span>
<span id="864">864</span>
<span id="865">865</span>
<span id="866">866</span>
<span id="867">867</span>
<span id="868">868</span>
<span id="869">869</span>
<span id="870">870</span>
<span id="871">871</span>
<span id="872">872</span>
<span id="873">873</span>
<span id="874">874</span>
<span id="875">875</span>
<span id="876">876</span>
<span id="877">877</span>
<span id="878">878</span>
<span id="879">879</span>
<span id="880">880</span>
<span id="881">881</span>
<span id="882">882</span>
<span id="883">883</span>
<span id="884">884</span>
<span id="885">885</span>
<span id="886">886</span>
<span id="887">887</span>
<span id="888">888</span>
<span id="889">889</span>
<span id="890">890</span>
<span id="891">891</span>
<span id="892">892</span>
<span id="893">893</span>
<span id="894">894</span>
<span id="895">895</span>
<span id="896">896</span>
<span id="897">897</span>
<span id="898">898</span>
<span id="899">899</span>
<span id="900">900</span>
<span id="901">901</span>
<span id="902">902</span>
<span id="903">903</span>
<span id="904">904</span>
<span id="905">905</span>
<span id="906">906</span>
<span id="907">907</span>
<span id="908">908</span>
<span id="909">909</span>
<span id="910">910</span>
<span id="911">911</span>
<span id="912">912</span>
<span id="913">913</span>
<span id="914">914</span>
<span id="915">915</span>
<span id="916">916</span>
<span id="917">917</span>
<span id="918">918</span>
<span id="919">919</span>
<span id="920">920</span>
<span id="921">921</span>
<span id="922">922</span>
<span id="923">923</span>
<span id="924">924</span>
<span id="925">925</span>
<span id="926">926</span>
<span id="927">927</span>
<span id="928">928</span>
<span id="929">929</span>
<span id="930">930</span>
<span id="931">931</span>
<span id="932">932</span>
<span id="933">933</span>
<span id="934">934</span>
<span id="935">935</span>
<span id="936">936</span>
<span id="937">937</span>
<span id="938">938</span>
<span id="939">939</span>
<span id="940">940</span>
<span id="941">941</span>
<span id="942">942</span>
<span id="943">943</span>
<span id="944">944</span>
<span id="945">945</span>
<span id="946">946</span>
<span id="947">947</span>
<span id="948">948</span>
<span id="949">949</span>
<span id="950">950</span>
<span id="951">951</span>
<span id="952">952</span>
<span id="953">953</span>
<span id="954">954</span>
<span id="955">955</span>
<span id="956">956</span>
<span id="957">957</span>
<span id="958">958</span>
<span id="959">959</span>
<span id="960">960</span>
<span id="961">961</span>
<span id="962">962</span>
<span id="963">963</span>
<span id="964">964</span>
<span id="965">965</span>
<span id="966">966</span>
<span id="967">967</span>
<span id="968">968</span>
<span id="969">969</span>
<span id="970">970</span>
<span id="971">971</span>
<span id="972">972</span>
<span id="973">973</span>
<span id="974">974</span>
<span id="975">975</span>
<span id="976">976</span>
<span id="977">977</span>
<span id="978">978</span>
<span id="979">979</span>
<span id="980">980</span>
<span id="981">981</span>
<span id="982">982</span>
<span id="983">983</span>
<span id="984">984</span>
<span id="985">985</span>
<span id="986">986</span>
<span id="987">987</span>
<span id="988">988</span>
<span id="989">989</span>
<span id="990">990</span>
<span id="991">991</span>
<span id="992">992</span>
<span id="993">993</span>
<span id="994">994</span>
<span id="995">995</span>
<span id="996">996</span>
<span id="997">997</span>
<span id="998">998</span>
<span id="999">999</span>
<span id="1000">1000</span>
<span id="1001">1001</span>
<span id="1002">1002</span>
<span id="1003">1003</span>
<span id="1004">1004</span>
<span id="1005">1005</span>
<span id="1006">1006</span>
<span id="1007">1007</span>
<span id="1008">1008</span>
<span id="1009">1009</span>
<span id="1010">1010</span>
<span id="1011">1011</span>
<span id="1012">1012</span>
<span id="1013">1013</span>
<span id="1014">1014</span>
<span id="1015">1015</span>
<span id="1016">1016</span>
<span id="1017">1017</span>
<span id="1018">1018</span>
<span id="1019">1019</span>
<span id="1020">1020</span>
<span id="1021">1021</span>
<span id="1022">1022</span>
<span id="1023">1023</span>
<span id="1024">1024</span>
<span id="1025">1025</span>
<span id="1026">1026</span>
<span id="1027">1027</span>
<span id="1028">1028</span>
<span id="1029">1029</span>
<span id="1030">1030</span>
<span id="1031">1031</span>
<span id="1032">1032</span>
<span id="1033">1033</span>
<span id="1034">1034</span>
<span id="1035">1035</span>
<span id="1036">1036</span>
<span id="1037">1037</span>
<span id="1038">1038</span>
<span id="1039">1039</span>
<span id="1040">1040</span>
<span id="1041">1041</span>
<span id="1042">1042</span>
<span id="1043">1043</span>
<span id="1044">1044</span>
<span id="1045">1045</span>
<span id="1046">1046</span>
<span id="1047">1047</span>
<span id="1048">1048</span>
<span id="1049">1049</span>
<span id="1050">1050</span>
<span id="1051">1051</span>
<span id="1052">1052</span>
<span id="1053">1053</span>
<span id="1054">1054</span>
<span id="1055">1055</span>
<span id="1056">1056</span>
<span id="1057">1057</span>
<span id="1058">1058</span>
<span id="1059">1059</span>
<span id="1060">1060</span>
<span id="1061">1061</span>
<span id="1062">1062</span>
<span id="1063">1063</span>
<span id="1064">1064</span>
<span id="1065">1065</span>
<span id="1066">1066</span>
<span id="1067">1067</span>
<span id="1068">1068</span>
<span id="1069">1069</span>
<span id="1070">1070</span>
<span id="1071">1071</span>
<span id="1072">1072</span>
<span id="1073">1073</span>
<span id="1074">1074</span>
<span id="1075">1075</span>
<span id="1076">1076</span>
<span id="1077">1077</span>
<span id="1078">1078</span>
<span id="1079">1079</span>
<span id="1080">1080</span>
<span id="1081">1081</span>
<span id="1082">1082</span>
<span id="1083">1083</span>
<span id="1084">1084</span>
<span id="1085">1085</span>
<span id="1086">1086</span>
<span id="1087">1087</span>
<span id="1088">1088</span>
<span id="1089">1089</span>
<span id="1090">1090</span>
<span id="1091">1091</span>
<span id="1092">1092</span>
<span id="1093">1093</span>
<span id="1094">1094</span>
<span id="1095">1095</span>
<span id="1096">1096</span>
<span id="1097">1097</span>
<span id="1098">1098</span>
<span id="1099">1099</span>
<span id="1100">1100</span>
<span id="1101">1101</span>
<span id="1102">1102</span>
<span id="1103">1103</span>
<span id="1104">1104</span>
<span id="1105">1105</span>
<span id="1106">1106</span>
<span id="1107">1107</span>
<span id="1108">1108</span>
<span id="1109">1109</span>
<span id="1110">1110</span>
<span id="1111">1111</span>
<span id="1112">1112</span>
<span id="1113">1113</span>
<span id="1114">1114</span>
<span id="1115">1115</span>
<span id="1116">1116</span>
<span id="1117">1117</span>
<span id="1118">1118</span>
<span id="1119">1119</span>
<span id="1120">1120</span>
<span id="1121">1121</span>
<span id="1122">1122</span>
<span id="1123">1123</span>
<span id="1124">1124</span>
<span id="1125">1125</span>
<span id="1126">1126</span>
<span id="1127">1127</span>
<span id="1128">1128</span>
<span id="1129">1129</span>
<span id="1130">1130</span>
<span id="1131">1131</span>
<span id="1132">1132</span>
<span id="1133">1133</span>
<span id="1134">1134</span>
<span id="1135">1135</span>
<span id="1136">1136</span>
<span id="1137">1137</span>
<span id="1138">1138</span>
<span id="1139">1139</span>
<span id="1140">1140</span>
<span id="1141">1141</span>
<span id="1142">1142</span>
<span id="1143">1143</span>
<span id="1144">1144</span>
<span id="1145">1145</span>
<span id="1146">1146</span>
<span id="1147">1147</span>
<span id="1148">1148</span>
<span id="1149">1149</span>
<span id="1150">1150</span>
<span id="1151">1151</span>
<span id="1152">1152</span>
<span id="1153">1153</span>
<span id="1154">1154</span>
<span id="1155">1155</span>
<span id="1156">1156</span>
<span id="1157">1157</span>
<span id="1158">1158</span>
<span id="1159">1159</span>
<span id="1160">1160</span>
<span id="1161">1161</span>
<span id="1162">1162</span>
<span id="1163">1163</span>
<span id="1164">1164</span>
<span id="1165">1165</span>
<span id="1166">1166</span>
<span id="1167">1167</span>
<span id="1168">1168</span>
<span id="1169">1169</span>
<span id="1170">1170</span>
<span id="1171">1171</span>
<span id="1172">1172</span>
<span id="1173">1173</span>
<span id="1174">1174</span>
<span id="1175">1175</span>
<span id="1176">1176</span>
<span id="1177">1177</span>
<span id="1178">1178</span>
<span id="1179">1179</span>
<span id="1180">1180</span>
<span id="1181">1181</span>
<span id="1182">1182</span>
<span id="1183">1183</span>
<span id="1184">1184</span>
<span id="1185">1185</span>
<span id="1186">1186</span>
<span id="1187">1187</span>
<span id="1188">1188</span>
<span id="1189">1189</span>
<span id="1190">1190</span>
<span id="1191">1191</span>
<span id="1192">1192</span>
<span id="1193">1193</span>
<span id="1194">1194</span>
<span id="1195">1195</span>
<span id="1196">1196</span>
<span id="1197">1197</span>
<span id="1198">1198</span>
<span id="1199">1199</span>
<span id="1200">1200</span>
<span id="1201">1201</span>
<span id="1202">1202</span>
<span id="1203">1203</span>
<span id="1204">1204</span>
<span id="1205">1205</span>
<span id="1206">1206</span>
<span id="1207">1207</span>
<span id="1208">1208</span>
<span id="1209">1209</span>
<span id="1210">1210</span>
<span id="1211">1211</span>
<span id="1212">1212</span>
<span id="1213">1213</span>
<span id="1214">1214</span>
<span id="1215">1215</span>
<span id="1216">1216</span>
<span id="1217">1217</span>
<span id="1218">1218</span>
<span id="1219">1219</span>
<span id="1220">1220</span>
<span id="1221">1221</span>
<span id="1222">1222</span>
<span id="1223">1223</span>
<span id="1224">1224</span>
<span id="1225">1225</span>
<span id="1226">1226</span>
<span id="1227">1227</span>
<span id="1228">1228</span>
<span id="1229">1229</span>
<span id="1230">1230</span>
<span id="1231">1231</span>
<span id="1232">1232</span>
<span id="1233">1233</span>
<span id="1234">1234</span>
<span id="1235">1235</span>
<span id="1236">1236</span>
<span id="1237">1237</span>
<span id="1238">1238</span>
<span id="1239">1239</span>
<span id="1240">1240</span>
<span id="1241">1241</span>
<span id="1242">1242</span>
<span id="1243">1243</span>
<span id="1244">1244</span>
<span id="1245">1245</span>
<span id="1246">1246</span>
<span id="1247">1247</span>
<span id="1248">1248</span>
<span id="1249">1249</span>
<span id="1250">1250</span>
<span id="1251">1251</span>
<span id="1252">1252</span>
<span id="1253">1253</span>
<span id="1254">1254</span>
<span id="1255">1255</span>
<span id="1256">1256</span>
<span id="1257">1257</span>
<span id="1258">1258</span>
<span id="1259">1259</span>
<span id="1260">1260</span>
<span id="1261">1261</span>
<span id="1262">1262</span>
<span id="1263">1263</span>
<span id="1264">1264</span>
<span id="1265">1265</span>
<span id="1266">1266</span>
<span id="1267">1267</span>
<span id="1268">1268</span>
<span id="1269">1269</span>
<span id="1270">1270</span>
<span id="1271">1271</span>
<span id="1272">1272</span>
<span id="1273">1273</span>
<span id="1274">1274</span>
<span id="1275">1275</span>
<span id="1276">1276</span>
<span id="1277">1277</span>
<span id="1278">1278</span>
<span id="1279">1279</span>
<span id="1280">1280</span>
<span id="1281">1281</span>
<span id="1282">1282</span>
<span id="1283">1283</span>
<span id="1284">1284</span>
<span id="1285">1285</span>
<span id="1286">1286</span>
<span id="1287">1287</span>
<span id="1288">1288</span>
<span id="1289">1289</span>
<span id="1290">1290</span>
<span id="1291">1291</span>
<span id="1292">1292</span>
<span id="1293">1293</span>
<span id="1294">1294</span>
<span id="1295">1295</span>
<span id="1296">1296</span>
<span id="1297">1297</span>
<span id="1298">1298</span>
<span id="1299">1299</span>
<span id="1300">1300</span>
<span id="1301">1301</span>
<span id="1302">1302</span>
<span id="1303">1303</span>
<span id="1304">1304</span>
<span id="1305">1305</span>
<span id="1306">1306</span>
<span id="1307">1307</span>
<span id="1308">1308</span>
<span id="1309">1309</span>
<span id="1310">1310</span>
<span id="1311">1311</span>
<span id="1312">1312</span>
<span id="1313">1313</span>
<span id="1314">1314</span>
<span id="1315">1315</span>
<span id="1316">1316</span>
<span id="1317">1317</span>
<span id="1318">1318</span>
<span id="1319">1319</span>
<span id="1320">1320</span>
<span id="1321">1321</span>
<span id="1322">1322</span>
<span id="1323">1323</span>
<span id="1324">1324</span>
<span id="1325">1325</span>
<span id="1326">1326</span>
<span id="1327">1327</span>
<span id="1328">1328</span>
<span id="1329">1329</span>
<span id="1330">1330</span>
<span id="1331">1331</span>
<span id="1332">1332</span>
<span id="1333">1333</span>
<span id="1334">1334</span>
<span id="1335">1335</span>
<span id="1336">1336</span>
<span id="1337">1337</span>
<span id="1338">1338</span>
<span id="1339">1339</span>
<span id="1340">1340</span>
<span id="1341">1341</span>
<span id="1342">1342</span>
<span id="1343">1343</span>
<span id="1344">1344</span>
<span id="1345">1345</span>
<span id="1346">1346</span>
<span id="1347">1347</span>
<span id="1348">1348</span>
<span id="1349">1349</span>
<span id="1350">1350</span>
<span id="1351">1351</span>
<span id="1352">1352</span>
<span id="1353">1353</span>
<span id="1354">1354</span>
<span id="1355">1355</span>
<span id="1356">1356</span>
<span id="1357">1357</span>
<span id="1358">1358</span>
<span id="1359">1359</span>
<span id="1360">1360</span>
<span id="1361">1361</span>
<span id="1362">1362</span>
<span id="1363">1363</span>
<span id="1364">1364</span>
<span id="1365">1365</span>
<span id="1366">1366</span>
<span id="1367">1367</span>
<span id="1368">1368</span>
<span id="1369">1369</span>
<span id="1370">1370</span>
<span id="1371">1371</span>
<span id="1372">1372</span>
<span id="1373">1373</span>
<span id="1374">1374</span>
<span id="1375">1375</span>
<span id="1376">1376</span>
<span id="1377">1377</span>
<span id="1378">1378</span>
<span id="1379">1379</span>
<span id="1380">1380</span>
<span id="1381">1381</span>
<span id="1382">1382</span>
<span id="1383">1383</span>
<span id="1384">1384</span>
<span id="1385">1385</span>
<span id="1386">1386</span>
<span id="1387">1387</span>
<span id="1388">1388</span>
<span id="1389">1389</span>
<span id="1390">1390</span>
<span id="1391">1391</span>
<span id="1392">1392</span>
<span id="1393">1393</span>
<span id="1394">1394</span>
<span id="1395">1395</span>
<span id="1396">1396</span>
<span id="1397">1397</span>
<span id="1398">1398</span>
<span id="1399">1399</span>
<span id="1400">1400</span>
<span id="1401">1401</span>
<span id="1402">1402</span>
<span id="1403">1403</span>
<span id="1404">1404</span>
<span id="1405">1405</span>
<span id="1406">1406</span>
<span id="1407">1407</span>
<span id="1408">1408</span>
<span id="1409">1409</span>
<span id="1410">1410</span>
<span id="1411">1411</span>
<span id="1412">1412</span>
<span id="1413">1413</span>
<span id="1414">1414</span>
<span id="1415">1415</span>
<span id="1416">1416</span>
<span id="1417">1417</span>
<span id="1418">1418</span>
<span id="1419">1419</span>
<span id="1420">1420</span>
<span id="1421">1421</span>
<span id="1422">1422</span>
<span id="1423">1423</span>
<span id="1424">1424</span>
<span id="1425">1425</span>
<span id="1426">1426</span>
<span id="1427">1427</span>
<span id="1428">1428</span>
<span id="1429">1429</span>
<span id="1430">1430</span>
<span id="1431">1431</span>
<span id="1432">1432</span>
<span id="1433">1433</span>
<span id="1434">1434</span>
<span id="1435">1435</span>
<span id="1436">1436</span>
<span id="1437">1437</span>
<span id="1438">1438</span>
<span id="1439">1439</span>
<span id="1440">1440</span>
<span id="1441">1441</span>
<span id="1442">1442</span>
<span id="1443">1443</span>
<span id="1444">1444</span>
<span id="1445">1445</span>
<span id="1446">1446</span>
<span id="1447">1447</span>
<span id="1448">1448</span>
<span id="1449">1449</span>
<span id="1450">1450</span>
<span id="1451">1451</span>
<span id="1452">1452</span>
<span id="1453">1453</span>
<span id="1454">1454</span>
<span id="1455">1455</span>
<span id="1456">1456</span>
<span id="1457">1457</span>
<span id="1458">1458</span>
<span id="1459">1459</span>
<span id="1460">1460</span>
<span id="1461">1461</span>
<span id="1462">1462</span>
<span id="1463">1463</span>
<span id="1464">1464</span>
<span id="1465">1465</span>
<span id="1466">1466</span>
<span id="1467">1467</span>
<span id="1468">1468</span>
<span id="1469">1469</span>
<span id="1470">1470</span>
<span id="1471">1471</span>
<span id="1472">1472</span>
<span id="1473">1473</span>
<span id="1474">1474</span>
<span id="1475">1475</span>
<span id="1476">1476</span>
<span id="1477">1477</span>
<span id="1478">1478</span>
<span id="1479">1479</span>
<span id="1480">1480</span>
<span id="1481">1481</span>
<span id="1482">1482</span>
<span id="1483">1483</span>
<span id="1484">1484</span>
<span id="1485">1485</span>
<span id="1486">1486</span>
<span id="1487">1487</span>
<span id="1488">1488</span>
<span id="1489">1489</span>
<span id="1490">1490</span>
<span id="1491">1491</span>
<span id="1492">1492</span>
<span id="1493">1493</span>
<span id="1494">1494</span>
<span id="1495">1495</span>
<span id="1496">1496</span>
<span id="1497">1497</span>
<span id="1498">1498</span>
<span id="1499">1499</span>
<span id="1500">1500</span>
<span id="1501">1501</span>
<span id="1502">1502</span>
<span id="1503">1503</span>
<span id="1504">1504</span>
<span id="1505">1505</span>
<span id="1506">1506</span>
<span id="1507">1507</span>
<span id="1508">1508</span>
<span id="1509">1509</span>
<span id="1510">1510</span>
<span id="1511">1511</span>
<span id="1512">1512</span>
<span id="1513">1513</span>
<span id="1514">1514</span>
<span id="1515">1515</span>
<span id="1516">1516</span>
<span id="1517">1517</span>
<span id="1518">1518</span>
<span id="1519">1519</span>
<span id="1520">1520</span>
<span id="1521">1521</span>
<span id="1522">1522</span>
<span id="1523">1523</span>
<span id="1524">1524</span>
<span id="1525">1525</span>
<span id="1526">1526</span>
<span id="1527">1527</span>
<span id="1528">1528</span>
<span id="1529">1529</span>
<span id="1530">1530</span>
<span id="1531">1531</span>
<span id="1532">1532</span>
<span id="1533">1533</span>
<span id="1534">1534</span>
<span id="1535">1535</span>
<span id="1536">1536</span>
<span id="1537">1537</span>
<span id="1538">1538</span>
<span id="1539">1539</span>
<span id="1540">1540</span>
<span id="1541">1541</span>
<span id="1542">1542</span>
<span id="1543">1543</span>
<span id="1544">1544</span>
<span id="1545">1545</span>
<span id="1546">1546</span>
<span id="1547">1547</span>
<span id="1548">1548</span>
<span id="1549">1549</span>
<span id="1550">1550</span>
<span id="1551">1551</span>
<span id="1552">1552</span>
<span id="1553">1553</span>
<span id="1554">1554</span>
<span id="1555">1555</span>
<span id="1556">1556</span>
<span id="1557">1557</span>
<span id="1558">1558</span>
<span id="1559">1559</span>
<span id="1560">1560</span>
<span id="1561">1561</span>
<span id="1562">1562</span>
<span id="1563">1563</span>
<span id="1564">1564</span>
<span id="1565">1565</span>
<span id="1566">1566</span>
<span id="1567">1567</span>
<span id="1568">1568</span>
<span id="1569">1569</span>
<span id="1570">1570</span>
<span id="1571">1571</span>
<span id="1572">1572</span>
<span id="1573">1573</span>
<span id="1574">1574</span>
<span id="1575">1575</span>
<span id="1576">1576</span>
<span id="1577">1577</span>
<span id="1578">1578</span>
<span id="1579">1579</span>
<span id="1580">1580</span>
<span id="1581">1581</span>
<span id="1582">1582</span>
<span id="1583">1583</span>
<span id="1584">1584</span>
<span id="1585">1585</span>
<span id="1586">1586</span>
<span id="1587">1587</span>
<span id="1588">1588</span>
<span id="1589">1589</span>
<span id="1590">1590</span>
<span id="1591">1591</span>
<span id="1592">1592</span>
<span id="1593">1593</span>
<span id="1594">1594</span>
<span id="1595">1595</span>
<span id="1596">1596</span>
<span id="1597">1597</span>
<span id="1598">1598</span>
<span id="1599">1599</span>
<span id="1600">1600</span>
<span id="1601">1601</span>
<span id="1602">1602</span>
<span id="1603">1603</span>
<span id="1604">1604</span>
<span id="1605">1605</span>
<span id="1606">1606</span>
<span id="1607">1607</span>
<span id="1608">1608</span>
<span id="1609">1609</span>
<span id="1610">1610</span>
<span id="1611">1611</span>
<span id="1612">1612</span>
<span id="1613">1613</span>
<span id="1614">1614</span>
<span id="1615">1615</span>
<span id="1616">1616</span>
<span id="1617">1617</span>
<span id="1618">1618</span>
<span id="1619">1619</span>
<span id="1620">1620</span>
<span id="1621">1621</span>
<span id="1622">1622</span>
<span id="1623">1623</span>
<span id="1624">1624</span>
<span id="1625">1625</span>
<span id="1626">1626</span>
<span id="1627">1627</span>
<span id="1628">1628</span>
<span id="1629">1629</span>
<span id="1630">1630</span>
<span id="1631">1631</span>
<span id="1632">1632</span>
<span id="1633">1633</span>
<span id="1634">1634</span>
<span id="1635">1635</span>
<span id="1636">1636</span>
<span id="1637">1637</span>
<span id="1638">1638</span>
<span id="1639">1639</span>
<span id="1640">1640</span>
<span id="1641">1641</span>
<span id="1642">1642</span>
<span id="1643">1643</span>
<span id="1644">1644</span>
<span id="1645">1645</span>
<span id="1646">1646</span>
<span id="1647">1647</span>
<span id="1648">1648</span>
<span id="1649">1649</span>
<span id="1650">1650</span>
<span id="1651">1651</span>
<span id="1652">1652</span>
<span id="1653">1653</span>
<span id="1654">1654</span>
<span id="1655">1655</span>
<span id="1656">1656</span>
<span id="1657">1657</span>
<span id="1658">1658</span>
<span id="1659">1659</span>
<span id="1660">1660</span>
<span id="1661">1661</span>
<span id="1662">1662</span>
<span id="1663">1663</span>
<span id="1664">1664</span>
<span id="1665">1665</span>
<span id="1666">1666</span>
<span id="1667">1667</span>
<span id="1668">1668</span>
<span id="1669">1669</span>
<span id="1670">1670</span>
<span id="1671">1671</span>
<span id="1672">1672</span>
<span id="1673">1673</span>
<span id="1674">1674</span>
<span id="1675">1675</span>
<span id="1676">1676</span>
<span id="1677">1677</span>
<span id="1678">1678</span>
<span id="1679">1679</span>
<span id="1680">1680</span>
<span id="1681">1681</span>
<span id="1682">1682</span>
<span id="1683">1683</span>
<span id="1684">1684</span>
<span id="1685">1685</span>
<span id="1686">1686</span>
<span id="1687">1687</span>
<span id="1688">1688</span>
<span id="1689">1689</span>
<span id="1690">1690</span>
<span id="1691">1691</span>
<span id="1692">1692</span>
<span id="1693">1693</span>
<span id="1694">1694</span>
<span id="1695">1695</span>
<span id="1696">1696</span>
<span id="1697">1697</span>
<span id="1698">1698</span>
<span id="1699">1699</span>
<span id="1700">1700</span>
<span id="1701">1701</span>
<span id="1702">1702</span>
<span id="1703">1703</span>
<span id="1704">1704</span>
<span id="1705">1705</span>
<span id="1706">1706</span>
<span id="1707">1707</span>
<span id="1708">1708</span>
<span id="1709">1709</span>
<span id="1710">1710</span>
<span id="1711">1711</span>
<span id="1712">1712</span>
<span id="1713">1713</span>
<span id="1714">1714</span>
<span id="1715">1715</span>
<span id="1716">1716</span>
<span id="1717">1717</span>
<span id="1718">1718</span>
<span id="1719">1719</span>
<span id="1720">1720</span>
<span id="1721">1721</span>
<span id="1722">1722</span>
<span id="1723">1723</span>
<span id="1724">1724</span>
<span id="1725">1725</span>
<span id="1726">1726</span>
<span id="1727">1727</span>
<span id="1728">1728</span>
<span id="1729">1729</span>
<span id="1730">1730</span>
<span id="1731">1731</span>
<span id="1732">1732</span>
<span id="1733">1733</span>
<span id="1734">1734</span>
<span id="1735">1735</span>
<span id="1736">1736</span>
<span id="1737">1737</span>
<span id="1738">1738</span>
<span id="1739">1739</span>
<span id="1740">1740</span>
<span id="1741">1741</span>
<span id="1742">1742</span>
<span id="1743">1743</span>
<span id="1744">1744</span>
<span id="1745">1745</span>
<span id="1746">1746</span>
<span id="1747">1747</span>
<span id="1748">1748</span>
<span id="1749">1749</span>
<span id="1750">1750</span>
<span id="1751">1751</span>
<span id="1752">1752</span>
<span id="1753">1753</span>
<span id="1754">1754</span>
<span id="1755">1755</span>
<span id="1756">1756</span>
<span id="1757">1757</span>
<span id="1758">1758</span>
<span id="1759">1759</span>
<span id="1760">1760</span>
<span id="1761">1761</span>
<span id="1762">1762</span>
<span id="1763">1763</span>
<span id="1764">1764</span>
<span id="1765">1765</span>
<span id="1766">1766</span>
<span id="1767">1767</span>
<span id="1768">1768</span>
<span id="1769">1769</span>
<span id="1770">1770</span>
<span id="1771">1771</span>
<span id="1772">1772</span>
<span id="1773">1773</span>
<span id="1774">1774</span>
<span id="1775">1775</span>
<span id="1776">1776</span>
<span id="1777">1777</span>
<span id="1778">1778</span>
<span id="1779">1779</span>
<span id="1780">1780</span>
<span id="1781">1781</span>
<span id="1782">1782</span>
<span id="1783">1783</span>
<span id="1784">1784</span>
<span id="1785">1785</span>
<span id="1786">1786</span>
<span id="1787">1787</span>
<span id="1788">1788</span>
<span id="1789">1789</span>
<span id="1790">1790</span>
<span id="1791">1791</span>
<span id="1792">1792</span>
<span id="1793">1793</span>
<span id="1794">1794</span>
<span id="1795">1795</span>
<span id="1796">1796</span>
<span id="1797">1797</span>
<span id="1798">1798</span>
<span id="1799">1799</span>
<span id="1800">1800</span>
<span id="1801">1801</span>
<span id="1802">1802</span>
<span id="1803">1803</span>
<span id="1804">1804</span>
<span id="1805">1805</span>
<span id="1806">1806</span>
<span id="1807">1807</span>
<span id="1808">1808</span>
<span id="1809">1809</span>
<span id="1810">1810</span>
<span id="1811">1811</span>
<span id="1812">1812</span>
<span id="1813">1813</span>
<span id="1814">1814</span>
<span id="1815">1815</span>
<span id="1816">1816</span>
<span id="1817">1817</span>
<span id="1818">1818</span>
<span id="1819">1819</span>
<span id="1820">1820</span>
<span id="1821">1821</span>
<span id="1822">1822</span>
<span id="1823">1823</span>
<span id="1824">1824</span>
<span id="1825">1825</span>
<span id="1826">1826</span>
<span id="1827">1827</span>
<span id="1828">1828</span>
<span id="1829">1829</span>
<span id="1830">1830</span>
<span id="1831">1831</span>
<span id="1832">1832</span>
<span id="1833">1833</span>
<span id="1834">1834</span>
<span id="1835">1835</span>
<span id="1836">1836</span>
<span id="1837">1837</span>
<span id="1838">1838</span>
<span id="1839">1839</span>
<span id="1840">1840</span>
<span id="1841">1841</span>
<span id="1842">1842</span>
<span id="1843">1843</span>
<span id="1844">1844</span>
<span id="1845">1845</span>
<span id="1846">1846</span>
<span id="1847">1847</span>
<span id="1848">1848</span>
<span id="1849">1849</span>
<span id="1850">1850</span>
<span id="1851">1851</span>
<span id="1852">1852</span>
<span id="1853">1853</span>
<span id="1854">1854</span>
<span id="1855">1855</span>
<span id="1856">1856</span>
<span id="1857">1857</span>
<span id="1858">1858</span>
<span id="1859">1859</span>
<span id="1860">1860</span>
<span id="1861">1861</span>
<span id="1862">1862</span>
<span id="1863">1863</span>
<span id="1864">1864</span>
<span id="1865">1865</span>
<span id="1866">1866</span>
<span id="1867">1867</span>
<span id="1868">1868</span>
<span id="1869">1869</span>
<span id="1870">1870</span>
<span id="1871">1871</span>
<span id="1872">1872</span>
<span id="1873">1873</span>
<span id="1874">1874</span>
<span id="1875">1875</span>
<span id="1876">1876</span>
<span id="1877">1877</span>
<span id="1878">1878</span>
<span id="1879">1879</span>
<span id="1880">1880</span>
<span id="1881">1881</span>
<span id="1882">1882</span>
<span id="1883">1883</span>
<span id="1884">1884</span>
<span id="1885">1885</span>
<span id="1886">1886</span>
<span id="1887">1887</span>
<span id="1888">1888</span>
<span id="1889">1889</span>
<span id="1890">1890</span>
<span id="1891">1891</span>
<span id="1892">1892</span>
<span id="1893">1893</span>
<span id="1894">1894</span>
<span id="1895">1895</span>
<span id="1896">1896</span>
<span id="1897">1897</span>
<span id="1898">1898</span>
<span id="1899">1899</span>
<span id="1900">1900</span>
<span id="1901">1901</span>
<span id="1902">1902</span>
<span id="1903">1903</span>
<span id="1904">1904</span>
<span id="1905">1905</span>
<span id="1906">1906</span>
<span id="1907">1907</span>
<span id="1908">1908</span>
<span id="1909">1909</span>
<span id="1910">1910</span>
<span id="1911">1911</span>
<span id="1912">1912</span>
<span id="1913">1913</span>
<span id="1914">1914</span>
<span id="1915">1915</span>
<span id="1916">1916</span>
<span id="1917">1917</span>
<span id="1918">1918</span>
<span id="1919">1919</span>
<span id="1920">1920</span>
<span id="1921">1921</span>
<span id="1922">1922</span>
<span id="1923">1923</span>
<span id="1924">1924</span>
<span id="1925">1925</span>
<span id="1926">1926</span>
<span id="1927">1927</span>
<span id="1928">1928</span>
<span id="1929">1929</span>
<span id="1930">1930</span>
<span id="1931">1931</span>
<span id="1932">1932</span>
<span id="1933">1933</span>
<span id="1934">1934</span>
<span id="1935">1935</span>
<span id="1936">1936</span>
<span id="1937">1937</span>
<span id="1938">1938</span>
<span id="1939">1939</span>
<span id="1940">1940</span>
<span id="1941">1941</span>
<span id="1942">1942</span>
<span id="1943">1943</span>
<span id="1944">1944</span>
<span id="1945">1945</span>
<span id="1946">1946</span>
<span id="1947">1947</span>
<span id="1948">1948</span>
<span id="1949">1949</span>
<span id="1950">1950</span>
<span id="1951">1951</span>
<span id="1952">1952</span>
<span id="1953">1953</span>
<span id="1954">1954</span>
<span id="1955">1955</span>
<span id="1956">1956</span>
<span id="1957">1957</span>
<span id="1958">1958</span>
<span id="1959">1959</span>
<span id="1960">1960</span>
<span id="1961">1961</span>
<span id="1962">1962</span>
<span id="1963">1963</span>
<span id="1964">1964</span>
<span id="1965">1965</span>
<span id="1966">1966</span>
<span id="1967">1967</span>
<span id="1968">1968</span>
<span id="1969">1969</span>
<span id="1970">1970</span>
<span id="1971">1971</span>
<span id="1972">1972</span>
<span id="1973">1973</span>
<span id="1974">1974</span>
<span id="1975">1975</span>
<span id="1976">1976</span>
<span id="1977">1977</span>
<span id="1978">1978</span>
<span id="1979">1979</span>
<span id="1980">1980</span>
<span id="1981">1981</span>
<span id="1982">1982</span>
<span id="1983">1983</span>
<span id="1984">1984</span>
<span id="1985">1985</span>
<span id="1986">1986</span>
<span id="1987">1987</span>
<span id="1988">1988</span>
<span id="1989">1989</span>
<span id="1990">1990</span>
<span id="1991">1991</span>
<span id="1992">1992</span>
<span id="1993">1993</span>
<span id="1994">1994</span>
<span id="1995">1995</span>
<span id="1996">1996</span>
<span id="1997">1997</span>
<span id="1998">1998</span>
<span id="1999">1999</span>
<span id="2000">2000</span>
<span id="2001">2001</span>
<span id="2002">2002</span>
<span id="2003">2003</span>
<span id="2004">2004</span>
<span id="2005">2005</span>
<span id="2006">2006</span>
<span id="2007">2007</span>
<span id="2008">2008</span>
<span id="2009">2009</span>
<span id="2010">2010</span>
<span id="2011">2011</span>
<span id="2012">2012</span>
<span id="2013">2013</span>
<span id="2014">2014</span>
<span id="2015">2015</span>
<span id="2016">2016</span>
<span id="2017">2017</span>
<span id="2018">2018</span>
<span id="2019">2019</span>
<span id="2020">2020</span>
<span id="2021">2021</span>
<span id="2022">2022</span>
<span id="2023">2023</span>
<span id="2024">2024</span>
<span id="2025">2025</span>
<span id="2026">2026</span>
<span id="2027">2027</span>
<span id="2028">2028</span>
<span id="2029">2029</span>
<span id="2030">2030</span>
<span id="2031">2031</span>
<span id="2032">2032</span>
<span id="2033">2033</span>
<span id="2034">2034</span>
<span id="2035">2035</span>
<span id="2036">2036</span>
<span id="2037">2037</span>
<span id="2038">2038</span>
<span id="2039">2039</span>
<span id="2040">2040</span>
<span id="2041">2041</span>
<span id="2042">2042</span>
<span id="2043">2043</span>
<span id="2044">2044</span>
<span id="2045">2045</span>
<span id="2046">2046</span>
<span id="2047">2047</span>
<span id="2048">2048</span>
<span id="2049">2049</span>
<span id="2050">2050</span>
<span id="2051">2051</span>
<span id="2052">2052</span>
<span id="2053">2053</span>
<span id="2054">2054</span>
<span id="2055">2055</span>
<span id="2056">2056</span>
<span id="2057">2057</span>
<span id="2058">2058</span>
<span id="2059">2059</span>
<span id="2060">2060</span>
<span id="2061">2061</span>
<span id="2062">2062</span>
<span id="2063">2063</span>
<span id="2064">2064</span>
<span id="2065">2065</span>
<span id="2066">2066</span>
<span id="2067">2067</span>
<span id="2068">2068</span>
<span id="2069">2069</span>
<span id="2070">2070</span>
<span id="2071">2071</span>
<span id="2072">2072</span>
<span id="2073">2073</span>
<span id="2074">2074</span>
<span id="2075">2075</span>
<span id="2076">2076</span>
<span id="2077">2077</span>
<span id="2078">2078</span>
<span id="2079">2079</span>
<span id="2080">2080</span>
<span id="2081">2081</span>
<span id="2082">2082</span>
<span id="2083">2083</span>
<span id="2084">2084</span>
<span id="2085">2085</span>
<span id="2086">2086</span>
<span id="2087">2087</span>
<span id="2088">2088</span>
<span id="2089">2089</span>
<span id="2090">2090</span>
<span id="2091">2091</span>
<span id="2092">2092</span>
<span id="2093">2093</span>
<span id="2094">2094</span>
<span id="2095">2095</span>
<span id="2096">2096</span>
<span id="2097">2097</span>
<span id="2098">2098</span>
<span id="2099">2099</span>
<span id="2100">2100</span>
<span id="2101">2101</span>
<span id="2102">2102</span>
<span id="2103">2103</span>
<span id="2104">2104</span>
<span id="2105">2105</span>
<span id="2106">2106</span>
<span id="2107">2107</span>
<span id="2108">2108</span>
<span id="2109">2109</span>
<span id="2110">2110</span>
<span id="2111">2111</span>
<span id="2112">2112</span>
<span id="2113">2113</span>
<span id="2114">2114</span>
<span id="2115">2115</span>
<span id="2116">2116</span>
<span id="2117">2117</span>
<span id="2118">2118</span>
<span id="2119">2119</span>
<span id="2120">2120</span>
<span id="2121">2121</span>
<span id="2122">2122</span>
<span id="2123">2123</span>
<span id="2124">2124</span>
<span id="2125">2125</span>
<span id="2126">2126</span>
<span id="2127">2127</span>
<span id="2128">2128</span>
<span id="2129">2129</span>
<span id="2130">2130</span>
<span id="2131">2131</span>
<span id="2132">2132</span>
<span id="2133">2133</span>
<span id="2134">2134</span>
<span id="2135">2135</span>
<span id="2136">2136</span>
<span id="2137">2137</span>
<span id="2138">2138</span>
<span id="2139">2139</span>
<span id="2140">2140</span>
<span id="2141">2141</span>
<span id="2142">2142</span>
<span id="2143">2143</span>
<span id="2144">2144</span>
<span id="2145">2145</span>
<span id="2146">2146</span>
<span id="2147">2147</span>
<span id="2148">2148</span>
<span id="2149">2149</span>
<span id="2150">2150</span>
<span id="2151">2151</span>
<span id="2152">2152</span>
<span id="2153">2153</span>
<span id="2154">2154</span>
<span id="2155">2155</span>
<span id="2156">2156</span>
<span id="2157">2157</span>
<span id="2158">2158</span>
<span id="2159">2159</span>
<span id="2160">2160</span>
<span id="2161">2161</span>
<span id="2162">2162</span>
<span id="2163">2163</span>
<span id="2164">2164</span>
<span id="2165">2165</span>
<span id="2166">2166</span>
<span id="2167">2167</span>
<span id="2168">2168</span>
<span id="2169">2169</span>
<span id="2170">2170</span>
<span id="2171">2171</span>
<span id="2172">2172</span>
<span id="2173">2173</span>
<span id="2174">2174</span>
<span id="2175">2175</span>
<span id="2176">2176</span>
<span id="2177">2177</span>
<span id="2178">2178</span>
<span id="2179">2179</span>
<span id="2180">2180</span>
<span id="2181">2181</span>
<span id="2182">2182</span>
<span id="2183">2183</span>
<span id="2184">2184</span>
<span id="2185">2185</span>
<span id="2186">2186</span>
<span id="2187">2187</span>
<span id="2188">2188</span>
<span id="2189">2189</span>
<span id="2190">2190</span>
<span id="2191">2191</span>
<span id="2192">2192</span>
<span id="2193">2193</span>
<span id="2194">2194</span>
<span id="2195">2195</span>
<span id="2196">2196</span>
<span id="2197">2197</span>
<span id="2198">2198</span>
<span id="2199">2199</span>
<span id="2200">2200</span>
<span id="2201">2201</span>
<span id="2202">2202</span>
<span id="2203">2203</span>
<span id="2204">2204</span>
<span id="2205">2205</span>
<span id="2206">2206</span>
<span id="2207">2207</span>
<span id="2208">2208</span>
<span id="2209">2209</span>
<span id="2210">2210</span>
<span id="2211">2211</span>
<span id="2212">2212</span>
<span id="2213">2213</span>
<span id="2214">2214</span>
<span id="2215">2215</span>
<span id="2216">2216</span>
<span id="2217">2217</span>
<span id="2218">2218</span>
<span id="2219">2219</span>
<span id="2220">2220</span>
<span id="2221">2221</span>
<span id="2222">2222</span>
<span id="2223">2223</span>
<span id="2224">2224</span>
<span id="2225">2225</span>
<span id="2226">2226</span>
<span id="2227">2227</span>
<span id="2228">2228</span>
<span id="2229">2229</span>
<span id="2230">2230</span>
<span id="2231">2231</span>
<span id="2232">2232</span>
<span id="2233">2233</span>
<span id="2234">2234</span>
<span id="2235">2235</span>
<span id="2236">2236</span>
<span id="2237">2237</span>
<span id="2238">2238</span>
<span id="2239">2239</span>
<span id="2240">2240</span>
<span id="2241">2241</span>
<span id="2242">2242</span>
<span id="2243">2243</span>
<span id="2244">2244</span>
<span id="2245">2245</span>
<span id="2246">2246</span>
<span id="2247">2247</span>
<span id="2248">2248</span>
<span id="2249">2249</span>
<span id="2250">2250</span>
<span id="2251">2251</span>
<span id="2252">2252</span>
<span id="2253">2253</span>
<span id="2254">2254</span>
<span id="2255">2255</span>
<span id="2256">2256</span>
<span id="2257">2257</span>
<span id="2258">2258</span>
<span id="2259">2259</span>
<span id="2260">2260</span>
<span id="2261">2261</span>
<span id="2262">2262</span>
<span id="2263">2263</span>
<span id="2264">2264</span>
<span id="2265">2265</span>
<span id="2266">2266</span>
<span id="2267">2267</span>
<span id="2268">2268</span>
<span id="2269">2269</span>
<span id="2270">2270</span>
<span id="2271">2271</span>
<span id="2272">2272</span>
<span id="2273">2273</span>
<span id="2274">2274</span>
<span id="2275">2275</span>
<span id="2276">2276</span>
<span id="2277">2277</span>
<span id="2278">2278</span>
<span id="2279">2279</span>
<span id="2280">2280</span>
<span id="2281">2281</span>
<span id="2282">2282</span>
<span id="2283">2283</span>
<span id="2284">2284</span>
<span id="2285">2285</span>
<span id="2286">2286</span>
<span id="2287">2287</span>
<span id="2288">2288</span>
<span id="2289">2289</span>
<span id="2290">2290</span>
<span id="2291">2291</span>
<span id="2292">2292</span>
<span id="2293">2293</span>
<span id="2294">2294</span>
<span id="2295">2295</span>
<span id="2296">2296</span>
<span id="2297">2297</span>
<span id="2298">2298</span>
<span id="2299">2299</span>
<span id="2300">2300</span>
<span id="2301">2301</span>
<span id="2302">2302</span>
<span id="2303">2303</span>
<span id="2304">2304</span>
<span id="2305">2305</span>
<span id="2306">2306</span>
<span id="2307">2307</span>
<span id="2308">2308</span>
<span id="2309">2309</span>
<span id="2310">2310</span>
<span id="2311">2311</span>
<span id="2312">2312</span>
<span id="2313">2313</span>
<span id="2314">2314</span>
<span id="2315">2315</span>
<span id="2316">2316</span>
<span id="2317">2317</span>
<span id="2318">2318</span>
<span id="2319">2319</span>
<span id="2320">2320</span>
<span id="2321">2321</span>
<span id="2322">2322</span>
<span id="2323">2323</span>
<span id="2324">2324</span>
<span id="2325">2325</span>
<span id="2326">2326</span>
<span id="2327">2327</span>
<span id="2328">2328</span>
<span id="2329">2329</span>
<span id="2330">2330</span>
<span id="2331">2331</span>
<span id="2332">2332</span>
<span id="2333">2333</span>
<span id="2334">2334</span>
<span id="2335">2335</span>
<span id="2336">2336</span>
<span id="2337">2337</span>
<span id="2338">2338</span>
<span id="2339">2339</span>
<span id="2340">2340</span>
<span id="2341">2341</span>
<span id="2342">2342</span>
<span id="2343">2343</span>
<span id="2344">2344</span>
<span id="2345">2345</span>
<span id="2346">2346</span>
<span id="2347">2347</span>
<span id="2348">2348</span>
<span id="2349">2349</span>
<span id="2350">2350</span>
<span id="2351">2351</span>
<span id="2352">2352</span>
<span id="2353">2353</span>
<span id="2354">2354</span>
<span id="2355">2355</span>
<span id="2356">2356</span>
<span id="2357">2357</span>
<span id="2358">2358</span>
<span id="2359">2359</span>
<span id="2360">2360</span>
<span id="2361">2361</span>
<span id="2362">2362</span>
<span id="2363">2363</span>
<span id="2364">2364</span>
<span id="2365">2365</span>
<span id="2366">2366</span>
<span id="2367">2367</span>
<span id="2368">2368</span>
<span id="2369">2369</span>
<span id="2370">2370</span>
<span id="2371">2371</span>
<span id="2372">2372</span>
<span id="2373">2373</span>
<span id="2374">2374</span>
<span id="2375">2375</span>
<span id="2376">2376</span>
<span id="2377">2377</span>
<span id="2378">2378</span>
<span id="2379">2379</span>
<span id="2380">2380</span>
<span id="2381">2381</span>
<span id="2382">2382</span>
<span id="2383">2383</span>
<span id="2384">2384</span>
<span id="2385">2385</span>
<span id="2386">2386</span>
<span id="2387">2387</span>
<span id="2388">2388</span>
<span id="2389">2389</span>
<span id="2390">2390</span>
<span id="2391">2391</span>
<span id="2392">2392</span>
<span id="2393">2393</span>
<span id="2394">2394</span>
<span id="2395">2395</span>
<span id="2396">2396</span>
<span id="2397">2397</span>
<span id="2398">2398</span>
<span id="2399">2399</span>
<span id="2400">2400</span>
<span id="2401">2401</span>
<span id="2402">2402</span>
<span id="2403">2403</span>
<span id="2404">2404</span>
<span id="2405">2405</span>
<span id="2406">2406</span>
<span id="2407">2407</span>
<span id="2408">2408</span>
<span id="2409">2409</span>
<span id="2410">2410</span>
<span id="2411">2411</span>
<span id="2412">2412</span>
<span id="2413">2413</span>
<span id="2414">2414</span>
<span id="2415">2415</span>
<span id="2416">2416</span>
<span id="2417">2417</span>
<span id="2418">2418</span>
<span id="2419">2419</span>
<span id="2420">2420</span>
<span id="2421">2421</span>
<span id="2422">2422</span>
<span id="2423">2423</span>
<span id="2424">2424</span>
<span id="2425">2425</span>
<span id="2426">2426</span>
<span id="2427">2427</span>
<span id="2428">2428</span>
<span id="2429">2429</span>
<span id="2430">2430</span>
<span id="2431">2431</span>
<span id="2432">2432</span>
<span id="2433">2433</span>
<span id="2434">2434</span>
<span id="2435">2435</span>
<span id="2436">2436</span>
<span id="2437">2437</span>
<span id="2438">2438</span>
<span id="2439">2439</span>
<span id="2440">2440</span>
<span id="2441">2441</span>
<span id="2442">2442</span>
<span id="2443">2443</span>
<span id="2444">2444</span>
<span id="2445">2445</span>
<span id="2446">2446</span>
<span id="2447">2447</span>
<span id="2448">2448</span>
<span id="2449">2449</span>
<span id="2450">2450</span>
<span id="2451">2451</span>
<span id="2452">2452</span>
<span id="2453">2453</span>
<span id="2454">2454</span>
<span id="2455">2455</span>
<span id="2456">2456</span>
<span id="2457">2457</span>
<span id="2458">2458</span>
<span id="2459">2459</span>
<span id="2460">2460</span>
<span id="2461">2461</span>
<span id="2462">2462</span>
<span id="2463">2463</span>
<span id="2464">2464</span>
<span id="2465">2465</span>
<span id="2466">2466</span>
<span id="2467">2467</span>
<span id="2468">2468</span>
<span id="2469">2469</span>
<span id="2470">2470</span>
<span id="2471">2471</span>
<span id="2472">2472</span>
<span id="2473">2473</span>
<span id="2474">2474</span>
<span id="2475">2475</span>
<span id="2476">2476</span>
<span id="2477">2477</span>
<span id="2478">2478</span>
<span id="2479">2479</span>
<span id="2480">2480</span>
<span id="2481">2481</span>
<span id="2482">2482</span>
<span id="2483">2483</span>
<span id="2484">2484</span>
<span id="2485">2485</span>
<span id="2486">2486</span>
<span id="2487">2487</span>
<span id="2488">2488</span>
<span id="2489">2489</span>
<span id="2490">2490</span>
<span id="2491">2491</span>
<span id="2492">2492</span>
<span id="2493">2493</span>
<span id="2494">2494</span>
<span id="2495">2495</span>
<span id="2496">2496</span>
<span id="2497">2497</span>
<span id="2498">2498</span>
<span id="2499">2499</span>
<span id="2500">2500</span>
<span id="2501">2501</span>
<span id="2502">2502</span>
<span id="2503">2503</span>
<span id="2504">2504</span>
<span id="2505">2505</span>
<span id="2506">2506</span>
<span id="2507">2507</span>
<span id="2508">2508</span>
<span id="2509">2509</span>
<span id="2510">2510</span>
<span id="2511">2511</span>
<span id="2512">2512</span>
<span id="2513">2513</span>
<span id="2514">2514</span>
<span id="2515">2515</span>
<span id="2516">2516</span>
<span id="2517">2517</span>
<span id="2518">2518</span>
<span id="2519">2519</span>
<span id="2520">2520</span>
<span id="2521">2521</span>
<span id="2522">2522</span>
<span id="2523">2523</span>
<span id="2524">2524</span>
<span id="2525">2525</span>
<span id="2526">2526</span>
<span id="2527">2527</span>
<span id="2528">2528</span>
<span id="2529">2529</span>
<span id="2530">2530</span>
<span id="2531">2531</span>
<span id="2532">2532</span>
<span id="2533">2533</span>
<span id="2534">2534</span>
<span id="2535">2535</span>
<span id="2536">2536</span>
<span id="2537">2537</span>
<span id="2538">2538</span>
<span id="2539">2539</span>
<span id="2540">2540</span>
<span id="2541">2541</span>
<span id="2542">2542</span>
<span id="2543">2543</span>
<span id="2544">2544</span>
<span id="2545">2545</span>
<span id="2546">2546</span>
<span id="2547">2547</span>
<span id="2548">2548</span>
<span id="2549">2549</span>
<span id="2550">2550</span>
<span id="2551">2551</span>
<span id="2552">2552</span>
<span id="2553">2553</span>
<span id="2554">2554</span>
<span id="2555">2555</span>
<span id="2556">2556</span>
<span id="2557">2557</span>
<span id="2558">2558</span>
<span id="2559">2559</span>
<span id="2560">2560</span>
<span id="2561">2561</span>
<span id="2562">2562</span>
<span id="2563">2563</span>
<span id="2564">2564</span>
<span id="2565">2565</span>
<span id="2566">2566</span>
<span id="2567">2567</span>
<span id="2568">2568</span>
<span id="2569">2569</span>
<span id="2570">2570</span>
<span id="2571">2571</span>
<span id="2572">2572</span>
<span id="2573">2573</span>
<span id="2574">2574</span>
<span id="2575">2575</span>
<span id="2576">2576</span>
<span id="2577">2577</span>
<span id="2578">2578</span>
<span id="2579">2579</span>
<span id="2580">2580</span>
<span id="2581">2581</span>
<span id="2582">2582</span>
<span id="2583">2583</span>
<span id="2584">2584</span>
<span id="2585">2585</span>
<span id="2586">2586</span>
<span id="2587">2587</span>
<span id="2588">2588</span>
<span id="2589">2589</span>
<span id="2590">2590</span>
<span id="2591">2591</span>
<span id="2592">2592</span>
<span id="2593">2593</span>
<span id="2594">2594</span>
<span id="2595">2595</span>
<span id="2596">2596</span>
<span id="2597">2597</span>
<span id="2598">2598</span>
<span id="2599">2599</span>
<span id="2600">2600</span>
<span id="2601">2601</span>
<span id="2602">2602</span>
<span id="2603">2603</span>
<span id="2604">2604</span>
<span id="2605">2605</span>
<span id="2606">2606</span>
<span id="2607">2607</span>
<span id="2608">2608</span>
<span id="2609">2609</span>
<span id="2610">2610</span>
<span id="2611">2611</span>
<span id="2612">2612</span>
<span id="2613">2613</span>
<span id="2614">2614</span>
<span id="2615">2615</span>
<span id="2616">2616</span>
<span id="2617">2617</span>
<span id="2618">2618</span>
<span id="2619">2619</span>
<span id="2620">2620</span>
<span id="2621">2621</span>
<span id="2622">2622</span>
<span id="2623">2623</span>
<span id="2624">2624</span>
<span id="2625">2625</span>
<span id="2626">2626</span>
<span id="2627">2627</span>
<span id="2628">2628</span>
<span id="2629">2629</span>
<span id="2630">2630</span>
<span id="2631">2631</span>
<span id="2632">2632</span>
<span id="2633">2633</span>
<span id="2634">2634</span>
<span id="2635">2635</span>
<span id="2636">2636</span>
<span id="2637">2637</span>
<span id="2638">2638</span>
<span id="2639">2639</span>
<span id="2640">2640</span>
<span id="2641">2641</span>
<span id="2642">2642</span>
<span id="2643">2643</span>
<span id="2644">2644</span>
<span id="2645">2645</span>
<span id="2646">2646</span>
<span id="2647">2647</span>
<span id="2648">2648</span>
<span id="2649">2649</span>
<span id="2650">2650</span>
<span id="2651">2651</span>
<span id="2652">2652</span>
<span id="2653">2653</span>
<span id="2654">2654</span>
<span id="2655">2655</span>
<span id="2656">2656</span>
<span id="2657">2657</span>
<span id="2658">2658</span>
<span id="2659">2659</span>
<span id="2660">2660</span>
<span id="2661">2661</span>
<span id="2662">2662</span>
<span id="2663">2663</span>
<span id="2664">2664</span>
<span id="2665">2665</span>
<span id="2666">2666</span>
<span id="2667">2667</span>
<span id="2668">2668</span>
<span id="2669">2669</span>
<span id="2670">2670</span>
<span id="2671">2671</span>
<span id="2672">2672</span>
<span id="2673">2673</span>
<span id="2674">2674</span>
<span id="2675">2675</span>
<span id="2676">2676</span>
<span id="2677">2677</span>
<span id="2678">2678</span>
<span id="2679">2679</span>
<span id="2680">2680</span>
<span id="2681">2681</span>
<span id="2682">2682</span>
<span id="2683">2683</span>
<span id="2684">2684</span>
<span id="2685">2685</span>
<span id="2686">2686</span>
<span id="2687">2687</span>
<span id="2688">2688</span>
<span id="2689">2689</span>
<span id="2690">2690</span>
<span id="2691">2691</span>
<span id="2692">2692</span>
<span id="2693">2693</span>
<span id="2694">2694</span>
<span id="2695">2695</span>
<span id="2696">2696</span>
<span id="2697">2697</span>
<span id="2698">2698</span>
<span id="2699">2699</span>
<span id="2700">2700</span>
<span id="2701">2701</span>
<span id="2702">2702</span>
<span id="2703">2703</span>
<span id="2704">2704</span>
<span id="2705">2705</span>
<span id="2706">2706</span>
<span id="2707">2707</span>
<span id="2708">2708</span>
<span id="2709">2709</span>
<span id="2710">2710</span>
<span id="2711">2711</span>
<span id="2712">2712</span>
<span id="2713">2713</span>
<span id="2714">2714</span>
<span id="2715">2715</span>
<span id="2716">2716</span>
<span id="2717">2717</span>
<span id="2718">2718</span>
<span id="2719">2719</span>
<span id="2720">2720</span>
<span id="2721">2721</span>
<span id="2722">2722</span>
<span id="2723">2723</span>
<span id="2724">2724</span>
<span id="2725">2725</span>
<span id="2726">2726</span>
<span id="2727">2727</span>
<span id="2728">2728</span>
<span id="2729">2729</span>
<span id="2730">2730</span>
<span id="2731">2731</span>
<span id="2732">2732</span>
<span id="2733">2733</span>
<span id="2734">2734</span>
<span id="2735">2735</span>
<span id="2736">2736</span>
<span id="2737">2737</span>
<span id="2738">2738</span>
<span id="2739">2739</span>
<span id="2740">2740</span>
<span id="2741">2741</span>
<span id="2742">2742</span>
<span id="2743">2743</span>
<span id="2744">2744</span>
<span id="2745">2745</span>
<span id="2746">2746</span>
<span id="2747">2747</span>
<span id="2748">2748</span>
<span id="2749">2749</span>
<span id="2750">2750</span>
<span id="2751">2751</span>
<span id="2752">2752</span>
<span id="2753">2753</span>
<span id="2754">2754</span>
<span id="2755">2755</span>
<span id="2756">2756</span>
<span id="2757">2757</span>
<span id="2758">2758</span>
<span id="2759">2759</span>
<span id="2760">2760</span>
<span id="2761">2761</span>
<span id="2762">2762</span>
<span id="2763">2763</span>
<span id="2764">2764</span>
<span id="2765">2765</span>
<span id="2766">2766</span>
<span id="2767">2767</span>
<span id="2768">2768</span>
<span id="2769">2769</span>
<span id="2770">2770</span>
<span id="2771">2771</span>
<span id="2772">2772</span>
<span id="2773">2773</span>
<span id="2774">2774</span>
<span id="2775">2775</span>
<span id="2776">2776</span>
<span id="2777">2777</span>
<span id="2778">2778</span>
<span id="2779">2779</span>
<span id="2780">2780</span>
<span id="2781">2781</span>
<span id="2782">2782</span>
<span id="2783">2783</span>
<span id="2784">2784</span>
<span id="2785">2785</span>
<span id="2786">2786</span>
<span id="2787">2787</span>
<span id="2788">2788</span>
<span id="2789">2789</span>
<span id="2790">2790</span>
<span id="2791">2791</span>
<span id="2792">2792</span>
<span id="2793">2793</span>
<span id="2794">2794</span>
<span id="2795">2795</span>
<span id="2796">2796</span>
<span id="2797">2797</span>
<span id="2798">2798</span>
<span id="2799">2799</span>
<span id="2800">2800</span>
<span id="2801">2801</span>
<span id="2802">2802</span>
<span id="2803">2803</span>
<span id="2804">2804</span>
<span id="2805">2805</span>
<span id="2806">2806</span>
<span id="2807">2807</span>
<span id="2808">2808</span>
<span id="2809">2809</span>
<span id="2810">2810</span>
<span id="2811">2811</span>
<span id="2812">2812</span>
<span id="2813">2813</span>
<span id="2814">2814</span>
<span id="2815">2815</span>
<span id="2816">2816</span>
<span id="2817">2817</span>
<span id="2818">2818</span>
<span id="2819">2819</span>
<span id="2820">2820</span>
<span id="2821">2821</span>
<span id="2822">2822</span>
<span id="2823">2823</span>
<span id="2824">2824</span>
<span id="2825">2825</span>
<span id="2826">2826</span>
<span id="2827">2827</span>
<span id="2828">2828</span>
<span id="2829">2829</span>
<span id="2830">2830</span>
<span id="2831">2831</span>
<span id="2832">2832</span>
<span id="2833">2833</span>
<span id="2834">2834</span>
<span id="2835">2835</span>
<span id="2836">2836</span>
<span id="2837">2837</span>
<span id="2838">2838</span>
<span id="2839">2839</span>
<span id="2840">2840</span>
<span id="2841">2841</span>
<span id="2842">2842</span>
<span id="2843">2843</span>
<span id="2844">2844</span>
<span id="2845">2845</span>
<span id="2846">2846</span>
<span id="2847">2847</span>
<span id="2848">2848</span>
<span id="2849">2849</span>
<span id="2850">2850</span>
<span id="2851">2851</span>
<span id="2852">2852</span>
<span id="2853">2853</span>
<span id="2854">2854</span>
<span id="2855">2855</span>
<span id="2856">2856</span>
<span id="2857">2857</span>
<span id="2858">2858</span>
<span id="2859">2859</span>
<span id="2860">2860</span>
<span id="2861">2861</span>
<span id="2862">2862</span>
<span id="2863">2863</span>
<span id="2864">2864</span>
<span id="2865">2865</span>
<span id="2866">2866</span>
<span id="2867">2867</span>
<span id="2868">2868</span>
<span id="2869">2869</span>
<span id="2870">2870</span>
<span id="2871">2871</span>
<span id="2872">2872</span>
<span id="2873">2873</span>
<span id="2874">2874</span>
<span id="2875">2875</span>
<span id="2876">2876</span>
<span id="2877">2877</span>
<span id="2878">2878</span>
<span id="2879">2879</span>
<span id="2880">2880</span>
<span id="2881">2881</span>
<span id="2882">2882</span>
<span id="2883">2883</span>
<span id="2884">2884</span>
<span id="2885">2885</span>
<span id="2886">2886</span>
<span id="2887">2887</span>
<span id="2888">2888</span>
<span id="2889">2889</span>
<span id="2890">2890</span>
<span id="2891">2891</span>
<span id="2892">2892</span>
<span id="2893">2893</span>
<span id="2894">2894</span>
<span id="2895">2895</span>
<span id="2896">2896</span>
<span id="2897">2897</span>
<span id="2898">2898</span>
<span id="2899">2899</span>
<span id="2900">2900</span>
<span id="2901">2901</span>
<span id="2902">2902</span>
<span id="2903">2903</span>
<span id="2904">2904</span>
<span id="2905">2905</span>
<span id="2906">2906</span>
<span id="2907">2907</span>
<span id="2908">2908</span>
<span id="2909">2909</span>
<span id="2910">2910</span>
<span id="2911">2911</span>
<span id="2912">2912</span>
<span id="2913">2913</span>
<span id="2914">2914</span>
<span id="2915">2915</span>
<span id="2916">2916</span>
<span id="2917">2917</span>
<span id="2918">2918</span>
<span id="2919">2919</span>
<span id="2920">2920</span>
<span id="2921">2921</span>
<span id="2922">2922</span>
<span id="2923">2923</span>
<span id="2924">2924</span>
<span id="2925">2925</span>
<span id="2926">2926</span>
<span id="2927">2927</span>
<span id="2928">2928</span>
<span id="2929">2929</span>
<span id="2930">2930</span>
<span id="2931">2931</span>
<span id="2932">2932</span>
<span id="2933">2933</span>
<span id="2934">2934</span>
<span id="2935">2935</span>
<span id="2936">2936</span>
<span id="2937">2937</span>
<span id="2938">2938</span>
<span id="2939">2939</span>
<span id="2940">2940</span>
<span id="2941">2941</span>
<span id="2942">2942</span>
<span id="2943">2943</span>
<span id="2944">2944</span>
<span id="2945">2945</span>
<span id="2946">2946</span>
<span id="2947">2947</span>
<span id="2948">2948</span>
<span id="2949">2949</span>
<span id="2950">2950</span>
<span id="2951">2951</span>
<span id="2952">2952</span>
<span id="2953">2953</span>
<span id="2954">2954</span>
<span id="2955">2955</span>
<span id="2956">2956</span>
<span id="2957">2957</span>
<span id="2958">2958</span>
<span id="2959">2959</span>
<span id="2960">2960</span>
<span id="2961">2961</span>
<span id="2962">2962</span>
<span id="2963">2963</span>
<span id="2964">2964</span>
<span id="2965">2965</span>
<span id="2966">2966</span>
<span id="2967">2967</span>
<span id="2968">2968</span>
<span id="2969">2969</span>
<span id="2970">2970</span>
<span id="2971">2971</span>
<span id="2972">2972</span>
<span id="2973">2973</span>
<span id="2974">2974</span>
<span id="2975">2975</span>
<span id="2976">2976</span>
<span id="2977">2977</span>
<span id="2978">2978</span>
<span id="2979">2979</span>
<span id="2980">2980</span>
<span id="2981">2981</span>
<span id="2982">2982</span>
<span id="2983">2983</span>
<span id="2984">2984</span>
<span id="2985">2985</span>
<span id="2986">2986</span>
<span id="2987">2987</span>
<span id="2988">2988</span>
<span id="2989">2989</span>
<span id="2990">2990</span>
<span id="2991">2991</span>
<span id="2992">2992</span>
<span id="2993">2993</span>
<span id="2994">2994</span>
<span id="2995">2995</span>
<span id="2996">2996</span>
<span id="2997">2997</span>
<span id="2998">2998</span>
<span id="2999">2999</span>
<span id="3000">3000</span>
<span id="3001">3001</span>
<span id="3002">3002</span>
<span id="3003">3003</span>
<span id="3004">3004</span>
<span id="3005">3005</span>
<span id="3006">3006</span>
<span id="3007">3007</span>
<span id="3008">3008</span>
<span id="3009">3009</span>
<span id="3010">3010</span>
<span id="3011">3011</span>
<span id="3012">3012</span>
<span id="3013">3013</span>
<span id="3014">3014</span>
<span id="3015">3015</span>
<span id="3016">3016</span>
<span id="3017">3017</span>
<span id="3018">3018</span>
<span id="3019">3019</span>
<span id="3020">3020</span>
<span id="3021">3021</span>
<span id="3022">3022</span>
<span id="3023">3023</span>
<span id="3024">3024</span>
<span id="3025">3025</span>
<span id="3026">3026</span>
<span id="3027">3027</span>
<span id="3028">3028</span>
<span id="3029">3029</span>
<span id="3030">3030</span>
<span id="3031">3031</span>
<span id="3032">3032</span>
<span id="3033">3033</span>
<span id="3034">3034</span>
<span id="3035">3035</span>
<span id="3036">3036</span>
<span id="3037">3037</span>
<span id="3038">3038</span>
<span id="3039">3039</span>
<span id="3040">3040</span>
<span id="3041">3041</span>
<span id="3042">3042</span>
<span id="3043">3043</span>
<span id="3044">3044</span>
<span id="3045">3045</span>
<span id="3046">3046</span>
<span id="3047">3047</span>
<span id="3048">3048</span>
<span id="3049">3049</span>
<span id="3050">3050</span>
<span id="3051">3051</span>
<span id="3052">3052</span>
<span id="3053">3053</span>
<span id="3054">3054</span>
<span id="3055">3055</span>
<span id="3056">3056</span>
<span id="3057">3057</span>
<span id="3058">3058</span>
<span id="3059">3059</span>
<span id="3060">3060</span>
<span id="3061">3061</span>
<span id="3062">3062</span>
<span id="3063">3063</span>
<span id="3064">3064</span>
<span id="3065">3065</span>
<span id="3066">3066</span>
<span id="3067">3067</span>
<span id="3068">3068</span>
<span id="3069">3069</span>
<span id="3070">3070</span>
<span id="3071">3071</span>
<span id="3072">3072</span>
<span id="3073">3073</span>
<span id="3074">3074</span>
<span id="3075">3075</span>
<span id="3076">3076</span>
<span id="3077">3077</span>
<span id="3078">3078</span>
<span id="3079">3079</span>
<span id="3080">3080</span>
<span id="3081">3081</span>
<span id="3082">3082</span>
<span id="3083">3083</span>
<span id="3084">3084</span>
<span id="3085">3085</span>
<span id="3086">3086</span>
<span id="3087">3087</span>
<span id="3088">3088</span>
<span id="3089">3089</span>
<span id="3090">3090</span>
<span id="3091">3091</span>
<span id="3092">3092</span>
<span id="3093">3093</span>
<span id="3094">3094</span>
<span id="3095">3095</span>
<span id="3096">3096</span>
<span id="3097">3097</span>
<span id="3098">3098</span>
<span id="3099">3099</span>
<span id="3100">3100</span>
<span id="3101">3101</span>
<span id="3102">3102</span>
<span id="3103">3103</span>
<span id="3104">3104</span>
<span id="3105">3105</span>
<span id="3106">3106</span>
<span id="3107">3107</span>
<span id="3108">3108</span>
<span id="3109">3109</span>
<span id="3110">3110</span>
<span id="3111">3111</span>
<span id="3112">3112</span>
<span id="3113">3113</span>
<span id="3114">3114</span>
<span id="3115">3115</span>
<span id="3116">3116</span>
<span id="3117">3117</span>
<span id="3118">3118</span>
<span id="3119">3119</span>
<span id="3120">3120</span>
<span id="3121">3121</span>
<span id="3122">3122</span>
<span id="3123">3123</span>
<span id="3124">3124</span>
<span id="3125">3125</span>
<span id="3126">3126</span>
<span id="3127">3127</span>
<span id="3128">3128</span>
<span id="3129">3129</span>
<span id="3130">3130</span>
<span id="3131">3131</span>
<span id="3132">3132</span>
<span id="3133">3133</span>
<span id="3134">3134</span>
<span id="3135">3135</span>
<span id="3136">3136</span>
<span id="3137">3137</span>
<span id="3138">3138</span>
<span id="3139">3139</span>
<span id="3140">3140</span>
<span id="3141">3141</span>
<span id="3142">3142</span>
<span id="3143">3143</span>
<span id="3144">3144</span>
<span id="3145">3145</span>
<span id="3146">3146</span>
<span id="3147">3147</span>
<span id="3148">3148</span>
<span id="3149">3149</span>
<span id="3150">3150</span>
<span id="3151">3151</span>
<span id="3152">3152</span>
<span id="3153">3153</span>
<span id="3154">3154</span>
<span id="3155">3155</span>
<span id="3156">3156</span>
<span id="3157">3157</span>
<span id="3158">3158</span>
<span id="3159">3159</span>
<span id="3160">3160</span>
<span id="3161">3161</span>
<span id="3162">3162</span>
<span id="3163">3163</span>
<span id="3164">3164</span>
<span id="3165">3165</span>
</pre><pre class="rust"><code><span class="doccomment">/*!
Provides literal extraction from `Hir` expressions.
An [`Extractor`] pulls literals out of [`Hir`] expressions and returns a
[`Seq`] of [`Literal`]s.
The purpose of literal extraction is generally to provide avenues for
optimizing regex searches. The main idea is that substring searches can be an
order of magnitude faster than a regex search. Therefore, if one can execute
a substring search to find candidate match locations and only run the regex
search at those locations, then it is possible for huge improvements in
performance to be realized.
With that said, literal optimizations are generally a black art because even
though substring search is generally faster, if the number of candidates
produced is high, then it can create a lot of overhead by ping-ponging between
the substring search and the regex search.
Here are some heuristics that might be used to help increase the chances of
effective literal optimizations:
* Stick to small [`Seq`]s. If you search for too many literals, it&#39;s likely
to lead to substring search that is only a little faster than a regex search,
and thus the overhead of using literal optimizations in the first place might
make things slower overall.
* The literals in your [`Seq`] shoudn&#39;t be too short. In general, longer is
better. A sequence corresponding to single bytes that occur frequently in the
haystack, for example, is probably a bad literal optimization because it&#39;s
likely to produce many false positive candidates. Longer literals are less
likely to match, and thus probably produce fewer false positives.
* If it&#39;s possible to estimate the approximate frequency of each byte according
to some pre-computed background distribution, it is possible to compute a score
of how &quot;good&quot; a `Seq` is. If a `Seq` isn&#39;t good enough, you might consider
skipping the literal optimization and just use the regex engine.
(It should be noted that there are always pathological cases that can make
any kind of literal optimization be a net slower result. This is why it
might be a good idea to be conservative, or to even provide a means for
literal optimizations to be dynamically disabled if they are determined to be
ineffective according to some measure.)
You&#39;re encouraged to explore the methods on [`Seq`], which permit shrinking
the size of sequences in a preference-order preserving fashion.
Finally, note that it isn&#39;t strictly necessary to use an [`Extractor`]. Namely,
an `Extractor` only uses public APIs of the [`Seq`] and [`Literal`] types,
so it is possible to implement your own extractor. For example, for n-grams
or &quot;inner&quot; literals (i.e., not prefix or suffix literals). The `Extractor`
is mostly responsible for the case analysis over `Hir` expressions. Much of
the &quot;trickier&quot; parts are how to combine literal sequences, and that is all
implemented on [`Seq`].
*/
</span><span class="kw">use </span>core::{cmp, mem};
<span class="kw">use </span>alloc::{vec, vec::Vec};
<span class="kw">use </span><span class="kw">crate</span>::hir::{<span class="self">self</span>, Hir};
<span class="doccomment">/// Extracts prefix or suffix literal sequences from [`Hir`] expressions.
///
/// Literal extraction is based on the following observations:
///
/// * Many regexes start with one or a small number of literals.
/// * Substring search for literals is often much faster (sometimes by an order
/// of magnitude) than a regex search.
///
/// Thus, in many cases, one can search for literals to find candidate starting
/// locations of a match, and then only run the full regex engine at each such
/// location instead of over the full haystack.
///
/// The main downside of literal extraction is that it can wind up causing a
/// search to be slower overall. For example, if there are many matches or if
/// there are many candidates that don&#39;t ultimately lead to a match, then a
/// lot of overhead will be spent in shuffing back-and-forth between substring
/// search and the regex engine. This is the fundamental reason why literal
/// optimizations for regex patterns is sometimes considered a &quot;black art.&quot;
///
/// # Look-around assertions
///
/// Literal extraction treats all look-around assertions as-if they match every
/// empty string. So for example, the regex `\bquux\b` will yield a sequence
/// containing a single exact literal `quux`. However, not all occurrences
/// of `quux` correspond to a match a of the regex. For example, `\bquux\b`
/// does not match `ZquuxZ` anywhere because `quux` does not fall on a word
/// boundary.
///
/// In effect, if your regex contains look-around assertions, then a match of
/// an exact literal does not necessarily mean the regex overall matches. So
/// you may still need to run the regex engine in such cases to confirm the
/// match.
///
/// The precise guarantee you get from a literal sequence is: if every literal
/// in the sequence is exact and the original regex contains zero look-around
/// assertions, then a preference-order multi-substring search of those
/// literals will precisely match a preference-order search of the original
/// regex.
///
/// # Example
///
/// This shows how to extract prefixes:
///
/// ```
/// use regex_syntax::{hir::literal::{Extractor, Literal, Seq}, parse};
///
/// let hir = parse(r&quot;(a|b|c)(x|y|z)[A-Z]+foo&quot;)?;
/// let got = Extractor::new().extract(&amp;hir);
/// // All literals returned are &quot;inexact&quot; because none of them reach the
/// // match state.
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;ax&quot;),
/// Literal::inexact(&quot;ay&quot;),
/// Literal::inexact(&quot;az&quot;),
/// Literal::inexact(&quot;bx&quot;),
/// Literal::inexact(&quot;by&quot;),
/// Literal::inexact(&quot;bz&quot;),
/// Literal::inexact(&quot;cx&quot;),
/// Literal::inexact(&quot;cy&quot;),
/// Literal::inexact(&quot;cz&quot;),
/// ]);
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
///
/// This shows how to extract suffixes:
///
/// ```
/// use regex_syntax::{
/// hir::literal::{Extractor, ExtractKind, Literal, Seq},
/// parse,
/// };
///
/// let hir = parse(r&quot;foo|[A-Z]+bar&quot;)?;
/// let got = Extractor::new().kind(ExtractKind::Suffix).extract(&amp;hir);
/// // Since &#39;foo&#39; gets to a match state, it is considered exact. But &#39;bar&#39;
/// // does not because of the &#39;[A-Z]+&#39;, and thus is marked inexact.
/// let expected = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="attribute">#[derive(Clone, Debug)]
</span><span class="kw">pub struct </span>Extractor {
kind: ExtractKind,
limit_class: usize,
limit_repeat: usize,
limit_literal_len: usize,
limit_total: usize,
}
<span class="kw">impl </span>Extractor {
<span class="doccomment">/// Create a new extractor with a default configuration.
///
/// The extractor can be optionally configured before calling
/// [`Extractor::extract`] to get a literal sequence.
</span><span class="kw">pub fn </span>new() -&gt; Extractor {
Extractor {
kind: ExtractKind::Prefix,
limit_class: <span class="number">10</span>,
limit_repeat: <span class="number">10</span>,
limit_literal_len: <span class="number">100</span>,
limit_total: <span class="number">250</span>,
}
}
<span class="doccomment">/// Execute the extractor and return a sequence of literals.
</span><span class="kw">pub fn </span>extract(<span class="kw-2">&amp;</span><span class="self">self</span>, hir: <span class="kw-2">&amp;</span>Hir) -&gt; Seq {
<span class="kw">use </span><span class="kw">crate</span>::hir::HirKind::<span class="kw-2">*</span>;
<span class="kw">match </span><span class="kw-2">*</span>hir.kind() {
Empty | Look(<span class="kw">_</span>) =&gt; Seq::singleton(<span class="self">self</span>::Literal::exact(<span class="macro">vec!</span>[])),
Literal(hir::Literal(<span class="kw-2">ref </span>bytes)) =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>seq =
Seq::singleton(<span class="self">self</span>::Literal::exact(bytes.to_vec()));
<span class="self">self</span>.enforce_literal_len(<span class="kw-2">&amp;mut </span>seq);
seq
}
Class(hir::Class::Unicode(<span class="kw-2">ref </span>cls)) =&gt; {
<span class="self">self</span>.extract_class_unicode(cls)
}
Class(hir::Class::Bytes(<span class="kw-2">ref </span>cls)) =&gt; <span class="self">self</span>.extract_class_bytes(cls),
Repetition(<span class="kw-2">ref </span>rep) =&gt; <span class="self">self</span>.extract_repetition(rep),
Capture(hir::Capture { <span class="kw-2">ref </span>sub, .. }) =&gt; <span class="self">self</span>.extract(sub),
Concat(<span class="kw-2">ref </span>hirs) =&gt; <span class="kw">match </span><span class="self">self</span>.kind {
ExtractKind::Prefix =&gt; <span class="self">self</span>.extract_concat(hirs.iter()),
ExtractKind::Suffix =&gt; <span class="self">self</span>.extract_concat(hirs.iter().rev()),
},
Alternation(<span class="kw-2">ref </span>hirs) =&gt; {
<span class="comment">// Unlike concat, we always union starting from the beginning,
// since the beginning corresponds to the highest preference,
// which doesn&#39;t change based on forwards vs reverse.
</span><span class="self">self</span>.extract_alternation(hirs.iter())
}
}
}
<span class="doccomment">/// Set the kind of literal sequence to extract from an [`Hir`] expression.
///
/// The default is to extract prefixes, but suffixes can be selected
/// instead. The contract for prefixes is that every match of the
/// corresponding `Hir` must start with one of the literals in the sequence
/// returned. Moreover, the _order_ of the sequence returned corresponds to
/// the preference order.
///
/// Suffixes satisfy a similar contract in that every match of the
/// corresponding `Hir` must end with one of the literals in the sequence
/// returned. However, there is no guarantee that the literals are in
/// preference order.
///
/// Remember that a sequence can be infinite. For example, unless the
/// limits are configured to be impractically large, attempting to extract
/// prefixes (or suffixes) for the pattern `[A-Z]` will return an infinite
/// sequence. Generally speaking, if the sequence returned is infinite,
/// then it is presumed to be unwise to do prefix (or suffix) optimizations
/// for the pattern.
</span><span class="kw">pub fn </span>kind(<span class="kw-2">&amp;mut </span><span class="self">self</span>, kind: ExtractKind) -&gt; <span class="kw-2">&amp;mut </span>Extractor {
<span class="self">self</span>.kind = kind;
<span class="self">self
</span>}
<span class="doccomment">/// Configure a limit on the length of the sequence that is permitted for
/// a character class. If a character class exceeds this limit, then the
/// sequence returned for it is infinite.
///
/// This prevents classes like `[A-Z]` or `\pL` from getting turned into
/// huge and likely unproductive sequences of literals.
///
/// # Example
///
/// This example shows how this limit can be lowered to decrease the tolerance
/// for character classes being turned into literal sequences.
///
/// ```
/// use regex_syntax::{hir::literal::{Extractor, Seq}, parse};
///
/// let hir = parse(r&quot;[0-9]&quot;)?;
///
/// let got = Extractor::new().extract(&amp;hir);
/// let expected = Seq::new([
/// &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;, &quot;7&quot;, &quot;8&quot;, &quot;9&quot;,
/// ]);
/// assert_eq!(expected, got);
///
/// // Now let&#39;s shrink the limit and see how that changes things.
/// let got = Extractor::new().limit_class(4).extract(&amp;hir);
/// let expected = Seq::infinite();
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>limit_class(<span class="kw-2">&amp;mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="kw-2">&amp;mut </span>Extractor {
<span class="self">self</span>.limit_class = limit;
<span class="self">self
</span>}
<span class="doccomment">/// Configure a limit on the total number of repetitions that is permitted
/// before literal extraction is stopped.
///
/// This is useful for limiting things like `(abcde){50}`, or more
/// insidiously, `(?:){1000000000}`. This limit prevents any one single
/// repetition from adding too much to a literal sequence.
///
/// With this limit set, repetitions that exceed it will be stopped and any
/// literals extracted up to that point will be made inexact.
///
/// # Example
///
/// This shows how to decrease the limit and compares it with the default.
///
/// ```
/// use regex_syntax::{hir::literal::{Extractor, Literal, Seq}, parse};
///
/// let hir = parse(r&quot;(abc){8}&quot;)?;
///
/// let got = Extractor::new().extract(&amp;hir);
/// let expected = Seq::new([&quot;abcabcabcabcabcabcabcabc&quot;]);
/// assert_eq!(expected, got);
///
/// // Now let&#39;s shrink the limit and see how that changes things.
/// let got = Extractor::new().limit_repeat(4).extract(&amp;hir);
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;abcabcabcabc&quot;),
/// ]);
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>limit_repeat(<span class="kw-2">&amp;mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="kw-2">&amp;mut </span>Extractor {
<span class="self">self</span>.limit_repeat = limit;
<span class="self">self
</span>}
<span class="doccomment">/// Configure a limit on the maximum length of any literal in a sequence.
///
/// This is useful for limiting things like `(abcde){5}{5}{5}{5}`. While
/// each repetition or literal in that regex is small, when all the
/// repetitions are applied, one ends up with a literal of length `5^4 =
/// 625`.
///
/// With this limit set, literals that exceed it will be made inexact and
/// thus prevented from growing.
///
/// # Example
///
/// This shows how to decrease the limit and compares it with the default.
///
/// ```
/// use regex_syntax::{hir::literal::{Extractor, Literal, Seq}, parse};
///
/// let hir = parse(r&quot;(abc){2}{2}{2}&quot;)?;
///
/// let got = Extractor::new().extract(&amp;hir);
/// let expected = Seq::new([&quot;abcabcabcabcabcabcabcabc&quot;]);
/// assert_eq!(expected, got);
///
/// // Now let&#39;s shrink the limit and see how that changes things.
/// let got = Extractor::new().limit_literal_len(14).extract(&amp;hir);
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;abcabcabcabcab&quot;),
/// ]);
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>limit_literal_len(<span class="kw-2">&amp;mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="kw-2">&amp;mut </span>Extractor {
<span class="self">self</span>.limit_literal_len = limit;
<span class="self">self
</span>}
<span class="doccomment">/// Configure a limit on the total number of literals that will be
/// returned.
///
/// This is useful as a practical measure for avoiding the creation of
/// large sequences of literals. While the extractor will automatically
/// handle local creations of large sequences (for example, `[A-Z]` yields
/// an infinite sequence by default), large sequences can be created
/// through non-local means as well.
///
/// For example, `[ab]{3}{3}` would yield a sequence of length `512 = 2^9`
/// despite each of the repetitions being small on their own. This limit
/// thus represents a &quot;catch all&quot; for avoiding locally small sequences from
/// combining into large sequences.
///
/// # Example
///
/// This example shows how reducing the limit will change the literal
/// sequence returned.
///
/// ```
/// use regex_syntax::{hir::literal::{Extractor, Literal, Seq}, parse};
///
/// let hir = parse(r&quot;[ab]{2}{2}&quot;)?;
///
/// let got = Extractor::new().extract(&amp;hir);
/// let expected = Seq::new([
/// &quot;aaaa&quot;, &quot;aaab&quot;, &quot;aaba&quot;, &quot;aabb&quot;,
/// &quot;abaa&quot;, &quot;abab&quot;, &quot;abba&quot;, &quot;abbb&quot;,
/// &quot;baaa&quot;, &quot;baab&quot;, &quot;baba&quot;, &quot;babb&quot;,
/// &quot;bbaa&quot;, &quot;bbab&quot;, &quot;bbba&quot;, &quot;bbbb&quot;,
/// ]);
/// assert_eq!(expected, got);
///
/// // The default limit is not too big, but big enough to extract all
/// // literals from &#39;[ab]{2}{2}&#39;. If we shrink the limit to less than 16,
/// // then we&#39;ll get a truncated set. Notice that it returns a sequence of
/// // length 4 even though our limit was 10. This is because the sequence
/// // is difficult to increase without blowing the limit. Notice also
/// // that every literal in the sequence is now inexact because they were
/// // stripped of some suffix.
/// let got = Extractor::new().limit_total(10).extract(&amp;hir);
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;aa&quot;),
/// Literal::inexact(&quot;ab&quot;),
/// Literal::inexact(&quot;ba&quot;),
/// Literal::inexact(&quot;bb&quot;),
/// ]);
/// assert_eq!(expected, got);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>limit_total(<span class="kw-2">&amp;mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="kw-2">&amp;mut </span>Extractor {
<span class="self">self</span>.limit_total = limit;
<span class="self">self
</span>}
<span class="doccomment">/// Extract a sequence from the given concatenation. Sequences from each of
/// the child HIR expressions are combined via cross product.
///
/// This short circuits once the cross product turns into a sequence
/// containing only inexact literals.
</span><span class="kw">fn </span>extract_concat&lt;<span class="lifetime">&#39;a</span>, I: Iterator&lt;Item = <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>Hir&gt;&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, it: I) -&gt; Seq {
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::singleton(<span class="self">self</span>::Literal::exact(<span class="macro">vec!</span>[]));
<span class="kw">for </span>hir <span class="kw">in </span>it {
<span class="comment">// If every element in the sequence is inexact, then a cross
// product will always be a no-op. Thus, there is nothing else we
// can add to it and can quit early. Note that this also includes
// infinite sequences.
</span><span class="kw">if </span>seq.is_inexact() {
<span class="kw">break</span>;
}
<span class="comment">// Note that &#39;cross&#39; also dispatches based on whether we&#39;re
// extracting prefixes or suffixes.
</span>seq = <span class="self">self</span>.cross(seq, <span class="kw-2">&amp;mut </span><span class="self">self</span>.extract(hir));
}
seq
}
<span class="doccomment">/// Extract a sequence from the given alternation.
///
/// This short circuits once the union turns into an infinite sequence.
</span><span class="kw">fn </span>extract_alternation&lt;<span class="lifetime">&#39;a</span>, I: Iterator&lt;Item = <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>Hir&gt;&gt;(
<span class="kw-2">&amp;</span><span class="self">self</span>,
it: I,
) -&gt; Seq {
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::empty();
<span class="kw">for </span>hir <span class="kw">in </span>it {
<span class="comment">// Once our &#39;seq&#39; is infinite, every subsequent union
// operation on it will itself always result in an
// infinite sequence. Thus, it can never change and we can
// short-circuit.
</span><span class="kw">if </span>!seq.is_finite() {
<span class="kw">break</span>;
}
seq = <span class="self">self</span>.union(seq, <span class="kw-2">&amp;mut </span><span class="self">self</span>.extract(hir));
}
seq
}
<span class="doccomment">/// Extract a sequence of literals from the given repetition. We do our
/// best, Some examples:
///
/// &#39;a*&#39; =&gt; [inexact(a), exact(&quot;&quot;)]
/// &#39;a*?&#39; =&gt; [exact(&quot;&quot;), inexact(a)]
/// &#39;a+&#39; =&gt; [inexact(a)]
/// &#39;a{3}&#39; =&gt; [exact(aaa)]
/// &#39;a{3,5} =&gt; [inexact(aaa)]
///
/// The key here really is making sure we get the &#39;inexact&#39; vs &#39;exact&#39;
/// attributes correct on each of the literals we add. For example, the
/// fact that &#39;a*&#39; gives us an inexact &#39;a&#39; and an exact empty string means
/// that a regex like &#39;ab*c&#39; will result in [inexact(ab), exact(ac)]
/// literals being extracted, which might actually be a better prefilter
/// than just &#39;a&#39;.
</span><span class="kw">fn </span>extract_repetition(<span class="kw-2">&amp;</span><span class="self">self</span>, rep: <span class="kw-2">&amp;</span>hir::Repetition) -&gt; Seq {
<span class="kw">let </span><span class="kw-2">mut </span>subseq = <span class="self">self</span>.extract(<span class="kw-2">&amp;</span>rep.sub);
<span class="kw">match </span><span class="kw-2">*</span>rep {
hir::Repetition { min: <span class="number">0</span>, max, greedy, .. } =&gt; {
<span class="comment">// When &#39;max=1&#39;, we can retain exactness, since &#39;a?&#39; is
// equivalent to &#39;a|&#39;. Similarly below, &#39;a??&#39; is equivalent to
// &#39;|a&#39;.
</span><span class="kw">if </span>max != <span class="prelude-val">Some</span>(<span class="number">1</span>) {
subseq.make_inexact();
}
<span class="kw">let </span><span class="kw-2">mut </span>empty = Seq::singleton(Literal::exact(<span class="macro">vec!</span>[]));
<span class="kw">if </span>!greedy {
mem::swap(<span class="kw-2">&amp;mut </span>subseq, <span class="kw-2">&amp;mut </span>empty);
}
<span class="self">self</span>.union(subseq, <span class="kw-2">&amp;mut </span>empty)
}
hir::Repetition { min, max: <span class="prelude-val">Some</span>(max), .. } <span class="kw">if </span>min == max =&gt; {
<span class="macro">assert!</span>(min &gt; <span class="number">0</span>); <span class="comment">// handled above
</span><span class="kw">let </span>limit =
u32::try_from(<span class="self">self</span>.limit_repeat).unwrap_or(u32::MAX);
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::singleton(Literal::exact(<span class="macro">vec!</span>[]));
<span class="kw">for _ in </span><span class="number">0</span>..cmp::min(min, limit) {
<span class="kw">if </span>seq.is_inexact() {
<span class="kw">break</span>;
}
seq = <span class="self">self</span>.cross(seq, <span class="kw-2">&amp;mut </span>subseq.clone());
}
<span class="kw">if </span>usize::try_from(min).is_err() || min &gt; limit {
seq.make_inexact();
}
seq
}
hir::Repetition { min, max: <span class="prelude-val">Some</span>(max), .. } <span class="kw">if </span>min &lt; max =&gt; {
<span class="macro">assert!</span>(min &gt; <span class="number">0</span>); <span class="comment">// handled above
</span><span class="kw">let </span>limit =
u32::try_from(<span class="self">self</span>.limit_repeat).unwrap_or(u32::MAX);
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::singleton(Literal::exact(<span class="macro">vec!</span>[]));
<span class="kw">for _ in </span><span class="number">0</span>..cmp::min(min, limit) {
<span class="kw">if </span>seq.is_inexact() {
<span class="kw">break</span>;
}
seq = <span class="self">self</span>.cross(seq, <span class="kw-2">&amp;mut </span>subseq.clone());
}
seq.make_inexact();
seq
}
hir::Repetition { .. } =&gt; {
subseq.make_inexact();
subseq
}
}
}
<span class="doccomment">/// Convert the given Unicode class into a sequence of literals if the
/// class is small enough. If the class is too big, return an infinite
/// sequence.
</span><span class="kw">fn </span>extract_class_unicode(<span class="kw-2">&amp;</span><span class="self">self</span>, cls: <span class="kw-2">&amp;</span>hir::ClassUnicode) -&gt; Seq {
<span class="kw">if </span><span class="self">self</span>.class_over_limit_unicode(cls) {
<span class="kw">return </span>Seq::infinite();
}
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::empty();
<span class="kw">for </span>r <span class="kw">in </span>cls.iter() {
<span class="kw">for </span>ch <span class="kw">in </span>r.start()..=r.end() {
seq.push(Literal::from(ch));
}
}
<span class="self">self</span>.enforce_literal_len(<span class="kw-2">&amp;mut </span>seq);
seq
}
<span class="doccomment">/// Convert the given byte class into a sequence of literals if the class
/// is small enough. If the class is too big, return an infinite sequence.
</span><span class="kw">fn </span>extract_class_bytes(<span class="kw-2">&amp;</span><span class="self">self</span>, cls: <span class="kw-2">&amp;</span>hir::ClassBytes) -&gt; Seq {
<span class="kw">if </span><span class="self">self</span>.class_over_limit_bytes(cls) {
<span class="kw">return </span>Seq::infinite();
}
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::empty();
<span class="kw">for </span>r <span class="kw">in </span>cls.iter() {
<span class="kw">for </span>b <span class="kw">in </span>r.start()..=r.end() {
seq.push(Literal::from(b));
}
}
<span class="self">self</span>.enforce_literal_len(<span class="kw-2">&amp;mut </span>seq);
seq
}
<span class="doccomment">/// Returns true if the given Unicode class exceeds the configured limits
/// on this extractor.
</span><span class="kw">fn </span>class_over_limit_unicode(<span class="kw-2">&amp;</span><span class="self">self</span>, cls: <span class="kw-2">&amp;</span>hir::ClassUnicode) -&gt; bool {
<span class="kw">let </span><span class="kw-2">mut </span>count = <span class="number">0</span>;
<span class="kw">for </span>r <span class="kw">in </span>cls.iter() {
<span class="kw">if </span>count &gt; <span class="self">self</span>.limit_class {
<span class="kw">return </span><span class="bool-val">true</span>;
}
count += r.len();
}
count &gt; <span class="self">self</span>.limit_class
}
<span class="doccomment">/// Returns true if the given byte class exceeds the configured limits on
/// this extractor.
</span><span class="kw">fn </span>class_over_limit_bytes(<span class="kw-2">&amp;</span><span class="self">self</span>, cls: <span class="kw-2">&amp;</span>hir::ClassBytes) -&gt; bool {
<span class="kw">let </span><span class="kw-2">mut </span>count = <span class="number">0</span>;
<span class="kw">for </span>r <span class="kw">in </span>cls.iter() {
<span class="kw">if </span>count &gt; <span class="self">self</span>.limit_class {
<span class="kw">return </span><span class="bool-val">true</span>;
}
count += r.len();
}
count &gt; <span class="self">self</span>.limit_class
}
<span class="doccomment">/// Compute the cross product of the two sequences if the result would be
/// within configured limits. Otherwise, make `seq2` infinite and cross the
/// infinite sequence with `seq1`.
</span><span class="kw">fn </span>cross(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="kw-2">mut </span>seq1: Seq, seq2: <span class="kw-2">&amp;mut </span>Seq) -&gt; Seq {
<span class="kw">if </span>seq1.max_cross_len(seq2).map_or(<span class="bool-val">false</span>, |len| len &gt; <span class="self">self</span>.limit_total)
{
seq2.make_infinite();
}
<span class="kw">if let </span>ExtractKind::Suffix = <span class="self">self</span>.kind {
seq1.cross_reverse(seq2);
} <span class="kw">else </span>{
seq1.cross_forward(seq2);
}
<span class="macro">assert!</span>(seq1.len().map_or(<span class="bool-val">true</span>, |x| x &lt;= <span class="self">self</span>.limit_total));
<span class="self">self</span>.enforce_literal_len(<span class="kw-2">&amp;mut </span>seq1);
seq1
}
<span class="doccomment">/// Union the two sequences if the result would be within configured
/// limits. Otherwise, make `seq2` infinite and union the infinite sequence
/// with `seq1`.
</span><span class="kw">fn </span>union(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="kw-2">mut </span>seq1: Seq, seq2: <span class="kw-2">&amp;mut </span>Seq) -&gt; Seq {
<span class="kw">if </span>seq1.max_union_len(seq2).map_or(<span class="bool-val">false</span>, |len| len &gt; <span class="self">self</span>.limit_total)
{
<span class="comment">// We try to trim our literal sequences to see if we can make
// room for more literals. The idea is that we&#39;d rather trim down
// literals already in our sequence if it means we can add a few
// more and retain a finite sequence. Otherwise, we&#39;ll union with
// an infinite sequence and that infects everything and effectively
// stops literal extraction in its tracks.
//
// We do we keep 4 bytes here? Well, it&#39;s a bit of an abstraction
// leakage. Downstream, the literals may wind up getting fed to
// the Teddy algorithm, which supports searching literals up to
// length 4. So that&#39;s why we pick that number here. Arguably this
// should be a tuneable parameter, but it seems a little tricky to
// describe. And I&#39;m still unsure if this is the right way to go
// about culling literal sequences.
</span><span class="kw">match </span><span class="self">self</span>.kind {
ExtractKind::Prefix =&gt; {
seq1.keep_first_bytes(<span class="number">4</span>);
seq2.keep_first_bytes(<span class="number">4</span>);
}
ExtractKind::Suffix =&gt; {
seq1.keep_last_bytes(<span class="number">4</span>);
seq2.keep_last_bytes(<span class="number">4</span>);
}
}
seq1.dedup();
seq2.dedup();
<span class="kw">if </span>seq1
.max_union_len(seq2)
.map_or(<span class="bool-val">false</span>, |len| len &gt; <span class="self">self</span>.limit_total)
{
seq2.make_infinite();
}
}
seq1.union(seq2);
<span class="macro">assert!</span>(seq1.len().map_or(<span class="bool-val">true</span>, |x| x &lt;= <span class="self">self</span>.limit_total));
seq1
}
<span class="doccomment">/// Applies the literal length limit to the given sequence. If none of the
/// literals in the sequence exceed the limit, then this is a no-op.
</span><span class="kw">fn </span>enforce_literal_len(<span class="kw-2">&amp;</span><span class="self">self</span>, seq: <span class="kw-2">&amp;mut </span>Seq) {
<span class="kw">let </span>len = <span class="self">self</span>.limit_literal_len;
<span class="kw">match </span><span class="self">self</span>.kind {
ExtractKind::Prefix =&gt; seq.keep_first_bytes(len),
ExtractKind::Suffix =&gt; seq.keep_last_bytes(len),
}
}
}
<span class="kw">impl </span>Default <span class="kw">for </span>Extractor {
<span class="kw">fn </span>default() -&gt; Extractor {
Extractor::new()
}
}
<span class="doccomment">/// The kind of literals to extract from an [`Hir`] expression.
///
/// The default extraction kind is `Prefix`.
</span><span class="attribute">#[non_exhaustive]
#[derive(Clone, Debug)]
</span><span class="kw">pub enum </span>ExtractKind {
<span class="doccomment">/// Extracts only prefix literals from a regex.
</span>Prefix,
<span class="doccomment">/// Extracts only suffix literals from a regex.
///
/// Note that the sequence returned by suffix literals currently may
/// not correctly represent leftmost-first or &quot;preference&quot; order match
/// semantics.
</span>Suffix,
}
<span class="kw">impl </span>ExtractKind {
<span class="doccomment">/// Returns true if this kind is the `Prefix` variant.
</span><span class="kw">pub fn </span>is_prefix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="macro">matches!</span>(<span class="kw-2">*</span><span class="self">self</span>, ExtractKind::Prefix)
}
<span class="doccomment">/// Returns true if this kind is the `Suffix` variant.
</span><span class="kw">pub fn </span>is_suffix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="macro">matches!</span>(<span class="kw-2">*</span><span class="self">self</span>, ExtractKind::Suffix)
}
}
<span class="kw">impl </span>Default <span class="kw">for </span>ExtractKind {
<span class="kw">fn </span>default() -&gt; ExtractKind {
ExtractKind::Prefix
}
}
<span class="doccomment">/// A sequence of literals.
///
/// A `Seq` is very much like a set in that it represents a union of its
/// members. That is, it corresponds to a set of literals where at least one
/// must match in order for a particular [`Hir`] expression to match. (Whether
/// this corresponds to the entire `Hir` expression, a prefix of it or a suffix
/// of it depends on how the `Seq` was extracted from the `Hir`.)
///
/// It is also unlike a set in that multiple identical literals may appear,
/// and that the order of the literals in the `Seq` matters. For example, if
/// the sequence is `[sam, samwise]` and leftmost-first matching is used, then
/// `samwise` can never match and the sequence is equivalent to `[sam]`.
///
/// # States of a sequence
///
/// A `Seq` has a few different logical states to consider:
///
/// * The sequence can represent &quot;any&quot; literal. When this happens, the set does
/// not have a finite size. The purpose of this state is to inhibit callers
/// from making assumptions about what literals are required in order to match
/// a particular [`Hir`] expression. Generally speaking, when a set is in this
/// state, literal optimizations are inhibited. A good example of a regex that
/// will cause this sort of set to apppear is `[A-Za-z]`. The character class
/// is just too big (and also too narrow) to be usefully expanded into 52
/// different literals. (Note that the decision for when a seq should become
/// infinite is determined by the caller. A seq itself has no hard-coded
/// limits.)
/// * The sequence can be empty, in which case, it is an affirmative statement
/// that there are no literals that can match the corresponding `Hir`.
/// Consequently, the `Hir` never matches any input. For example, `[a&amp;&amp;b]`.
/// * The sequence can be non-empty, in which case, at least one of the
/// literals must match in order for the corresponding `Hir` to match.
///
/// # Example
///
/// This example shows how literal sequences can be simplified by stripping
/// suffixes and minimizing while maintaining preference order.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq = Seq::new(&amp;[
/// &quot;farm&quot;,
/// &quot;appliance&quot;,
/// &quot;faraway&quot;,
/// &quot;apple&quot;,
/// &quot;fare&quot;,
/// &quot;gap&quot;,
/// &quot;applicant&quot;,
/// &quot;applaud&quot;,
/// ]);
/// seq.keep_first_bytes(3);
/// seq.minimize_by_preference();
/// // Notice that &#39;far&#39; comes before &#39;app&#39;, which matches the order in the
/// // original sequence. This guarantees that leftmost-first semantics are
/// // not altered by simplifying the set.
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;far&quot;),
/// Literal::inexact(&quot;app&quot;),
/// Literal::exact(&quot;gap&quot;),
/// ]);
/// assert_eq!(expected, seq);
/// ```
</span><span class="attribute">#[derive(Clone, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Seq {
<span class="doccomment">/// The members of this seq.
///
/// When `None`, the seq represents all possible literals. That is, it
/// prevents one from making assumptions about specific literals in the
/// seq, and forces one to treat it as if any literal might be in the seq.
///
/// Note that `Some(vec![])` is valid and corresponds to the empty seq of
/// literals, i.e., a regex that can never match. For example, `[a&amp;&amp;b]`.
/// It is distinct from `Some(vec![&quot;&quot;])`, which corresponds to the seq
/// containing an empty string, which matches at every position.
</span>literals: <span class="prelude-ty">Option</span>&lt;Vec&lt;Literal&gt;&gt;,
}
<span class="kw">impl </span>Seq {
<span class="doccomment">/// Returns an empty sequence.
///
/// An empty sequence matches zero literals, and thus corresponds to a
/// regex that itself can never match.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>empty() -&gt; Seq {
Seq { literals: <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[]) }
}
<span class="doccomment">/// Returns a sequence of literals without a finite size and may contain
/// any literal.
///
/// A sequence without finite size does not reveal anything about the
/// characteristics of the literals in its set. There are no fixed prefixes
/// or suffixes, nor are lower or upper bounds on the length of the literals
/// in the set known.
///
/// This is useful to represent constructs in a regex that are &quot;too big&quot;
/// to useful represent as a sequence of literals. For example, `[A-Za-z]`.
/// When sequences get too big, they lose their discriminating nature and
/// are more likely to produce false positives, which in turn makes them
/// less likely to speed up searches.
///
/// More pragmatically, for many regexes, enumerating all possible literals
/// is itself not possible or might otherwise use too many resources. So
/// constraining the size of sets during extraction is a practical trade
/// off to make.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>infinite() -&gt; Seq {
Seq { literals: <span class="prelude-val">None </span>}
}
<span class="doccomment">/// Returns a sequence containing a single literal.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>singleton(lit: Literal) -&gt; Seq {
Seq { literals: <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[lit]) }
}
<span class="doccomment">/// Returns a sequence of exact literals from the given byte strings.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>new&lt;I, B&gt;(it: I) -&gt; Seq
<span class="kw">where
</span>I: IntoIterator&lt;Item = B&gt;,
B: AsRef&lt;[u8]&gt;,
{
it.into_iter().map(|b| Literal::exact(b.as_ref())).collect()
}
<span class="doccomment">/// If this is a finite sequence, return its members as a slice of
/// literals.
///
/// The slice returned may be empty, in which case, there are no literals
/// that can match this sequence.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>literals(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>[Literal]&gt; {
<span class="self">self</span>.literals.as_deref()
}
<span class="doccomment">/// Push a literal to the end of this sequence.
///
/// If this sequence is not finite, then this is a no-op.
///
/// Similarly, if the most recently added item of this sequence is
/// equivalent to the literal given, then it is not added. This reflects
/// a `Seq`&#39;s &quot;set like&quot; behavior, and represents a practical trade off.
/// Namely, there is never any need to have two adjacent and equivalent
/// literals in the same sequence, _and_ it is easy to detect in some
/// cases.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>push(<span class="kw-2">&amp;mut </span><span class="self">self</span>, lit: Literal) {
<span class="kw">let </span>lits = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
<span class="kw">if </span>lits.last().map_or(<span class="bool-val">false</span>, |m| m == <span class="kw-2">&amp;</span>lit) {
<span class="kw">return</span>;
}
lits.push(lit);
}
<span class="doccomment">/// Make all of the literals in this sequence inexact.
///
/// This is a no-op if this sequence is not finite.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>make_inexact(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">let </span>lits = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
<span class="kw">for </span>lit <span class="kw">in </span>lits.iter_mut() {
lit.make_inexact();
}
}
<span class="doccomment">/// Converts this sequence to an infinite sequence.
///
/// This is a no-op if the sequence is already infinite.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>make_infinite(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.literals = <span class="prelude-val">None</span>;
}
<span class="doccomment">/// Modify this sequence to contain the cross product between it and the
/// sequence given.
///
/// The cross product only considers literals in this sequence that are
/// exact. That is, inexact literals are not extended.
///
/// The literals are always drained from `other`, even if none are used.
/// This permits callers to reuse the sequence allocation elsewhere.
///
/// If this sequence is infinite, then this is a no-op, regardless of what
/// `other` contains (and in this case, the literals are still drained from
/// `other`). If `other` is infinite and this sequence is finite, then this
/// is a no-op, unless this sequence contains a zero-length literal. In
/// which case, the infiniteness of `other` infects this sequence, and this
/// sequence is itself made infinite.
///
/// Like [`Seq::union`], this may attempt to deduplicate literals. See
/// [`Seq::dedup`] for how deduplication deals with exact and inexact
/// literals.
///
/// # Example
///
/// This example shows basic usage and how exact and inexact literals
/// interact.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::from_iter([
/// Literal::inexact(&quot;quux&quot;),
/// Literal::exact(&quot;baz&quot;),
/// ]);
/// seq1.cross_forward(&amp;mut seq2);
///
/// // The literals are pulled out of seq2.
/// assert_eq!(Some(0), seq2.len());
///
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;fooquux&quot;),
/// Literal::exact(&quot;foobaz&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// assert_eq!(expected, seq1);
/// ```
///
/// This example shows the behavior of when `other` is an infinite
/// sequence.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::infinite();
/// seq1.cross_forward(&amp;mut seq2);
///
/// // When seq2 is infinite, cross product doesn&#39;t add anything, but
/// // ensures all members of seq1 are inexact.
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// assert_eq!(expected, seq1);
/// ```
///
/// This example is like the one above, but shows what happens when this
/// sequence contains an empty string. In this case, an infinite `other`
/// sequence infects this sequence (because the empty string means that
/// there are no finite prefixes):
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::exact(&quot;&quot;), // inexact provokes same behavior
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::infinite();
/// seq1.cross_forward(&amp;mut seq2);
///
/// // seq1 is now infinite!
/// assert!(!seq1.is_finite());
/// ```
///
/// This example shows the behavior of this sequence is infinite.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::infinite();
/// let mut seq2 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// seq1.cross_forward(&amp;mut seq2);
///
/// // seq1 remains unchanged.
/// assert!(!seq1.is_finite());
/// // Even though the literals in seq2 weren&#39;t used, it was still drained.
/// assert_eq!(Some(0), seq2.len());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>cross_forward(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;mut </span>Seq) {
<span class="kw">let </span>(lits1, lits2) = <span class="kw">match </span><span class="self">self</span>.cross_preamble(other) {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>((lits1, lits2)) =&gt; (lits1, lits2),
};
<span class="kw">let </span>newcap = lits1.len().saturating_mul(lits2.len());
<span class="kw">for </span>selflit <span class="kw">in </span>mem::replace(lits1, Vec::with_capacity(newcap)) {
<span class="kw">if </span>!selflit.is_exact() {
lits1.push(selflit);
<span class="kw">continue</span>;
}
<span class="kw">for </span>otherlit <span class="kw">in </span>lits2.iter() {
<span class="kw">let </span><span class="kw-2">mut </span>newlit = Literal::exact(Vec::with_capacity(
selflit.len() + otherlit.len(),
));
newlit.extend(<span class="kw-2">&amp;</span>selflit);
newlit.extend(<span class="kw-2">&amp;</span>otherlit);
<span class="kw">if </span>!otherlit.is_exact() {
newlit.make_inexact();
}
lits1.push(newlit);
}
}
lits2.drain(..);
<span class="self">self</span>.dedup();
}
<span class="doccomment">/// Modify this sequence to contain the cross product between it and
/// the sequence given, where the sequences are treated as suffixes
/// instead of prefixes. Namely, the sequence `other` is *prepended*
/// to `self` (as opposed to `other` being *appended* to `self` in
/// [`Seq::cross_forward`]).
///
/// The cross product only considers literals in this sequence that are
/// exact. That is, inexact literals are not extended.
///
/// The literals are always drained from `other`, even if none are used.
/// This permits callers to reuse the sequence allocation elsewhere.
///
/// If this sequence is infinite, then this is a no-op, regardless of what
/// `other` contains (and in this case, the literals are still drained from
/// `other`). If `other` is infinite and this sequence is finite, then this
/// is a no-op, unless this sequence contains a zero-length literal. In
/// which case, the infiniteness of `other` infects this sequence, and this
/// sequence is itself made infinite.
///
/// Like [`Seq::union`], this may attempt to deduplicate literals. See
/// [`Seq::dedup`] for how deduplication deals with exact and inexact
/// literals.
///
/// # Example
///
/// This example shows basic usage and how exact and inexact literals
/// interact.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::from_iter([
/// Literal::inexact(&quot;quux&quot;),
/// Literal::exact(&quot;baz&quot;),
/// ]);
/// seq1.cross_reverse(&amp;mut seq2);
///
/// // The literals are pulled out of seq2.
/// assert_eq!(Some(0), seq2.len());
///
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;quuxfoo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// Literal::exact(&quot;bazfoo&quot;),
/// ]);
/// assert_eq!(expected, seq1);
/// ```
///
/// This example shows the behavior of when `other` is an infinite
/// sequence.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::infinite();
/// seq1.cross_reverse(&amp;mut seq2);
///
/// // When seq2 is infinite, cross product doesn&#39;t add anything, but
/// // ensures all members of seq1 are inexact.
/// let expected = Seq::from_iter([
/// Literal::inexact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// assert_eq!(expected, seq1);
/// ```
///
/// This example is like the one above, but shows what happens when this
/// sequence contains an empty string. In this case, an infinite `other`
/// sequence infects this sequence (because the empty string means that
/// there are no finite suffixes):
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::exact(&quot;&quot;), // inexact provokes same behavior
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// let mut seq2 = Seq::infinite();
/// seq1.cross_reverse(&amp;mut seq2);
///
/// // seq1 is now infinite!
/// assert!(!seq1.is_finite());
/// ```
///
/// This example shows the behavior when this sequence is infinite.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq1 = Seq::infinite();
/// let mut seq2 = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;bar&quot;),
/// ]);
/// seq1.cross_reverse(&amp;mut seq2);
///
/// // seq1 remains unchanged.
/// assert!(!seq1.is_finite());
/// // Even though the literals in seq2 weren&#39;t used, it was still drained.
/// assert_eq!(Some(0), seq2.len());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>cross_reverse(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;mut </span>Seq) {
<span class="kw">let </span>(lits1, lits2) = <span class="kw">match </span><span class="self">self</span>.cross_preamble(other) {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>((lits1, lits2)) =&gt; (lits1, lits2),
};
<span class="comment">// We basically proceed as we do in &#39;cross_forward&#39; at this point,
// except that the outer loop is now &#39;other&#39; and the inner loop is now
// &#39;self&#39;. That&#39;s because &#39;self&#39; corresponds to suffixes and &#39;other&#39;
// corresponds to the sequence we want to *prepend* to the suffixes.
</span><span class="kw">let </span>newcap = lits1.len().saturating_mul(lits2.len());
<span class="kw">let </span>selflits = mem::replace(lits1, Vec::with_capacity(newcap));
<span class="kw">for </span>(i, otherlit) <span class="kw">in </span>lits2.drain(..).enumerate() {
<span class="kw">for </span>selflit <span class="kw">in </span>selflits.iter() {
<span class="kw">if </span>!selflit.is_exact() {
<span class="comment">// If the suffix isn&#39;t exact, then we can&#39;t prepend
// anything to it. However, we still want to keep it. But
// we only want to keep one of them, to avoid duplication.
// (The duplication is okay from a correctness perspective,
// but wasteful.)
</span><span class="kw">if </span>i == <span class="number">0 </span>{
lits1.push(selflit.clone());
}
<span class="kw">continue</span>;
}
<span class="kw">let </span><span class="kw-2">mut </span>newlit = Literal::exact(Vec::with_capacity(
otherlit.len() + selflit.len(),
));
newlit.extend(<span class="kw-2">&amp;</span>otherlit);
newlit.extend(<span class="kw-2">&amp;</span>selflit);
<span class="kw">if </span>!otherlit.is_exact() {
newlit.make_inexact();
}
lits1.push(newlit);
}
}
<span class="self">self</span>.dedup();
}
<span class="doccomment">/// A helper function the corresponds to the subtle preamble for both
/// `cross_forward` and `cross_reverse`. In effect, it handles the cases
/// of infinite sequences for both `self` and `other`, as well as ensuring
/// that literals from `other` are drained even if they aren&#39;t used.
</span><span class="kw">fn </span>cross_preamble&lt;<span class="lifetime">&#39;a</span>&gt;(
<span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span><span class="kw-2">mut </span><span class="self">self</span>,
other: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span><span class="kw-2">mut </span>Seq,
) -&gt; <span class="prelude-ty">Option</span>&lt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span><span class="kw-2">mut </span>Vec&lt;Literal&gt;, <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span><span class="kw-2">mut </span>Vec&lt;Literal&gt;)&gt; {
<span class="kw">let </span>lits2 = <span class="kw">match </span>other.literals {
<span class="prelude-val">None </span>=&gt; {
<span class="comment">// If our current seq contains the empty string and the seq
// we&#39;re adding matches any literal, then it follows that the
// current seq must now also match any literal.
//
// Otherwise, we just have to make sure everything in this
// sequence is inexact.
</span><span class="kw">if </span><span class="self">self</span>.min_literal_len() == <span class="prelude-val">Some</span>(<span class="number">0</span>) {
<span class="kw-2">*</span><span class="self">self </span>= Seq::infinite();
} <span class="kw">else </span>{
<span class="self">self</span>.make_inexact();
}
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
<span class="kw">let </span>lits1 = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; {
<span class="comment">// If we aren&#39;t going to make it to the end of this routine
// where lits2 is drained, then we need to do it now.
</span>lits2.drain(..);
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
<span class="prelude-val">Some</span>((lits1, lits2))
}
<span class="doccomment">/// Unions the `other` sequence into this one.
///
/// The literals are always drained out of the given `other` sequence,
/// even if they are being unioned into an infinite sequence. This permits
/// the caller to reuse the `other` sequence in another context.
///
/// Some literal deduping may be performed. If any deduping happens,
/// any leftmost-first or &quot;preference&quot; order match semantics will be
/// preserved.
///
/// # Example
///
/// This example shows basic usage.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq1 = Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]);
/// let mut seq2 = Seq::new(&amp;[&quot;bar&quot;, &quot;quux&quot;, &quot;foo&quot;]);
/// seq1.union(&amp;mut seq2);
///
/// // The literals are pulled out of seq2.
/// assert_eq!(Some(0), seq2.len());
///
/// // Adjacent literals are deduped, but non-adjacent literals may not be.
/// assert_eq!(Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;, &quot;quux&quot;, &quot;foo&quot;]), seq1);
/// ```
///
/// This example shows that literals are drained from `other` even when
/// they aren&#39;t necessarily used.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq1 = Seq::infinite();
/// // Infinite sequences have no finite length.
/// assert_eq!(None, seq1.len());
///
/// let mut seq2 = Seq::new(&amp;[&quot;bar&quot;, &quot;quux&quot;, &quot;foo&quot;]);
/// seq1.union(&amp;mut seq2);
///
/// // seq1 is still infinite and seq2 has been drained.
/// assert_eq!(None, seq1.len());
/// assert_eq!(Some(0), seq2.len());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>union(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;mut </span>Seq) {
<span class="kw">let </span>lits2 = <span class="kw">match </span>other.literals {
<span class="prelude-val">None </span>=&gt; {
<span class="comment">// Unioning with an infinite sequence always results in an
// infinite sequence.
</span><span class="self">self</span>.make_infinite();
<span class="kw">return</span>;
}
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits.drain(..),
};
<span class="kw">let </span>lits1 = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
lits1.extend(lits2);
<span class="self">self</span>.dedup();
}
<span class="doccomment">/// Unions the `other` sequence into this one by splice the `other`
/// sequence at the position of the first zero-length literal.
///
/// This is useful for preserving preference order semantics when combining
/// two literal sequences. For example, in the regex `(a||f)+foo`, the
/// correct preference order prefix sequence is `[a, foo, f]`.
///
/// The literals are always drained out of the given `other` sequence,
/// even if they are being unioned into an infinite sequence. This permits
/// the caller to reuse the `other` sequence in another context. Note that
/// the literals are drained even if no union is performed as well, i.e.,
/// when this sequence does not contain a zero-length literal.
///
/// Some literal deduping may be performed. If any deduping happens,
/// any leftmost-first or &quot;preference&quot; order match semantics will be
/// preserved.
///
/// # Example
///
/// This example shows basic usage.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq1 = Seq::new(&amp;[&quot;a&quot;, &quot;&quot;, &quot;f&quot;, &quot;&quot;]);
/// let mut seq2 = Seq::new(&amp;[&quot;foo&quot;]);
/// seq1.union_into_empty(&amp;mut seq2);
///
/// // The literals are pulled out of seq2.
/// assert_eq!(Some(0), seq2.len());
/// // &#39;foo&#39; gets spliced into seq1 where the first empty string occurs.
/// assert_eq!(Seq::new(&amp;[&quot;a&quot;, &quot;foo&quot;, &quot;f&quot;]), seq1);
/// ```
///
/// This example shows that literals are drained from `other` even when
/// they aren&#39;t necessarily used.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq1 = Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]);
/// let mut seq2 = Seq::new(&amp;[&quot;bar&quot;, &quot;quux&quot;, &quot;foo&quot;]);
/// seq1.union_into_empty(&amp;mut seq2);
///
/// // seq1 has no zero length literals, so no splicing happens.
/// assert_eq!(Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]), seq1);
/// // Even though no splicing happens, seq2 is still drained.
/// assert_eq!(Some(0), seq2.len());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>union_into_empty(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;mut </span>Seq) {
<span class="kw">let </span>lits2 = other.literals.as_mut().map(|lits| lits.drain(..));
<span class="kw">let </span>lits1 = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) =&gt; lits,
};
<span class="kw">let </span>first_empty = <span class="kw">match </span>lits1.iter().position(|m| m.is_empty()) {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(i) =&gt; i,
};
<span class="kw">let </span>lits2 = <span class="kw">match </span>lits2 {
<span class="prelude-val">None </span>=&gt; {
<span class="comment">// Note that we are only here if we&#39;ve found an empty literal,
// which implies that an infinite sequence infects this seq and
// also turns it into an infinite sequence.
</span><span class="self">self</span>.literals = <span class="prelude-val">None</span>;
<span class="kw">return</span>;
}
<span class="prelude-val">Some</span>(lits) =&gt; lits,
};
<span class="comment">// Clearing out the empties needs to come before the splice because
// the splice might add more empties that we don&#39;t want to get rid
// of. Since we&#39;re splicing into the position of the first empty, the
// &#39;first_empty&#39; position computed above is still correct.
</span>lits1.retain(|m| !m.is_empty());
lits1.splice(first_empty..first_empty, lits2);
<span class="self">self</span>.dedup();
}
<span class="doccomment">/// Deduplicate adjacent equivalent literals in this sequence.
///
/// If adjacent literals are equivalent strings but one is exact and the
/// other inexact, the inexact literal is kept and the exact one is
/// removed.
///
/// Deduping an infinite sequence is a no-op.
///
/// # Example
///
/// This example shows how literals that are duplicate byte strings but
/// are not equivalent with respect to exactness are resolved.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::inexact(&quot;foo&quot;),
/// ]);
/// seq.dedup();
///
/// assert_eq!(Seq::from_iter([Literal::inexact(&quot;foo&quot;)]), seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>dedup(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
lits.dedup_by(|lit1, lit2| {
<span class="kw">if </span>lit1.as_bytes() != lit2.as_bytes() {
<span class="kw">return </span><span class="bool-val">false</span>;
}
<span class="kw">if </span>lit1.is_exact() != lit2.is_exact() {
lit1.make_inexact();
lit2.make_inexact();
}
<span class="bool-val">true
</span>});
}
}
<span class="doccomment">/// Sorts this sequence of literals lexicographically.
///
/// Note that if, before sorting, if a literal that is a prefix of another
/// literal appears after it, then after sorting, the sequence will not
/// represent the same preference order match semantics. For example,
/// sorting the sequence `[samwise, sam]` yields the sequence `[sam,
/// samwise]`. Under preference order semantics, the latter sequence will
/// never match `samwise` where as the first sequence can.
///
/// # Example
///
/// This example shows basic usage.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq = Seq::new(&amp;[&quot;foo&quot;, &quot;quux&quot;, &quot;bar&quot;]);
/// seq.sort();
///
/// assert_eq!(Seq::new(&amp;[&quot;bar&quot;, &quot;foo&quot;, &quot;quux&quot;]), seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>sort(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
lits.sort();
}
}
<span class="doccomment">/// Reverses all of the literals in this sequence.
///
/// The order of the sequence itself is preserved.
///
/// # Example
///
/// This example shows basic usage.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let mut seq = Seq::new(&amp;[&quot;oof&quot;, &quot;rab&quot;]);
/// seq.reverse_literals();
/// assert_eq!(Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]), seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>reverse_literals(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
<span class="kw">for </span>lit <span class="kw">in </span>lits.iter_mut() {
lit.reverse();
}
}
}
<span class="doccomment">/// Shrinks this seq to its minimal size while respecting the preference
/// order of its literals.
///
/// While this routine will remove duplicate literals from this seq, it
/// will also remove literals that can never match in a leftmost-first or
/// &quot;preference order&quot; search. Similar to [`Seq::dedup`], if a literal is
/// deduped, then the one that remains is made inexact.
///
/// This is a no-op on seqs that are empty or not finite.
///
/// # Example
///
/// This example shows the difference between `{sam, samwise}` and
/// `{samwise, sam}`.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// // If &#39;sam&#39; comes before &#39;samwise&#39; and a preference order search is
/// // executed, then &#39;samwise&#39; can never match.
/// let mut seq = Seq::new(&amp;[&quot;sam&quot;, &quot;samwise&quot;]);
/// seq.minimize_by_preference();
/// assert_eq!(Seq::from_iter([Literal::inexact(&quot;sam&quot;)]), seq);
///
/// // But if they are reversed, then it&#39;s possible for &#39;samwise&#39; to match
/// // since it is given higher preference.
/// let mut seq = Seq::new(&amp;[&quot;samwise&quot;, &quot;sam&quot;]);
/// seq.minimize_by_preference();
/// assert_eq!(Seq::new(&amp;[&quot;samwise&quot;, &quot;sam&quot;]), seq);
/// ```
///
/// This example shows that if an empty string is in this seq, then
/// anything that comes after it can never match.
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// // An empty string is a prefix of all strings, so it automatically
/// // inhibits any subsequent strings from matching.
/// let mut seq = Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;, &quot;&quot;, &quot;quux&quot;, &quot;fox&quot;]);
/// seq.minimize_by_preference();
/// let expected = Seq::from_iter([
/// Literal::exact(&quot;foo&quot;),
/// Literal::exact(&quot;bar&quot;),
/// Literal::inexact(&quot;&quot;),
/// ]);
/// assert_eq!(expected, seq);
///
/// // And of course, if it&#39;s at the beginning, then it makes it impossible
/// // for anything else to match.
/// let mut seq = Seq::new(&amp;[&quot;&quot;, &quot;foo&quot;, &quot;quux&quot;, &quot;fox&quot;]);
/// seq.minimize_by_preference();
/// assert_eq!(Seq::from_iter([Literal::inexact(&quot;&quot;)]), seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>minimize_by_preference(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
PreferenceTrie::minimize(lits, <span class="bool-val">false</span>);
}
}
<span class="doccomment">/// Trims all literals in this seq such that only the first `len` bytes
/// remain. If a literal has less than or equal to `len` bytes, then it
/// remains unchanged. Otherwise, it is trimmed and made inexact.
///
/// # Example
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq = Seq::new(&amp;[&quot;a&quot;, &quot;foo&quot;, &quot;quux&quot;]);
/// seq.keep_first_bytes(2);
///
/// let expected = Seq::from_iter([
/// Literal::exact(&quot;a&quot;),
/// Literal::inexact(&quot;fo&quot;),
/// Literal::inexact(&quot;qu&quot;),
/// ]);
/// assert_eq!(expected, seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>keep_first_bytes(<span class="kw-2">&amp;mut </span><span class="self">self</span>, len: usize) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
<span class="kw">for </span>m <span class="kw">in </span>lits.iter_mut() {
m.keep_first_bytes(len);
}
}
}
<span class="doccomment">/// Trims all literals in this seq such that only the last `len` bytes
/// remain. If a literal has less than or equal to `len` bytes, then it
/// remains unchanged. Otherwise, it is trimmed and made inexact.
///
/// # Example
///
/// ```
/// use regex_syntax::hir::literal::{Literal, Seq};
///
/// let mut seq = Seq::new(&amp;[&quot;a&quot;, &quot;foo&quot;, &quot;quux&quot;]);
/// seq.keep_last_bytes(2);
///
/// let expected = Seq::from_iter([
/// Literal::exact(&quot;a&quot;),
/// Literal::inexact(&quot;oo&quot;),
/// Literal::inexact(&quot;ux&quot;),
/// ]);
/// assert_eq!(expected, seq);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>keep_last_bytes(<span class="kw-2">&amp;mut </span><span class="self">self</span>, len: usize) {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
<span class="kw">for </span>m <span class="kw">in </span>lits.iter_mut() {
m.keep_last_bytes(len);
}
}
}
<span class="doccomment">/// Returns true if this sequence is finite.
///
/// When false, this sequence is infinite and must be treated as if it
/// contains every possible literal.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_finite(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.literals.is_some()
}
<span class="doccomment">/// Returns true if and only if this sequence is finite and empty.
///
/// An empty sequence never matches anything. It can only be produced by
/// literal extraction when the corresponding regex itself cannot match.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_empty(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.len() == <span class="prelude-val">Some</span>(<span class="number">0</span>)
}
<span class="doccomment">/// Returns the number of literals in this sequence if the sequence is
/// finite. If the sequence is infinite, then `None` is returned.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.literals.as_ref().map(|lits| lits.len())
}
<span class="doccomment">/// Returns true if and only if all literals in this sequence are exact.
///
/// This returns false if the sequence is infinite.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_exact(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.literals().map_or(<span class="bool-val">false</span>, |lits| lits.iter().all(|x| x.is_exact()))
}
<span class="doccomment">/// Returns true if and only if all literals in this sequence are inexact.
///
/// This returns true if the sequence is infinite.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_inexact(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.literals().map_or(<span class="bool-val">true</span>, |lits| lits.iter().all(|x| !x.is_exact()))
}
<span class="doccomment">/// Return the maximum length of the sequence that would result from
/// unioning `self` with `other`. If either set is infinite, then this
/// returns `None`.
</span><span class="attribute">#[inline]
</span><span class="kw">fn </span>max_union_len(<span class="kw-2">&amp;</span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>Seq) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">let </span>len1 = <span class="self">self</span>.len()<span class="question-mark">?</span>;
<span class="kw">let </span>len2 = other.len()<span class="question-mark">?</span>;
<span class="prelude-val">Some</span>(len1.saturating_add(len2))
}
<span class="doccomment">/// Return the maximum length of the sequence that would result from the
/// cross product of `self` with `other`. If either set is infinite, then
/// this returns `None`.
</span><span class="attribute">#[inline]
</span><span class="kw">fn </span>max_cross_len(<span class="kw-2">&amp;</span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>Seq) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">let </span>len1 = <span class="self">self</span>.len()<span class="question-mark">?</span>;
<span class="kw">let </span>len2 = other.len()<span class="question-mark">?</span>;
<span class="prelude-val">Some</span>(len1.saturating_mul(len2))
}
<span class="doccomment">/// Returns the length of the shortest literal in this sequence.
///
/// If the sequence is infinite or empty, then this returns `None`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>min_literal_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.literals.as_ref()<span class="question-mark">?</span>.iter().map(|x| x.len()).min()
}
<span class="doccomment">/// Returns the length of the longest literal in this sequence.
///
/// If the sequence is infinite or empty, then this returns `None`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>max_literal_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.literals.as_ref()<span class="question-mark">?</span>.iter().map(|x| x.len()).max()
}
<span class="doccomment">/// Returns the longest common prefix from this seq.
///
/// If the seq matches any literal or other contains no literals, then
/// there is no meaningful prefix and this returns `None`.
///
/// # Example
///
/// This shows some example seqs and their longest common prefix.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let seq = Seq::new(&amp;[&quot;foo&quot;, &quot;foobar&quot;, &quot;fo&quot;]);
/// assert_eq!(Some(&amp;b&quot;fo&quot;[..]), seq.longest_common_prefix());
/// let seq = Seq::new(&amp;[&quot;foo&quot;, &quot;foo&quot;]);
/// assert_eq!(Some(&amp;b&quot;foo&quot;[..]), seq.longest_common_prefix());
/// let seq = Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]);
/// assert_eq!(Some(&amp;b&quot;&quot;[..]), seq.longest_common_prefix());
/// let seq = Seq::new(&amp;[&quot;&quot;]);
/// assert_eq!(Some(&amp;b&quot;&quot;[..]), seq.longest_common_prefix());
///
/// let seq = Seq::infinite();
/// assert_eq!(None, seq.longest_common_prefix());
/// let seq = Seq::empty();
/// assert_eq!(None, seq.longest_common_prefix());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>longest_common_prefix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>[u8]&gt; {
<span class="comment">// If we match everything or match nothing, then there&#39;s no meaningful
// longest common prefix.
</span><span class="kw">let </span>lits = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref </span>lits) =&gt; lits,
};
<span class="kw">if </span>lits.len() == <span class="number">0 </span>{
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="kw">let </span>base = lits[<span class="number">0</span>].as_bytes();
<span class="kw">let </span><span class="kw-2">mut </span>len = base.len();
<span class="kw">for </span>m <span class="kw">in </span>lits.iter().skip(<span class="number">1</span>) {
len = m
.as_bytes()
.iter()
.zip(base[..len].iter())
.take_while(|<span class="kw-2">&amp;</span>(a, b)| a == b)
.count();
<span class="kw">if </span>len == <span class="number">0 </span>{
<span class="kw">return </span><span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>[]);
}
}
<span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>base[..len])
}
<span class="doccomment">/// Returns the longest common suffix from this seq.
///
/// If the seq matches any literal or other contains no literals, then
/// there is no meaningful suffix and this returns `None`.
///
/// # Example
///
/// This shows some example seqs and their longest common suffix.
///
/// ```
/// use regex_syntax::hir::literal::Seq;
///
/// let seq = Seq::new(&amp;[&quot;oof&quot;, &quot;raboof&quot;, &quot;of&quot;]);
/// assert_eq!(Some(&amp;b&quot;of&quot;[..]), seq.longest_common_suffix());
/// let seq = Seq::new(&amp;[&quot;foo&quot;, &quot;foo&quot;]);
/// assert_eq!(Some(&amp;b&quot;foo&quot;[..]), seq.longest_common_suffix());
/// let seq = Seq::new(&amp;[&quot;foo&quot;, &quot;bar&quot;]);
/// assert_eq!(Some(&amp;b&quot;&quot;[..]), seq.longest_common_suffix());
/// let seq = Seq::new(&amp;[&quot;&quot;]);
/// assert_eq!(Some(&amp;b&quot;&quot;[..]), seq.longest_common_suffix());
///
/// let seq = Seq::infinite();
/// assert_eq!(None, seq.longest_common_suffix());
/// let seq = Seq::empty();
/// assert_eq!(None, seq.longest_common_suffix());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>longest_common_suffix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>[u8]&gt; {
<span class="comment">// If we match everything or match nothing, then there&#39;s no meaningful
// longest common suffix.
</span><span class="kw">let </span>lits = <span class="kw">match </span><span class="self">self</span>.literals {
<span class="prelude-val">None </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref </span>lits) =&gt; lits,
};
<span class="kw">if </span>lits.len() == <span class="number">0 </span>{
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="kw">let </span>base = lits[<span class="number">0</span>].as_bytes();
<span class="kw">let </span><span class="kw-2">mut </span>len = base.len();
<span class="kw">for </span>m <span class="kw">in </span>lits.iter().skip(<span class="number">1</span>) {
len = m
.as_bytes()
.iter()
.rev()
.zip(base[base.len() - len..].iter().rev())
.take_while(|<span class="kw-2">&amp;</span>(a, b)| a == b)
.count();
<span class="kw">if </span>len == <span class="number">0 </span>{
<span class="kw">return </span><span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>[]);
}
}
<span class="prelude-val">Some</span>(<span class="kw-2">&amp;</span>base[base.len() - len..])
}
<span class="doccomment">/// Optimizes this seq while treating its literals as prefixes and
/// respecting the preference order of its literals.
///
/// The specific way &quot;optimization&quot; works is meant to be an implementation
/// detail, as it essentially represents a set of heuristics. The goal
/// that optimization tries to accomplish is to make the literals in this
/// set reflect inputs that will result in a more effective prefilter.
/// Principally by reducing the false positive rate of candidates found by
/// the literals in this sequence. That is, when a match of a literal is
/// found, we would like it to be a strong predictor of the overall match
/// of the regex. If it isn&#39;t, then much time will be spent starting and
/// stopping the prefilter search and attempting to confirm the match only
/// to have it fail.
///
/// Some of those heuristics might be:
///
/// * Identifying a common prefix from a larger sequence of literals, and
/// shrinking the sequence down to that single common prefix.
/// * Rejecting the sequence entirely if it is believed to result in very
/// high false positive rate. When this happens, the sequence is made
/// infinite.
/// * Shrinking the sequence to a smaller number of literals representing
/// prefixes, but not shrinking it so much as to make literals too short.
/// (A sequence with very short literals, of 1 or 2 bytes, will typically
/// result in a higher false positive rate.)
///
/// Optimization should only be run once extraction is complete. Namely,
/// optimization may make assumptions that do not compose with other
/// operations in the middle of extraction. For example, optimization will
/// reduce `[E(sam), E(samwise)]` to `[E(sam)]`, but such a transformation
/// is only valid if no other extraction will occur. If other extraction
/// may occur, then the correct transformation would be to `[I(sam)]`.
///
/// The [`Seq::optimize_for_suffix_by_preference`] does the same thing, but
/// for suffixes.
///
/// # Example
///
/// This shows how optimization might transform a sequence. Note that
/// the specific behavior is not a documented guarantee. The heuristics
/// used are an implementation detail and may change over time in semver
/// compatible releases.
///
/// ```
/// use regex_syntax::hir::literal::{Seq, Literal};
///
/// let mut seq = Seq::new(&amp;[
/// &quot;samantha&quot;,
/// &quot;sam&quot;,
/// &quot;samwise&quot;,
/// &quot;frodo&quot;,
/// ]);
/// seq.optimize_for_prefix_by_preference();
/// assert_eq!(Seq::from_iter([
/// Literal::exact(&quot;samantha&quot;),
/// // Kept exact even though &#39;samwise&#39; got pruned
/// // because optimization assumes literal extraction
/// // has finished.
/// Literal::exact(&quot;sam&quot;),
/// Literal::exact(&quot;frodo&quot;),
/// ]), seq);
/// ```
///
/// # Example: optimization may make the sequence infinite
///
/// If the heuristics deem that the sequence could cause a very high false
/// positive rate, then it may make the sequence infinite, effectively
/// disabling its use as a prefilter.
///
/// ```
/// use regex_syntax::hir::literal::{Seq, Literal};
///
/// let mut seq = Seq::new(&amp;[
/// &quot;samantha&quot;,
/// // An empty string matches at every position,
/// // thus rendering the prefilter completely
/// // ineffective.
/// &quot;&quot;,
/// &quot;sam&quot;,
/// &quot;samwise&quot;,
/// &quot;frodo&quot;,
/// ]);
/// seq.optimize_for_prefix_by_preference();
/// assert!(!seq.is_finite());
/// ```
///
/// Do note that just because there is a `&quot; &quot;` in the sequence, that
/// doesn&#39;t mean the sequence will always be made infinite after it is
/// optimized. Namely, if the sequence is considered exact (any match
/// corresponds to an overall match of the original regex), then any match
/// is an overall match, and so the false positive rate is always `0`.
///
/// To demonstrate this, we remove `samwise` from our sequence. This
/// results in no optimization happening and all literals remain exact.
/// Thus the entire sequence is exact, and it is kept as-is, even though
/// one is an ASCII space:
///
/// ```
/// use regex_syntax::hir::literal::{Seq, Literal};
///
/// let mut seq = Seq::new(&amp;[
/// &quot;samantha&quot;,
/// &quot; &quot;,
/// &quot;sam&quot;,
/// &quot;frodo&quot;,
/// ]);
/// seq.optimize_for_prefix_by_preference();
/// assert!(seq.is_finite());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>optimize_for_prefix_by_preference(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.optimize_by_preference(<span class="bool-val">true</span>);
}
<span class="doccomment">/// Optimizes this seq while treating its literals as suffixes and
/// respecting the preference order of its literals.
///
/// Optimization should only be run once extraction is complete.
///
/// The [`Seq::optimize_for_prefix_by_preference`] does the same thing, but
/// for prefixes. See its documentation for more explanation.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>optimize_for_suffix_by_preference(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.optimize_by_preference(<span class="bool-val">false</span>);
}
<span class="kw">fn </span>optimize_by_preference(<span class="kw-2">&amp;mut </span><span class="self">self</span>, prefix: bool) {
<span class="kw">let </span>origlen = <span class="kw">match </span><span class="self">self</span>.len() {
<span class="prelude-val">None </span>=&gt; <span class="kw">return</span>,
<span class="prelude-val">Some</span>(len) =&gt; len,
};
<span class="comment">// Make sure we start with the smallest sequence possible. We use a
// special version of preference minimization that retains exactness.
// This is legal because optimization is only expected to occur once
// extraction is complete.
</span><span class="kw">if </span>prefix {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>lits) = <span class="self">self</span>.literals {
PreferenceTrie::minimize(lits, <span class="bool-val">true</span>);
}
}
<span class="comment">// Look for a common prefix (or suffix). If we found one of those and
// it&#39;s long enough, then it&#39;s a good bet that it will be our fastest
// possible prefilter since single-substring search is so fast.
</span><span class="kw">let </span>fix = <span class="kw">if </span>prefix {
<span class="self">self</span>.longest_common_prefix()
} <span class="kw">else </span>{
<span class="self">self</span>.longest_common_suffix()
};
<span class="kw">if let </span><span class="prelude-val">Some</span>(fix) = fix {
<span class="comment">// As a special case, if we have a common prefix and the leading
// byte of that prefix is one that we think probably occurs rarely,
// then strip everything down to just that single byte. This should
// promote the use of memchr.
//
// ... we only do this though if our sequence has more than one
// literal. Otherwise, we&#39;d rather just stick with a single literal
// scan. That is, using memchr is probably better than looking
// for 2 or more literals, but probably not as good as a straight
// memmem search.
//
// ... and also only do this when the prefix is short and probably
// not too discriminatory anyway. If it&#39;s longer, then it&#39;s
// probably quite discriminatory and thus is likely to have a low
// false positive rate.
</span><span class="kw">if </span>prefix
&amp;&amp; origlen &gt; <span class="number">1
</span>&amp;&amp; fix.len() &gt;= <span class="number">1
</span>&amp;&amp; fix.len() &lt;= <span class="number">3
</span>&amp;&amp; rank(fix[<span class="number">0</span>]) &lt; <span class="number">200
</span>{
<span class="self">self</span>.keep_first_bytes(<span class="number">1</span>);
<span class="self">self</span>.dedup();
<span class="kw">return</span>;
}
<span class="comment">// We only strip down to the common prefix/suffix if we think
// the existing set of literals isn&#39;t great, or if the common
// prefix/suffix is expected to be particularly discriminatory.
</span><span class="kw">let </span>isfast =
<span class="self">self</span>.is_exact() &amp;&amp; <span class="self">self</span>.len().map_or(<span class="bool-val">false</span>, |len| len &lt;= <span class="number">16</span>);
<span class="kw">let </span>usefix = fix.len() &gt; <span class="number">4 </span>|| (fix.len() &gt; <span class="number">1 </span>&amp;&amp; !isfast);
<span class="kw">if </span>usefix {
<span class="comment">// If we keep exactly the number of bytes equal to the length
// of the prefix (or suffix), then by the definition of a
// prefix, every literal in the sequence will be equivalent.
// Thus, &#39;dedup&#39; will leave us with one literal.
//
// We do it this way to avoid an alloc, but also to make sure
// the exactness of literals is kept (or not).
</span><span class="kw">if </span>prefix {
<span class="self">self</span>.keep_first_bytes(fix.len());
} <span class="kw">else </span>{
<span class="self">self</span>.keep_last_bytes(fix.len());
}
<span class="self">self</span>.dedup();
<span class="macro">assert_eq!</span>(<span class="prelude-val">Some</span>(<span class="number">1</span>), <span class="self">self</span>.len());
<span class="comment">// We still fall through here. In particular, we want our
// longest common prefix to be subject to the poison check.
</span>}
}
<span class="comment">// Everything below this check is more-or-less about trying to
// heuristically reduce the false positive rate of a prefilter. But
// if our sequence is completely exact, then it&#39;s possible the regex
// engine can be skipped entirely. In this case, the false positive
// rate is zero because every literal match corresponds to a regex
// match.
//
// This is OK even if the sequence contains a poison literal. Remember,
// a literal is only poisononous because of what we assume about its
// impact on the false positive rate. However, we do still check for
// an empty string. Empty strings are weird and it&#39;s best to let the
// regex engine handle those.
//
// We do currently do this check after the longest common prefix (or
// suffix) check, under the theory that single-substring search is so
// fast that we want that even if we&#39;d end up turning an exact sequence
// into an inexact one. But this might be wrong...
</span><span class="kw">if </span><span class="self">self</span>.is_exact()
&amp;&amp; <span class="self">self</span>.min_literal_len().map_or(<span class="bool-val">false</span>, |len| len &gt; <span class="number">0</span>)
{
<span class="kw">return</span>;
}
<span class="comment">// Now we attempt to shorten the sequence. The idea here is that we
// don&#39;t want to look for too many literals, but we want to shorten
// our sequence enough to improve our odds of using better algorithms
// downstream (such as Teddy).
</span><span class="kw">const </span>ATTEMPTS: [(usize, usize); <span class="number">5</span>] =
[(<span class="number">5</span>, <span class="number">64</span>), (<span class="number">4</span>, <span class="number">64</span>), (<span class="number">3</span>, <span class="number">64</span>), (<span class="number">2</span>, <span class="number">64</span>), (<span class="number">1</span>, <span class="number">10</span>)];
<span class="kw">for </span>(keep, limit) <span class="kw">in </span>ATTEMPTS {
<span class="kw">let </span>len = <span class="kw">match </span><span class="self">self</span>.len() {
<span class="prelude-val">None </span>=&gt; <span class="kw">break</span>,
<span class="prelude-val">Some</span>(len) =&gt; len,
};
<span class="kw">if </span>len &lt;= limit {
<span class="kw">break</span>;
}
<span class="kw">if </span>prefix {
<span class="self">self</span>.keep_first_bytes(keep);
} <span class="kw">else </span>{
<span class="self">self</span>.keep_last_bytes(keep);
}
<span class="self">self</span>.minimize_by_preference();
}
<span class="comment">// Check for a poison literal. A poison literal is one that is short
// and is believed to have a very high match count. These poisons
// generally lead to a prefilter with a very high false positive rate,
// and thus overall worse performance.
//
// We do this last because we could have gone from a non-poisonous
// sequence to a poisonous one. Perhaps we should add some code to
// prevent such transitions in the first place, but then again, we
// likely only made the transition in the first place if the sequence
// was itself huge. And huge sequences are themselves poisonous. So...
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(lits) = <span class="self">self</span>.literals() {
<span class="kw">if </span>lits.iter().any(|lit| lit.is_poisonous()) {
<span class="self">self</span>.make_infinite();
}
}
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>Seq {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter) -&gt; core::fmt::Result {
<span class="macro">write!</span>(f, <span class="string">&quot;Seq&quot;</span>)<span class="question-mark">?</span>;
<span class="kw">if let </span><span class="prelude-val">Some</span>(lits) = <span class="self">self</span>.literals() {
f.debug_list().entries(lits.iter()).finish()
} <span class="kw">else </span>{
<span class="macro">write!</span>(f, <span class="string">&quot;[∅]&quot;</span>)
}
}
}
<span class="kw">impl </span>FromIterator&lt;Literal&gt; <span class="kw">for </span>Seq {
<span class="kw">fn </span>from_iter&lt;T: IntoIterator&lt;Item = Literal&gt;&gt;(it: T) -&gt; Seq {
<span class="kw">let </span><span class="kw-2">mut </span>seq = Seq::empty();
<span class="kw">for </span>literal <span class="kw">in </span>it {
seq.push(literal);
}
seq
}
}
<span class="doccomment">/// A single literal extracted from an [`Hir`] expression.
///
/// A literal is composed of two things:
///
/// * A sequence of bytes. No guarantees with respect to UTF-8 are provided.
/// In particular, even if the regex a literal is extracted from is UTF-8, the
/// literal extracted may not be valid UTF-8. (For example, if an [`Extractor`]
/// limit resulted in trimming a literal in a way that splits a codepoint.)
/// * Whether the literal is &quot;exact&quot; or not. An &quot;exact&quot; literal means that it
/// has not been trimmed, and may continue to be extended. If a literal is
/// &quot;exact&quot; after visiting the entire `Hir` expression, then this implies that
/// the literal leads to a match state. (Although it doesn&#39;t necessarily imply
/// all occurrences of the literal correspond to a match of the regex, since
/// literal extraction ignores look-around assertions.)
</span><span class="attribute">#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
</span><span class="kw">pub struct </span>Literal {
bytes: Vec&lt;u8&gt;,
exact: bool,
}
<span class="kw">impl </span>Literal {
<span class="doccomment">/// Returns a new exact literal containing the bytes given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>exact&lt;B: Into&lt;Vec&lt;u8&gt;&gt;&gt;(bytes: B) -&gt; Literal {
Literal { bytes: bytes.into(), exact: <span class="bool-val">true </span>}
}
<span class="doccomment">/// Returns a new inexact literal containing the bytes given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>inexact&lt;B: Into&lt;Vec&lt;u8&gt;&gt;&gt;(bytes: B) -&gt; Literal {
Literal { bytes: bytes.into(), exact: <span class="bool-val">false </span>}
}
<span class="doccomment">/// Returns the bytes in this literal.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>as_bytes(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[u8] {
<span class="kw-2">&amp;</span><span class="self">self</span>.bytes
}
<span class="doccomment">/// Yields ownership of the bytes inside this literal.
///
/// Note that this throws away whether the literal is &quot;exact&quot; or not.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>into_bytes(<span class="self">self</span>) -&gt; Vec&lt;u8&gt; {
<span class="self">self</span>.bytes
}
<span class="doccomment">/// Returns the length of this literal in bytes.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<span class="self">self</span>.as_bytes().len()
}
<span class="doccomment">/// Returns true if and only if this literal has zero bytes.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_empty(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.len() == <span class="number">0
</span>}
<span class="doccomment">/// Returns true if and only if this literal is exact.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_exact(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.exact
}
<span class="doccomment">/// Marks this literal as inexact.
///
/// Inexact literals can never be extended. For example,
/// [`Seq::cross_forward`] will not extend inexact literals.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>make_inexact(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.exact = <span class="bool-val">false</span>;
}
<span class="doccomment">/// Reverse the bytes in this literal.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>reverse(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.bytes.reverse();
}
<span class="doccomment">/// Extend this literal with the literal given.
///
/// If this literal is inexact, then this is a no-op.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>extend(<span class="kw-2">&amp;mut </span><span class="self">self</span>, lit: <span class="kw-2">&amp;</span>Literal) {
<span class="kw">if </span>!<span class="self">self</span>.is_exact() {
<span class="kw">return</span>;
}
<span class="self">self</span>.bytes.extend_from_slice(<span class="kw-2">&amp;</span>lit.bytes);
}
<span class="doccomment">/// Trims this literal such that only the first `len` bytes remain. If
/// this literal has fewer than `len` bytes, then it remains unchanged.
/// Otherwise, the literal is marked as inexact.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>keep_first_bytes(<span class="kw-2">&amp;mut </span><span class="self">self</span>, len: usize) {
<span class="kw">if </span>len &gt;= <span class="self">self</span>.len() {
<span class="kw">return</span>;
}
<span class="self">self</span>.make_inexact();
<span class="self">self</span>.bytes.truncate(len);
}
<span class="doccomment">/// Trims this literal such that only the last `len` bytes remain. If this
/// literal has fewer than `len` bytes, then it remains unchanged.
/// Otherwise, the literal is marked as inexact.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>keep_last_bytes(<span class="kw-2">&amp;mut </span><span class="self">self</span>, len: usize) {
<span class="kw">if </span>len &gt;= <span class="self">self</span>.len() {
<span class="kw">return</span>;
}
<span class="self">self</span>.make_inexact();
<span class="self">self</span>.bytes.drain(..<span class="self">self</span>.len() - len);
}
<span class="doccomment">/// Returns true if it is believe that this literal is likely to match very
/// frequently, and is thus not a good candidate for a prefilter.
</span><span class="kw">fn </span>is_poisonous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.is_empty() || (<span class="self">self</span>.len() == <span class="number">1 </span>&amp;&amp; rank(<span class="self">self</span>.as_bytes()[<span class="number">0</span>]) &gt;= <span class="number">250</span>)
}
}
<span class="kw">impl </span>From&lt;u8&gt; <span class="kw">for </span>Literal {
<span class="kw">fn </span>from(byte: u8) -&gt; Literal {
Literal::exact(<span class="macro">vec!</span>[byte])
}
}
<span class="kw">impl </span>From&lt;char&gt; <span class="kw">for </span>Literal {
<span class="kw">fn </span>from(ch: char) -&gt; Literal {
<span class="kw">use </span>alloc::string::ToString;
Literal::exact(ch.encode_utf8(<span class="kw-2">&amp;mut </span>[<span class="number">0</span>; <span class="number">4</span>]).to_string())
}
}
<span class="kw">impl </span>AsRef&lt;[u8]&gt; <span class="kw">for </span>Literal {
<span class="kw">fn </span>as_ref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[u8] {
<span class="self">self</span>.as_bytes()
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>Literal {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter) -&gt; core::fmt::Result {
<span class="kw">let </span>tag = <span class="kw">if </span><span class="self">self</span>.exact { <span class="string">&quot;E&quot; </span>} <span class="kw">else </span>{ <span class="string">&quot;I&quot; </span>};
f.debug_tuple(tag)
.field(<span class="kw-2">&amp;</span><span class="kw">crate</span>::debug::Bytes(<span class="self">self</span>.as_bytes()))
.finish()
}
}
<span class="doccomment">/// A &quot;preference&quot; trie that rejects literals that will never match when
/// executing a leftmost first or &quot;preference&quot; search.
///
/// For example, if &#39;sam&#39; is inserted, then trying to insert &#39;samwise&#39; will be
/// rejected because &#39;samwise&#39; can never match since &#39;sam&#39; will always take
/// priority. However, if &#39;samwise&#39; is inserted first, then inserting &#39;sam&#39;
/// after it is accepted. In this case, either &#39;samwise&#39; or &#39;sam&#39; can match in
/// a &quot;preference&quot; search.
///
/// Note that we only use this trie as a &quot;set.&quot; That is, given a sequence of
/// literals, we insert each one in order. An `insert` will reject a literal
/// if a prefix of that literal already exists in the trie. Thus, to rebuild
/// the &quot;minimal&quot; sequence, we simply only keep literals that were successfully
/// inserted. (Since we don&#39;t need traversal, one wonders whether we can make
/// some simplifications here, but I haven&#39;t given it a ton of thought and I&#39;ve
/// never seen this show up on a profile. Because of the heuristic limits
/// imposed on literal extractions, the size of the inputs here is usually
/// very small.)
</span><span class="attribute">#[derive(Debug, Default)]
</span><span class="kw">struct </span>PreferenceTrie {
<span class="doccomment">/// The states in this trie. The index of a state in this vector is its ID.
</span>states: Vec&lt;State&gt;,
<span class="doccomment">/// The index to allocate to the next literal added to this trie. Starts at
/// 0 and increments by 1 for every literal successfully added to the trie.
</span>next_literal_index: usize,
}
<span class="doccomment">/// A single state in a trie. Uses a sparse representation for its transitions.
</span><span class="attribute">#[derive(Debug, Default)]
</span><span class="kw">struct </span>State {
<span class="doccomment">/// Sparse representation of the transitions out of this state. Transitions
/// are sorted by byte. There is at most one such transition for any
/// particular byte.
</span>trans: Vec&lt;(u8, usize)&gt;,
<span class="doccomment">/// Whether this is a matching state or not. If it is, then it contains the
/// index to the matching literal.
</span>literal_index: <span class="prelude-ty">Option</span>&lt;usize&gt;,
}
<span class="kw">impl </span>PreferenceTrie {
<span class="doccomment">/// Minimizes the given sequence of literals while preserving preference
/// order semantics.
///
/// When `keep_exact` is true, the exactness of every literal retained is
/// kept. This is useful when dealing with a fully extracted `Seq` that
/// only contains exact literals. In that case, we can keep all retained
/// literals as exact because we know we&#39;ll never need to match anything
/// after them and because any removed literals are guaranteed to never
/// match.
</span><span class="kw">fn </span>minimize(literals: <span class="kw-2">&amp;mut </span>Vec&lt;Literal&gt;, keep_exact: bool) {
<span class="kw">use </span>core::cell::RefCell;
<span class="comment">// MSRV(1.61): Use retain_mut here to avoid interior mutability.
</span><span class="kw">let </span>trie = RefCell::new(PreferenceTrie::default());
<span class="kw">let </span><span class="kw-2">mut </span>make_inexact = <span class="macro">vec!</span>[];
literals.retain(|lit| {
<span class="kw">match </span>trie.borrow_mut().insert(lit.as_bytes()) {
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<span class="prelude-val">Err</span>(i) =&gt; {
<span class="kw">if </span>!keep_exact {
make_inexact.push(i);
}
<span class="bool-val">false
</span>}
}
});
<span class="kw">for </span>i <span class="kw">in </span>make_inexact {
literals[i].make_inexact();
}
}
<span class="doccomment">/// Returns `Ok` if the given byte string is accepted into this trie and
/// `Err` otherwise. The index for the success case corresponds to the
/// index of the literal added. The index for the error case corresponds to
/// the index of the literal already in the trie that prevented the given
/// byte string from being added. (Which implies it is a prefix of the one
/// given.)
///
/// In short, the byte string given is accepted into the trie if and only
/// if it is possible for it to match when executing a preference order
/// search.
</span><span class="kw">fn </span>insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bytes: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;usize, usize&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>prev = <span class="self">self</span>.root();
<span class="kw">if let </span><span class="prelude-val">Some</span>(idx) = <span class="self">self</span>.states[prev].literal_index {
<span class="kw">return </span><span class="prelude-val">Err</span>(idx);
}
<span class="kw">for </span><span class="kw-2">&amp;</span>b <span class="kw">in </span>bytes.iter() {
<span class="kw">match </span><span class="self">self</span>.states[prev].trans.binary_search_by_key(<span class="kw-2">&amp;</span>b, |t| t.<span class="number">0</span>) {
<span class="prelude-val">Ok</span>(i) =&gt; {
prev = <span class="self">self</span>.states[prev].trans[i].<span class="number">1</span>;
<span class="kw">if let </span><span class="prelude-val">Some</span>(idx) = <span class="self">self</span>.states[prev].literal_index {
<span class="kw">return </span><span class="prelude-val">Err</span>(idx);
}
}
<span class="prelude-val">Err</span>(i) =&gt; {
<span class="kw">let </span>next = <span class="self">self</span>.create_state();
<span class="self">self</span>.states[prev].trans.insert(i, (b, next));
prev = next;
}
}
}
<span class="kw">let </span>idx = <span class="self">self</span>.next_literal_index;
<span class="self">self</span>.next_literal_index += <span class="number">1</span>;
<span class="self">self</span>.states[prev].literal_index = <span class="prelude-val">Some</span>(idx);
<span class="prelude-val">Ok</span>(idx)
}
<span class="doccomment">/// Returns the root state ID, and if it doesn&#39;t exist, creates it.
</span><span class="kw">fn </span>root(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; usize {
<span class="kw">if </span>!<span class="self">self</span>.states.is_empty() {
<span class="number">0
</span>} <span class="kw">else </span>{
<span class="self">self</span>.create_state()
}
}
<span class="doccomment">/// Creates a new empty state and returns its ID.
</span><span class="kw">fn </span>create_state(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; usize {
<span class="kw">let </span>id = <span class="self">self</span>.states.len();
<span class="self">self</span>.states.push(State::default());
id
}
}
<span class="doccomment">/// Returns the &quot;rank&quot; of the given byte.
///
/// The minimum rank value is `0` and the maximum rank value is `255`.
///
/// The rank of a byte is derived from a heuristic background distribution of
/// relative frequencies of bytes. The heuristic says that lower the rank of a
/// byte, the less likely that byte is to appear in any arbitrary haystack.
</span><span class="kw">pub fn </span>rank(byte: u8) -&gt; u8 {
<span class="kw">crate</span>::rank::BYTE_FREQUENCIES[usize::from(byte)]
}
<span class="attribute">#[cfg(test)]
</span><span class="kw">mod </span>tests {
<span class="kw">use super</span>::<span class="kw-2">*</span>;
<span class="kw">fn </span>parse(pattern: <span class="kw-2">&amp;</span>str) -&gt; Hir {
<span class="kw">crate</span>::ParserBuilder::new().utf8(<span class="bool-val">false</span>).build().parse(pattern).unwrap()
}
<span class="kw">fn </span>prefixes(pattern: <span class="kw-2">&amp;</span>str) -&gt; Seq {
Extractor::new().kind(ExtractKind::Prefix).extract(<span class="kw-2">&amp;</span>parse(pattern))
}
<span class="kw">fn </span>suffixes(pattern: <span class="kw-2">&amp;</span>str) -&gt; Seq {
Extractor::new().kind(ExtractKind::Suffix).extract(<span class="kw-2">&amp;</span>parse(pattern))
}
<span class="kw">fn </span>e(pattern: <span class="kw-2">&amp;</span>str) -&gt; (Seq, Seq) {
(prefixes(pattern), suffixes(pattern))
}
<span class="attribute">#[allow(non_snake_case)]
</span><span class="kw">fn </span>E(x: <span class="kw-2">&amp;</span>str) -&gt; Literal {
Literal::exact(x.as_bytes())
}
<span class="attribute">#[allow(non_snake_case)]
</span><span class="kw">fn </span>I(x: <span class="kw-2">&amp;</span>str) -&gt; Literal {
Literal::inexact(x.as_bytes())
}
<span class="kw">fn </span>seq&lt;I: IntoIterator&lt;Item = Literal&gt;&gt;(it: I) -&gt; Seq {
Seq::from_iter(it)
}
<span class="kw">fn </span>infinite() -&gt; (Seq, Seq) {
(Seq::infinite(), Seq::infinite())
}
<span class="kw">fn </span>inexact&lt;I1, I2&gt;(it1: I1, it2: I2) -&gt; (Seq, Seq)
<span class="kw">where
</span>I1: IntoIterator&lt;Item = Literal&gt;,
I2: IntoIterator&lt;Item = Literal&gt;,
{
(Seq::from_iter(it1), Seq::from_iter(it2))
}
<span class="kw">fn </span>exact&lt;B: AsRef&lt;[u8]&gt;, I: IntoIterator&lt;Item = B&gt;&gt;(it: I) -&gt; (Seq, Seq) {
<span class="kw">let </span>s1 = Seq::new(it);
<span class="kw">let </span>s2 = s1.clone();
(s1, s2)
}
<span class="kw">fn </span>opt&lt;B: AsRef&lt;[u8]&gt;, I: IntoIterator&lt;Item = B&gt;&gt;(it: I) -&gt; (Seq, Seq) {
<span class="kw">let </span>(<span class="kw-2">mut </span>p, <span class="kw-2">mut </span>s) = exact(it);
p.optimize_for_prefix_by_preference();
s.optimize_for_suffix_by_preference();
(p, s)
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>literal() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>]), e(<span class="string">&quot;a&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;aaaaa&quot;</span>]), e(<span class="string">&quot;aaaaa&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;A&quot;</span>, <span class="string">&quot;a&quot;</span>]), e(<span class="string">&quot;(?i-u)a&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;AB&quot;</span>, <span class="string">&quot;Ab&quot;</span>, <span class="string">&quot;aB&quot;</span>, <span class="string">&quot;ab&quot;</span>]), e(<span class="string">&quot;(?i-u)ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abC&quot;</span>, <span class="string">&quot;abc&quot;</span>]), e(<span class="string">&quot;ab(?i-u)c&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">b&quot;\xFF&quot;</span>]), e(<span class="string">r&quot;(?-u:\xFF)&quot;</span>));
<span class="attribute">#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span>{
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;☃&quot;</span>]), e(<span class="string">&quot;☃&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;☃&quot;</span>]), e(<span class="string">&quot;(?i)☃&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;☃☃☃☃☃&quot;</span>]), e(<span class="string">&quot;☃☃☃☃☃&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;Δ&quot;</span>]), e(<span class="string">&quot;Δ&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;δ&quot;</span>]), e(<span class="string">&quot;δ&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;Δ&quot;</span>, <span class="string">&quot;δ&quot;</span>]), e(<span class="string">&quot;(?i)Δ&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;Δ&quot;</span>, <span class="string">&quot;δ&quot;</span>]), e(<span class="string">&quot;(?i)δ&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;S&quot;</span>, <span class="string">&quot;s&quot;</span>, <span class="string">&quot;ſ&quot;</span>]), e(<span class="string">&quot;(?i)S&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;S&quot;</span>, <span class="string">&quot;s&quot;</span>, <span class="string">&quot;ſ&quot;</span>]), e(<span class="string">&quot;(?i)s&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;S&quot;</span>, <span class="string">&quot;s&quot;</span>, <span class="string">&quot;ſ&quot;</span>]), e(<span class="string">&quot;(?i)ſ&quot;</span>));
}
<span class="kw">let </span>letters = <span class="string">&quot;ͱͳͷΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋ&quot;</span>;
<span class="macro">assert_eq!</span>(exact([letters]), e(letters));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]), e(<span class="string">&quot;[abc]&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a1b&quot;</span>, <span class="string">&quot;a2b&quot;</span>, <span class="string">&quot;a3b&quot;</span>]), e(<span class="string">&quot;a[123]b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;δ&quot;</span>, <span class="string">&quot;ε&quot;</span>]), e(<span class="string">&quot;[εδ]&quot;</span>));
<span class="attribute">#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span>{
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;Δ&quot;</span>, <span class="string">&quot;Ε&quot;</span>, <span class="string">&quot;δ&quot;</span>, <span class="string">&quot;ε&quot;</span>, <span class="string">&quot;ϵ&quot;</span>]), e(<span class="string">r&quot;(?i)[εδ]&quot;</span>));
}
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>look() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a\Ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a\zb&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a(?m:^)b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a(?m:$)b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a\bb&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a\Bb&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a(?-u:\b)b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;a(?-u:\B)b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;^ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;$ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;(?m:^)ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;(?m:$)ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;\bab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;\Bab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;(?-u:\b)ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;(?-u:\B)ab&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab^&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab$&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab(?m:^)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab(?m:$)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab\b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab\B&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab(?-u:\b)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;ab(?-u:\B)&quot;</span>));
<span class="kw">let </span>expected = (seq([I(<span class="string">&quot;aZ&quot;</span>), E(<span class="string">&quot;ab&quot;</span>)]), seq([I(<span class="string">&quot;Zb&quot;</span>), E(<span class="string">&quot;ab&quot;</span>)]));
<span class="macro">assert_eq!</span>(expected, e(<span class="string">r&quot;^aZ*b&quot;</span>));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>repetition() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;a?&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>, <span class="string">&quot;a&quot;</span>]), e(<span class="string">r&quot;a??&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;&quot;</span>)], [I(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;&quot;</span>)]), e(<span class="string">r&quot;a*&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([E(<span class="string">&quot;&quot;</span>), I(<span class="string">&quot;a&quot;</span>)], [E(<span class="string">&quot;&quot;</span>), I(<span class="string">&quot;a&quot;</span>)]), e(<span class="string">r&quot;a*?&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>)], [I(<span class="string">&quot;a&quot;</span>)]), e(<span class="string">r&quot;a+&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>)], [I(<span class="string">&quot;a&quot;</span>)]), e(<span class="string">r&quot;(a+)+&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;aZ{0}b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;aZb&quot;</span>, <span class="string">&quot;ab&quot;</span>]), e(<span class="string">r&quot;aZ?b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;ab&quot;</span>, <span class="string">&quot;aZb&quot;</span>]), e(<span class="string">r&quot;aZ??b&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;aZ&quot;</span>), E(<span class="string">&quot;ab&quot;</span>)], [I(<span class="string">&quot;Zb&quot;</span>), E(<span class="string">&quot;ab&quot;</span>)]),
e(<span class="string">r&quot;aZ*b&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact([E(<span class="string">&quot;ab&quot;</span>), I(<span class="string">&quot;aZ&quot;</span>)], [E(<span class="string">&quot;ab&quot;</span>), I(<span class="string">&quot;Zb&quot;</span>)]),
e(<span class="string">r&quot;aZ*?b&quot;</span>)
);
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;aZ&quot;</span>)], [I(<span class="string">&quot;Zb&quot;</span>)]), e(<span class="string">r&quot;aZ+b&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;aZ&quot;</span>)], [I(<span class="string">&quot;Zb&quot;</span>)]), e(<span class="string">r&quot;aZ+?b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;aZZb&quot;</span>]), e(<span class="string">r&quot;aZ{2}b&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;aZZ&quot;</span>)], [I(<span class="string">&quot;ZZb&quot;</span>)]), e(<span class="string">r&quot;aZ{2,3}b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;(abc)?&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>, <span class="string">&quot;abc&quot;</span>]), e(<span class="string">r&quot;(abc)??&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;b&quot;</span>)], [I(<span class="string">&quot;ab&quot;</span>), E(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;a*b&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([E(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;a&quot;</span>)], [E(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;ab&quot;</span>)]), e(<span class="string">r&quot;a*?b&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;ab&quot;</span>)], [I(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;ab+&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>)], [I(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;a*b+&quot;</span>));
<span class="comment">// FIXME: The suffixes for this don&#39;t look quite right to me. I think
// the right suffixes would be: [I(ac), I(bc), E(c)]. The main issue I
// think is that suffixes are computed by iterating over concatenations
// in reverse, and then [bc, ac, c] ordering is indeed correct from
// that perspective. We also test a few more equivalent regexes, and
// we get the same result, so it is consistent at least I suppose.
//
// The reason why this isn&#39;t an issue is that it only messes up
// preference order, and currently, suffixes are never used in a
// context where preference order matters. For prefixes it matters
// because we sometimes want to use prefilters without confirmation
// when all of the literals are exact (and there&#39;s no look-around). But
// we never do that for suffixes. Any time we use suffixes, we always
// include a confirmation step. If that ever changes, then it&#39;s likely
// this bug will need to be fixed, but last time I looked, it appears
// hard to do so.
</span><span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>), I(<span class="string">&quot;ac&quot;</span>), E(<span class="string">&quot;c&quot;</span>)]),
e(<span class="string">r&quot;a*b*c&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>), I(<span class="string">&quot;ac&quot;</span>), E(<span class="string">&quot;c&quot;</span>)]),
e(<span class="string">r&quot;(a+)?(b+)?c&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>), I(<span class="string">&quot;ac&quot;</span>), E(<span class="string">&quot;c&quot;</span>)]),
e(<span class="string">r&quot;(a+|)(b+|)c&quot;</span>)
);
<span class="comment">// A few more similarish but not identical regexes. These may have a
// similar problem as above.
</span><span class="macro">assert_eq!</span>(
inexact(
[I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;c&quot;</span>), E(<span class="string">&quot;&quot;</span>)],
[I(<span class="string">&quot;c&quot;</span>), I(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;&quot;</span>)]
),
e(<span class="string">r&quot;a*b*c*&quot;</span>)
);
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;c&quot;</span>)], [I(<span class="string">&quot;c&quot;</span>)]), e(<span class="string">r&quot;a*b*c+&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>)]), e(<span class="string">r&quot;a*b+c&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>)], [I(<span class="string">&quot;c&quot;</span>), I(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;a*b+c*&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;ab&quot;</span>), E(<span class="string">&quot;a&quot;</span>)], [I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;a&quot;</span>)]), e(<span class="string">r&quot;ab*&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;ab&quot;</span>), E(<span class="string">&quot;ac&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>), E(<span class="string">&quot;ac&quot;</span>)]),
e(<span class="string">r&quot;ab*c&quot;</span>)
);
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;ab&quot;</span>)], [I(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;ab+&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;ab&quot;</span>)], [I(<span class="string">&quot;bc&quot;</span>)]), e(<span class="string">r&quot;ab+c&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;z&quot;</span>), E(<span class="string">&quot;azb&quot;</span>)], [I(<span class="string">&quot;zazb&quot;</span>), E(<span class="string">&quot;azb&quot;</span>)]),
e(<span class="string">r&quot;z*azb&quot;</span>)
);
<span class="kw">let </span>expected =
exact([<span class="string">&quot;aaa&quot;</span>, <span class="string">&quot;aab&quot;</span>, <span class="string">&quot;aba&quot;</span>, <span class="string">&quot;abb&quot;</span>, <span class="string">&quot;baa&quot;</span>, <span class="string">&quot;bab&quot;</span>, <span class="string">&quot;bba&quot;</span>, <span class="string">&quot;bbb&quot;</span>]);
<span class="macro">assert_eq!</span>(expected, e(<span class="string">r&quot;[ab]{3}&quot;</span>));
<span class="kw">let </span>expected = inexact(
[
I(<span class="string">&quot;aaa&quot;</span>),
I(<span class="string">&quot;aab&quot;</span>),
I(<span class="string">&quot;aba&quot;</span>),
I(<span class="string">&quot;abb&quot;</span>),
I(<span class="string">&quot;baa&quot;</span>),
I(<span class="string">&quot;bab&quot;</span>),
I(<span class="string">&quot;bba&quot;</span>),
I(<span class="string">&quot;bbb&quot;</span>),
],
[
I(<span class="string">&quot;aaa&quot;</span>),
I(<span class="string">&quot;aab&quot;</span>),
I(<span class="string">&quot;aba&quot;</span>),
I(<span class="string">&quot;abb&quot;</span>),
I(<span class="string">&quot;baa&quot;</span>),
I(<span class="string">&quot;bab&quot;</span>),
I(<span class="string">&quot;bba&quot;</span>),
I(<span class="string">&quot;bbb&quot;</span>),
],
);
<span class="macro">assert_eq!</span>(expected, e(<span class="string">r&quot;[ab]{3,4}&quot;</span>));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>concat() {
<span class="kw">let </span>empty: [<span class="kw-2">&amp;</span>str; <span class="number">0</span>] = [];
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abcxyz&quot;</span>]), e(<span class="string">r&quot;abc()xyz&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abcxyz&quot;</span>]), e(<span class="string">r&quot;(abc)(xyz)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abcmnoxyz&quot;</span>]), e(<span class="string">r&quot;abc()mno()xyz&quot;</span>));
<span class="macro">assert_eq!</span>(exact(empty), e(<span class="string">r&quot;abc[a&amp;&amp;b]xyz&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abcxyz&quot;</span>]), e(<span class="string">r&quot;abc[a&amp;&amp;b]*xyz&quot;</span>));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>alternation() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;mno&quot;</span>, <span class="string">&quot;xyz&quot;</span>]), e(<span class="string">r&quot;abc|mno|xyz&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact(
[E(<span class="string">&quot;abc&quot;</span>), I(<span class="string">&quot;mZ&quot;</span>), E(<span class="string">&quot;mo&quot;</span>), E(<span class="string">&quot;xyz&quot;</span>)],
[E(<span class="string">&quot;abc&quot;</span>), I(<span class="string">&quot;Zo&quot;</span>), E(<span class="string">&quot;mo&quot;</span>), E(<span class="string">&quot;xyz&quot;</span>)]
),
e(<span class="string">r&quot;abc|mZ*o|xyz&quot;</span>)
);
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;xyz&quot;</span>]), e(<span class="string">r&quot;abc|M[a&amp;&amp;b]N|xyz&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;MN&quot;</span>, <span class="string">&quot;xyz&quot;</span>]), e(<span class="string">r&quot;abc|M[a&amp;&amp;b]*N|xyz&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;aaa&quot;</span>, <span class="string">&quot;aaaaa&quot;</span>]), e(<span class="string">r&quot;(?:|aa)aaa&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact(
[I(<span class="string">&quot;aaa&quot;</span>), E(<span class="string">&quot;&quot;</span>), I(<span class="string">&quot;aaaaa&quot;</span>), E(<span class="string">&quot;aa&quot;</span>)],
[I(<span class="string">&quot;aaa&quot;</span>), E(<span class="string">&quot;&quot;</span>), E(<span class="string">&quot;aa&quot;</span>)]
),
e(<span class="string">r&quot;(?:|aa)(?:aaa)*&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact(
[E(<span class="string">&quot;&quot;</span>), I(<span class="string">&quot;aaa&quot;</span>), E(<span class="string">&quot;aa&quot;</span>), I(<span class="string">&quot;aaaaa&quot;</span>)],
[E(<span class="string">&quot;&quot;</span>), I(<span class="string">&quot;aaa&quot;</span>), E(<span class="string">&quot;aa&quot;</span>)]
),
e(<span class="string">r&quot;(?:|aa)(?:aaa)*?&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact([E(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;&quot;</span>)], [E(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;&quot;</span>)]),
e(<span class="string">r&quot;a|b*&quot;</span>)
);
<span class="macro">assert_eq!</span>(inexact([E(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>)], [E(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>)]), e(<span class="string">r&quot;a|b+&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>)], [I(<span class="string">&quot;ab&quot;</span>), E(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>)]),
e(<span class="string">r&quot;a*b|c&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact(
[E(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;c&quot;</span>), E(<span class="string">&quot;&quot;</span>)],
[E(<span class="string">&quot;a&quot;</span>), E(<span class="string">&quot;b&quot;</span>), I(<span class="string">&quot;c&quot;</span>), E(<span class="string">&quot;&quot;</span>)]
),
e(<span class="string">r&quot;a|(?:b|c*)&quot;</span>)
);
<span class="macro">assert_eq!</span>(
inexact(
[I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;b&quot;</span>), E(<span class="string">&quot;c&quot;</span>), I(<span class="string">&quot;a&quot;</span>), I(<span class="string">&quot;ab&quot;</span>), E(<span class="string">&quot;c&quot;</span>)],
[I(<span class="string">&quot;ac&quot;</span>), I(<span class="string">&quot;bc&quot;</span>), E(<span class="string">&quot;c&quot;</span>), I(<span class="string">&quot;ac&quot;</span>), I(<span class="string">&quot;abc&quot;</span>), E(<span class="string">&quot;c&quot;</span>)],
),
e(<span class="string">r&quot;(a|b)*c|(a|ab)*c&quot;</span>)
);
<span class="macro">assert_eq!</span>(
exact([<span class="string">&quot;abef&quot;</span>, <span class="string">&quot;abgh&quot;</span>, <span class="string">&quot;cdef&quot;</span>, <span class="string">&quot;cdgh&quot;</span>]),
e(<span class="string">r&quot;(ab|cd)(ef|gh)&quot;</span>)
);
<span class="macro">assert_eq!</span>(
exact([
<span class="string">&quot;abefij&quot;</span>, <span class="string">&quot;abefkl&quot;</span>, <span class="string">&quot;abghij&quot;</span>, <span class="string">&quot;abghkl&quot;</span>, <span class="string">&quot;cdefij&quot;</span>, <span class="string">&quot;cdefkl&quot;</span>,
<span class="string">&quot;cdghij&quot;</span>, <span class="string">&quot;cdghkl&quot;</span>,
]),
e(<span class="string">r&quot;(ab|cd)(ef|gh)(ij|kl)&quot;</span>)
);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>impossible() {
<span class="kw">let </span>empty: [<span class="kw-2">&amp;</span>str; <span class="number">0</span>] = [];
<span class="macro">assert_eq!</span>(exact(empty), e(<span class="string">r&quot;[a&amp;&amp;b]&quot;</span>));
<span class="macro">assert_eq!</span>(exact(empty), e(<span class="string">r&quot;a[a&amp;&amp;b]&quot;</span>));
<span class="macro">assert_eq!</span>(exact(empty), e(<span class="string">r&quot;[a&amp;&amp;b]b&quot;</span>));
<span class="macro">assert_eq!</span>(exact(empty), e(<span class="string">r&quot;a[a&amp;&amp;b]b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>]), e(<span class="string">r&quot;a|[a&amp;&amp;b]|b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>]), e(<span class="string">r&quot;a|c[a&amp;&amp;b]|b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>]), e(<span class="string">r&quot;a|[a&amp;&amp;b]d|b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>]), e(<span class="string">r&quot;a|c[a&amp;&amp;b]d|b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;[a&amp;&amp;b]*&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;MN&quot;</span>]), e(<span class="string">r&quot;M[a&amp;&amp;b]*N&quot;</span>));
}
<span class="comment">// This tests patterns that contain something that defeats literal
// detection, usually because it would blow some limit on the total number
// of literals that can be returned.
//
// The main idea is that when literal extraction sees something that
// it knows will blow a limit, it replaces it with a marker that says
// &quot;any literal will match here.&quot; While not necessarily true, the
// over-estimation is just fine for the purposes of literal extraction,
// because the imprecision doesn&#39;t matter: too big is too big.
//
// This is one of the trickier parts of literal extraction, since we need
// to make sure all of our literal extraction operations correctly compose
// with the markers.
</span><span class="attribute">#[test]
</span><span class="kw">fn </span>anything() {
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;.&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;(?s).&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Za-z]&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;[A-Z]{0}&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]?&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]*&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]+&quot;</span>));
<span class="macro">assert_eq!</span>((seq([I(<span class="string">&quot;1&quot;</span>)]), Seq::infinite()), e(<span class="string">r&quot;1[A-Z]&quot;</span>));
<span class="macro">assert_eq!</span>((seq([I(<span class="string">&quot;1&quot;</span>)]), seq([I(<span class="string">&quot;2&quot;</span>)])), e(<span class="string">r&quot;1[A-Z]2&quot;</span>));
<span class="macro">assert_eq!</span>((Seq::infinite(), seq([I(<span class="string">&quot;123&quot;</span>)])), e(<span class="string">r&quot;[A-Z]+123&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]+123[A-Z]+&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;1|[A-Z]|3&quot;</span>));
<span class="macro">assert_eq!</span>(
(seq([E(<span class="string">&quot;1&quot;</span>), I(<span class="string">&quot;2&quot;</span>), E(<span class="string">&quot;3&quot;</span>)]), Seq::infinite()),
e(<span class="string">r&quot;1|2[A-Z]|3&quot;</span>),
);
<span class="macro">assert_eq!</span>(
(Seq::infinite(), seq([E(<span class="string">&quot;1&quot;</span>), I(<span class="string">&quot;2&quot;</span>), E(<span class="string">&quot;3&quot;</span>)])),
e(<span class="string">r&quot;1|[A-Z]2|3&quot;</span>),
);
<span class="macro">assert_eq!</span>(
(seq([E(<span class="string">&quot;1&quot;</span>), I(<span class="string">&quot;2&quot;</span>), E(<span class="string">&quot;4&quot;</span>)]), seq([E(<span class="string">&quot;1&quot;</span>), I(<span class="string">&quot;3&quot;</span>), E(<span class="string">&quot;4&quot;</span>)])),
e(<span class="string">r&quot;1|2[A-Z]3|4&quot;</span>),
);
<span class="macro">assert_eq!</span>((Seq::infinite(), seq([I(<span class="string">&quot;2&quot;</span>)])), e(<span class="string">r&quot;(?:|1)[A-Z]2&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;a&quot;</span>)], [I(<span class="string">&quot;z&quot;</span>)]), e(<span class="string">r&quot;a.z&quot;</span>));
}
<span class="comment">// Like the &#39;anything&#39; test, but it uses smaller limits in order to test
// the logic for effectively aborting literal extraction when the seqs get
// too big.
</span><span class="attribute">#[test]
</span><span class="kw">fn </span>anything_small_limits() {
<span class="kw">fn </span>prefixes(pattern: <span class="kw-2">&amp;</span>str) -&gt; Seq {
Extractor::new()
.kind(ExtractKind::Prefix)
.limit_total(<span class="number">10</span>)
.extract(<span class="kw-2">&amp;</span>parse(pattern))
}
<span class="kw">fn </span>suffixes(pattern: <span class="kw-2">&amp;</span>str) -&gt; Seq {
Extractor::new()
.kind(ExtractKind::Suffix)
.limit_total(<span class="number">10</span>)
.extract(<span class="kw-2">&amp;</span>parse(pattern))
}
<span class="kw">fn </span>e(pattern: <span class="kw-2">&amp;</span>str) -&gt; (Seq, Seq) {
(prefixes(pattern), suffixes(pattern))
}
<span class="macro">assert_eq!</span>(
(
seq([
I(<span class="string">&quot;aaa&quot;</span>),
I(<span class="string">&quot;aab&quot;</span>),
I(<span class="string">&quot;aba&quot;</span>),
I(<span class="string">&quot;abb&quot;</span>),
I(<span class="string">&quot;baa&quot;</span>),
I(<span class="string">&quot;bab&quot;</span>),
I(<span class="string">&quot;bba&quot;</span>),
I(<span class="string">&quot;bbb&quot;</span>)
]),
seq([
I(<span class="string">&quot;aaa&quot;</span>),
I(<span class="string">&quot;aab&quot;</span>),
I(<span class="string">&quot;aba&quot;</span>),
I(<span class="string">&quot;abb&quot;</span>),
I(<span class="string">&quot;baa&quot;</span>),
I(<span class="string">&quot;bab&quot;</span>),
I(<span class="string">&quot;bba&quot;</span>),
I(<span class="string">&quot;bbb&quot;</span>)
])
),
e(<span class="string">r&quot;[ab]{3}{3}&quot;</span>)
);
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;ab|cd|ef|gh|ij|kl|mn|op|qr|st|uv|wx|yz&quot;</span>));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>empty() {
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;^&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;$&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;(?m:^)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;(?m:$)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;\b&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;\B&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;(?-u:\b)&quot;</span>));
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;&quot;</span>]), e(<span class="string">r&quot;(?-u:\B)&quot;</span>));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>odds_and_ends() {
<span class="macro">assert_eq!</span>((Seq::infinite(), seq([I(<span class="string">&quot;a&quot;</span>)])), e(<span class="string">r&quot;.a&quot;</span>));
<span class="macro">assert_eq!</span>((seq([I(<span class="string">&quot;a&quot;</span>)]), Seq::infinite()), e(<span class="string">r&quot;a.&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;a|.&quot;</span>));
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;.|a&quot;</span>));
<span class="kw">let </span>pat = <span class="string">r&quot;M[ou]&#39;?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy]&quot;</span>;
<span class="kw">let </span>expected = inexact(
[<span class="string">&quot;Mo&#39;am&quot;</span>, <span class="string">&quot;Moam&quot;</span>, <span class="string">&quot;Mu&#39;am&quot;</span>, <span class="string">&quot;Muam&quot;</span>].map(I),
[
<span class="string">&quot;ddafi&quot;</span>, <span class="string">&quot;ddafy&quot;</span>, <span class="string">&quot;dhafi&quot;</span>, <span class="string">&quot;dhafy&quot;</span>, <span class="string">&quot;dzafi&quot;</span>, <span class="string">&quot;dzafy&quot;</span>, <span class="string">&quot;dafi&quot;</span>,
<span class="string">&quot;dafy&quot;</span>, <span class="string">&quot;tdafi&quot;</span>, <span class="string">&quot;tdafy&quot;</span>, <span class="string">&quot;thafi&quot;</span>, <span class="string">&quot;thafy&quot;</span>, <span class="string">&quot;tzafi&quot;</span>, <span class="string">&quot;tzafy&quot;</span>,
<span class="string">&quot;tafi&quot;</span>, <span class="string">&quot;tafy&quot;</span>, <span class="string">&quot;zdafi&quot;</span>, <span class="string">&quot;zdafy&quot;</span>, <span class="string">&quot;zhafi&quot;</span>, <span class="string">&quot;zhafy&quot;</span>, <span class="string">&quot;zzafi&quot;</span>,
<span class="string">&quot;zzafy&quot;</span>, <span class="string">&quot;zafi&quot;</span>, <span class="string">&quot;zafy&quot;</span>,
]
.map(I),
);
<span class="macro">assert_eq!</span>(expected, e(pat));
<span class="macro">assert_eq!</span>(
(seq([<span class="string">&quot;fn is_&quot;</span>, <span class="string">&quot;fn as_&quot;</span>].map(I)), Seq::infinite()),
e(<span class="string">r&quot;fn is_([A-Z]+)|fn as_([A-Z]+)&quot;</span>),
);
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;foo&quot;</span>)], [I(<span class="string">&quot;quux&quot;</span>)]),
e(<span class="string">r&quot;foo[A-Z]+bar[A-Z]+quux&quot;</span>)
);
<span class="macro">assert_eq!</span>(infinite(), e(<span class="string">r&quot;[A-Z]+bar[A-Z]+&quot;</span>));
<span class="macro">assert_eq!</span>(
exact([<span class="string">&quot;Sherlock Holmes&quot;</span>]),
e(<span class="string">r&quot;(?m)^Sherlock Holmes|Sherlock Holmes$&quot;</span>)
);
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;sa&quot;</span>, <span class="string">&quot;sb&quot;</span>]), e(<span class="string">r&quot;\bs(?:[ab])&quot;</span>));
}
<span class="comment">// This tests a specific regex along with some heuristic steps to reduce
// the sequences extracted. This is meant to roughly correspond to the
// types of heuristics used to shrink literal sets in practice. (Shrinking
// is done because you want to balance &quot;spend too much work looking for
// too many literals&quot; and &quot;spend too much work processing false positive
// matches from short literals.&quot;)
</span><span class="attribute">#[test]
#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span><span class="kw">fn </span>holmes() {
<span class="kw">let </span>expected = inexact(
[<span class="string">&quot;HOL&quot;</span>, <span class="string">&quot;HOl&quot;</span>, <span class="string">&quot;HoL&quot;</span>, <span class="string">&quot;Hol&quot;</span>, <span class="string">&quot;hOL&quot;</span>, <span class="string">&quot;hOl&quot;</span>, <span class="string">&quot;hoL&quot;</span>, <span class="string">&quot;hol&quot;</span>].map(I),
[
<span class="string">&quot;MES&quot;</span>, <span class="string">&quot;MEs&quot;</span>, <span class="string">&quot;Eſ&quot;</span>, <span class="string">&quot;MeS&quot;</span>, <span class="string">&quot;Mes&quot;</span>, <span class="string">&quot;eſ&quot;</span>, <span class="string">&quot;mES&quot;</span>, <span class="string">&quot;mEs&quot;</span>, <span class="string">&quot;meS&quot;</span>,
<span class="string">&quot;mes&quot;</span>,
]
.map(I),
);
<span class="kw">let </span>(<span class="kw-2">mut </span>prefixes, <span class="kw-2">mut </span>suffixes) = e(<span class="string">r&quot;(?i)Holmes&quot;</span>);
prefixes.keep_first_bytes(<span class="number">3</span>);
suffixes.keep_last_bytes(<span class="number">3</span>);
prefixes.minimize_by_preference();
suffixes.minimize_by_preference();
<span class="macro">assert_eq!</span>(expected, (prefixes, suffixes));
}
<span class="comment">// This tests that we get some kind of literals extracted for a beefier
// alternation with case insensitive mode enabled. At one point during
// development, this returned nothing, and motivated some special case
// code in Extractor::union to try and trim down the literal sequences
// if the union would blow the limits set.
</span><span class="attribute">#[test]
#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span><span class="kw">fn </span>holmes_alt() {
<span class="kw">let </span><span class="kw-2">mut </span>pre =
prefixes(<span class="string">r&quot;(?i)Sherlock|Holmes|Watson|Irene|Adler|John|Baker&quot;</span>);
<span class="macro">assert!</span>(pre.len().unwrap() &gt; <span class="number">0</span>);
pre.optimize_for_prefix_by_preference();
<span class="macro">assert!</span>(pre.len().unwrap() &gt; <span class="number">0</span>);
}
<span class="comment">// See: https://github.com/rust-lang/regex/security/advisories/GHSA-m5pq-gvj9-9vr8
// See: CVE-2022-24713
//
// We test this here to ensure literal extraction completes in reasonable
// time and isn&#39;t materially impacted by these sorts of pathological
// repeats.
</span><span class="attribute">#[test]
</span><span class="kw">fn </span>crazy_repeats() {
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;&quot;</span>)], [I(<span class="string">&quot;&quot;</span>)]), e(<span class="string">r&quot;(?:){4294967295}&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([I(<span class="string">&quot;&quot;</span>)], [I(<span class="string">&quot;&quot;</span>)]),
e(<span class="string">r&quot;(?:){64}{64}{64}{64}{64}{64}&quot;</span>)
);
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;&quot;</span>)], [I(<span class="string">&quot;&quot;</span>)]), e(<span class="string">r&quot;x{0}{4294967295}&quot;</span>));
<span class="macro">assert_eq!</span>(inexact([I(<span class="string">&quot;&quot;</span>)], [I(<span class="string">&quot;&quot;</span>)]), e(<span class="string">r&quot;(?:|){4294967295}&quot;</span>));
<span class="macro">assert_eq!</span>(
inexact([E(<span class="string">&quot;&quot;</span>)], [E(<span class="string">&quot;&quot;</span>)]),
e(<span class="string">r&quot;(?:){8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}&quot;</span>)
);
<span class="kw">let </span>repa = <span class="string">&quot;a&quot;</span>.repeat(<span class="number">100</span>);
<span class="macro">assert_eq!</span>(
inexact([I(<span class="kw-2">&amp;</span>repa)], [I(<span class="kw-2">&amp;</span>repa)]),
e(<span class="string">r&quot;a{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}{8}&quot;</span>)
);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>huge() {
<span class="kw">let </span>pat = <span class="string">r#&quot;(?-u)
2(?:
[45]\d{3}|
7(?:
1[0-267]|
2[0-289]|
3[0-29]|
4[01]|
5[1-3]|
6[013]|
7[0178]|
91
)|
8(?:
0[125]|
[139][1-6]|
2[0157-9]|
41|
6[1-35]|
7[1-5]|
8[1-8]|
90
)|
9(?:
0[0-2]|
1[0-4]|
2[568]|
3[3-6]|
5[5-7]|
6[0167]|
7[15]|
8[0146-9]
)
)\d{4}|
3(?:
12?[5-7]\d{2}|
0(?:
2(?:
[025-79]\d|
[348]\d{1,2}
)|
3(?:
[2-4]\d|
[56]\d?
)
)|
2(?:
1\d{2}|
2(?:
[12]\d|
[35]\d{1,2}|
4\d?
)
)|
3(?:
1\d{2}|
2(?:
[2356]\d|
4\d{1,2}
)
)|
4(?:
1\d{2}|
2(?:
2\d{1,2}|
[47]|
5\d{2}
)
)|
5(?:
1\d{2}|
29
)|
[67]1\d{2}|
8(?:
1\d{2}|
2(?:
2\d{2}|
3|
4\d
)
)
)\d{3}|
4(?:
0(?:
2(?:
[09]\d|
7
)|
33\d{2}
)|
1\d{3}|
2(?:
1\d{2}|
2(?:
[25]\d?|
[348]\d|
[67]\d{1,2}
)
)|
3(?:
1\d{2}(?:
\d{2}
)?|
2(?:
[045]\d|
[236-9]\d{1,2}
)|
32\d{2}
)|
4(?:
[18]\d{2}|
2(?:
[2-46]\d{2}|
3
)|
5[25]\d{2}
)|
5(?:
1\d{2}|
2(?:
3\d|
5
)
)|
6(?:
[18]\d{2}|
2(?:
3(?:
\d{2}
)?|
[46]\d{1,2}|
5\d{2}|
7\d
)|
5(?:
3\d?|
4\d|
[57]\d{1,2}|
6\d{2}|
8
)
)|
71\d{2}|
8(?:
[18]\d{2}|
23\d{2}|
54\d{2}
)|
9(?:
[18]\d{2}|
2[2-5]\d{2}|
53\d{1,2}
)
)\d{3}|
5(?:
02[03489]\d{2}|
1\d{2}|
2(?:
1\d{2}|
2(?:
2(?:
\d{2}
)?|
[457]\d{2}
)
)|
3(?:
1\d{2}|
2(?:
[37](?:
\d{2}
)?|
[569]\d{2}
)
)|
4(?:
1\d{2}|
2[46]\d{2}
)|
5(?:
1\d{2}|
26\d{1,2}
)|
6(?:
[18]\d{2}|
2|
53\d{2}
)|
7(?:
1|
24
)\d{2}|
8(?:
1|
26
)\d{2}|
91\d{2}
)\d{3}|
6(?:
0(?:
1\d{2}|
2(?:
3\d{2}|
4\d{1,2}
)
)|
2(?:
2[2-5]\d{2}|
5(?:
[3-5]\d{2}|
7
)|
8\d{2}
)|
3(?:
1|
2[3478]
)\d{2}|
4(?:
1|
2[34]
)\d{2}|
5(?:
1|
2[47]
)\d{2}|
6(?:
[18]\d{2}|
6(?:
2(?:
2\d|
[34]\d{2}
)|
5(?:
[24]\d{2}|
3\d|
5\d{1,2}
)
)
)|
72[2-5]\d{2}|
8(?:
1\d{2}|
2[2-5]\d{2}
)|
9(?:
1\d{2}|
2[2-6]\d{2}
)
)\d{3}|
7(?:
(?:
02|
[3-589]1|
6[12]|
72[24]
)\d{2}|
21\d{3}|
32
)\d{3}|
8(?:
(?:
4[12]|
[5-7]2|
1\d?
)|
(?:
0|
3[12]|
[5-7]1|
217
)\d
)\d{4}|
9(?:
[35]1|
(?:
[024]2|
81
)\d|
(?:
1|
[24]1
)\d{2}
)\d{3}
&quot;#</span>;
<span class="comment">// TODO: This is a good candidate of a seq of literals that could be
// shrunk quite a bit and still be very productive with respect to
// literal optimizations.
</span><span class="kw">let </span>(prefixes, suffixes) = e(pat);
<span class="macro">assert!</span>(!suffixes.is_finite());
<span class="macro">assert_eq!</span>(<span class="prelude-val">Some</span>(<span class="number">243</span>), prefixes.len());
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>optimize() {
<span class="comment">// This gets a common prefix that isn&#39;t too short.
</span><span class="kw">let </span>(p, s) =
opt([<span class="string">&quot;foobarfoobar&quot;</span>, <span class="string">&quot;foobar&quot;</span>, <span class="string">&quot;foobarzfoobar&quot;</span>, <span class="string">&quot;foobarfoobar&quot;</span>]);
<span class="macro">assert_eq!</span>(seq([I(<span class="string">&quot;foobar&quot;</span>)]), p);
<span class="macro">assert_eq!</span>(seq([I(<span class="string">&quot;foobar&quot;</span>)]), s);
<span class="comment">// This also finds a common prefix, but since it&#39;s only one byte, it
// prefers the multiple literals.
</span><span class="kw">let </span>(p, s) = opt([<span class="string">&quot;abba&quot;</span>, <span class="string">&quot;akka&quot;</span>, <span class="string">&quot;abccba&quot;</span>]);
<span class="macro">assert_eq!</span>(exact([<span class="string">&quot;abba&quot;</span>, <span class="string">&quot;akka&quot;</span>, <span class="string">&quot;abccba&quot;</span>]), (p, s));
<span class="kw">let </span>(p, s) = opt([<span class="string">&quot;sam&quot;</span>, <span class="string">&quot;samwise&quot;</span>]);
<span class="macro">assert_eq!</span>((seq([E(<span class="string">&quot;sam&quot;</span>)]), seq([E(<span class="string">&quot;sam&quot;</span>), E(<span class="string">&quot;samwise&quot;</span>)])), (p, s));
<span class="comment">// The empty string is poisonous, so our seq becomes infinite, even
// though all literals are exact.
</span><span class="kw">let </span>(p, s) = opt([<span class="string">&quot;foobarfoo&quot;</span>, <span class="string">&quot;foo&quot;</span>, <span class="string">&quot;&quot;</span>, <span class="string">&quot;foozfoo&quot;</span>, <span class="string">&quot;foofoo&quot;</span>]);
<span class="macro">assert!</span>(!p.is_finite());
<span class="macro">assert!</span>(!s.is_finite());
<span class="comment">// A space is also poisonous, so our seq becomes infinite. But this
// only gets triggered when we don&#39;t have a completely exact sequence.
// When the sequence is exact, spaces are okay, since we presume that
// any prefilter will match a space more quickly than the regex engine.
// (When the sequence is exact, there&#39;s a chance of the prefilter being
// used without needing the regex engine at all.)
</span><span class="kw">let </span><span class="kw-2">mut </span>p = seq([E(<span class="string">&quot;foobarfoo&quot;</span>), I(<span class="string">&quot;foo&quot;</span>), E(<span class="string">&quot; &quot;</span>), E(<span class="string">&quot;foofoo&quot;</span>)]);
p.optimize_for_prefix_by_preference();
<span class="macro">assert!</span>(!p.is_finite());
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="regex_syntax" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>