blob: c263ec4eaa8ef92d18ccbb685cc9e7add299b51a [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/termcolor-1.2.0/src/lib.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>lib.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="../../termcolor/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="../../termcolor/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>
</pre><pre class="rust"><code><span class="doccomment">/*!
This crate provides a cross platform abstraction for writing colored text to
a terminal. Colors are written using either ANSI escape sequences or by
communicating with a Windows console. Much of this API was motivated by use
inside command line applications, where colors or styles can be configured
by the end user and/or the environment.
This crate also provides platform independent support for writing colored text
to an in memory buffer. While this is easy to do with ANSI escape sequences
(because they are in the buffer themselves), it is trickier to do with the
Windows console API, which requires synchronous communication.
# Organization
The `WriteColor` trait extends the `io::Write` trait with methods for setting
colors or resetting them.
`StandardStream` and `StandardStreamLock` both satisfy `WriteColor` and are
analogous to `std::io::Stdout` and `std::io::StdoutLock`, or `std::io::Stderr`
and `std::io::StderrLock`.
`Buffer` is an in memory buffer that supports colored text. In a parallel
program, each thread might write to its own buffer. A buffer can be printed to
using a `BufferWriter`. The advantage of this design is that each thread can
work in parallel on a buffer without having to synchronize access to global
resources such as the Windows console. Moreover, this design also prevents
interleaving of buffer output.
`Ansi` and `NoColor` both satisfy `WriteColor` for arbitrary implementors of
`io::Write`. These types are useful when you know exactly what you need. An
analogous type for the Windows console is not provided since it cannot exist.
# Example: using `StandardStream`
The `StandardStream` type in this crate works similarly to `std::io::Stdout`,
except it is augmented with methods for coloring by the `WriteColor` trait.
For example, to write some green text:
```rust,no_run
# fn test() -&gt; Result&lt;(), Box&lt;::std::error::Error&gt;&gt; {
use std::io::Write;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
let mut stdout = StandardStream::stdout(ColorChoice::Always);
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
writeln!(&amp;mut stdout, &quot;green text!&quot;)?;
# Ok(()) }
```
Note that any text written to the terminal now will be colored
green when using ANSI escape sequences, even if it is written via
stderr, and even if stderr had previously been set to `Color::Red`.
Users will need to manage any color changes themselves by calling
[`WriteColor::set_color`](trait.WriteColor.html#tymethod.set_color), and this
may include calling [`WriteColor::reset`](trait.WriteColor.html#tymethod.reset)
before the program exits to a shell.
# Example: using `BufferWriter`
A `BufferWriter` can create buffers and write buffers to stdout or stderr. It
does *not* implement `io::Write` or `WriteColor` itself. Instead, `Buffer`
implements `io::Write` and `io::WriteColor`.
This example shows how to print some green text to stderr.
```rust,no_run
# fn test() -&gt; Result&lt;(), Box&lt;::std::error::Error&gt;&gt; {
use std::io::Write;
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};
let mut bufwtr = BufferWriter::stderr(ColorChoice::Always);
let mut buffer = bufwtr.buffer();
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
writeln!(&amp;mut buffer, &quot;green text!&quot;)?;
bufwtr.print(&amp;buffer)?;
# Ok(()) }
```
# Detecting presence of a terminal
In many scenarios when using color, one often wants to enable colors
automatically when writing to a terminal and disable colors automatically when
writing to anything else. The typical way to achieve this in Unix environments
is via libc&#39;s
[`isatty`](https://man7.org/linux/man-pages/man3/isatty.3.html)
function.
Unfortunately, this notoriously does not work well in Windows environments. To
work around that, the currently recommended solution is to use the
[`atty`](https://crates.io/crates/atty)
crate, which goes out of its way to get this as right as possible in Windows
environments.
For example, in a command line application that exposes a `--color` flag,
your logic for how to enable colors might look like this:
```rust,ignore
use atty;
use termcolor::{ColorChoice, StandardStream};
let preference = argv.get_flag(&quot;color&quot;).unwrap_or(&quot;auto&quot;);
let mut choice = preference.parse::&lt;ColorChoice&gt;()?;
if choice == ColorChoice::Auto &amp;&amp; !atty::is(atty::Stream::Stdout) {
choice = ColorChoice::Never;
}
let stdout = StandardStream::stdout(choice);
// ... write to stdout
```
Currently, `termcolor` does not provide anything to do this for you.
*/
</span><span class="attribute">#![deny(missing_debug_implementations, missing_docs)]
</span><span class="comment">// #[cfg(doctest)]
// use doc_comment::doctest;
// #[cfg(doctest)]
// doctest!(&quot;../README.md&quot;);
</span><span class="kw">use </span>std::env;
<span class="kw">use </span>std::error;
<span class="kw">use </span>std::fmt;
<span class="kw">use </span>std::io::{<span class="self">self</span>, Write};
<span class="kw">use </span>std::str::FromStr;
<span class="kw">use </span>std::sync::atomic::{AtomicBool, Ordering};
<span class="attribute">#[cfg(windows)]
</span><span class="kw">use </span>std::sync::{Mutex, MutexGuard};
<span class="attribute">#[cfg(windows)]
</span><span class="kw">use </span>winapi_util::console <span class="kw">as </span>wincon;
<span class="doccomment">/// This trait describes the behavior of writers that support colored output.
</span><span class="kw">pub trait </span>WriteColor: io::Write {
<span class="doccomment">/// Returns true if and only if the underlying writer supports colors.
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool;
<span class="doccomment">/// Set the color settings of the writer.
///
/// Subsequent writes to this writer will use these settings until either
/// `reset` is called or new color settings are set.
///
/// If there was a problem setting the color settings, then an error is
/// returned.
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt;;
<span class="doccomment">/// Reset the current color settings to their original settings.
///
/// If there was a problem resetting the color settings, then an error is
/// returned.
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt;;
<span class="doccomment">/// Returns true if and only if the underlying writer must synchronously
/// interact with an end user&#39;s device in order to control colors. By
/// default, this always returns `false`.
///
/// In practice, this should return `true` if the underlying writer is
/// manipulating colors using the Windows console APIs.
///
/// This is useful for writing generic code (such as a buffered writer)
/// that can perform certain optimizations when the underlying writer
/// doesn&#39;t rely on synchronous APIs. For example, ANSI escape sequences
/// can be passed through to the end user&#39;s device as is.
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>, T: <span class="question-mark">?</span>Sized + WriteColor&gt; WriteColor <span class="kw">for </span><span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span><span class="kw-2">mut </span>T {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
(<span class="kw-2">&amp;**</span><span class="self">self</span>).supports_color()
}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
(<span class="kw-2">&amp;mut **</span><span class="self">self</span>).set_color(spec)
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
(<span class="kw-2">&amp;mut **</span><span class="self">self</span>).reset()
}
<span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
(<span class="kw-2">&amp;**</span><span class="self">self</span>).is_synchronous()
}
}
<span class="kw">impl</span>&lt;T: <span class="question-mark">?</span>Sized + WriteColor&gt; WriteColor <span class="kw">for </span>Box&lt;T&gt; {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
(<span class="kw-2">&amp;**</span><span class="self">self</span>).supports_color()
}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
(<span class="kw-2">&amp;mut **</span><span class="self">self</span>).set_color(spec)
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
(<span class="kw-2">&amp;mut **</span><span class="self">self</span>).reset()
}
<span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
(<span class="kw-2">&amp;**</span><span class="self">self</span>).is_synchronous()
}
}
<span class="doccomment">/// ColorChoice represents the color preferences of an end user.
///
/// The `Default` implementation for this type will select `Auto`, which tries
/// to do the right thing based on the current environment.
///
/// The `FromStr` implementation for this type converts a lowercase kebab-case
/// string of the variant name to the corresponding variant. Any other string
/// results in an error.
</span><span class="attribute">#[derive(Clone, Copy, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>ColorChoice {
<span class="doccomment">/// Try very hard to emit colors. This includes emitting ANSI colors
/// on Windows if the console API is unavailable.
</span>Always,
<span class="doccomment">/// AlwaysAnsi is like Always, except it never tries to use anything other
/// than emitting ANSI color codes.
</span>AlwaysAnsi,
<span class="doccomment">/// Try to use colors, but don&#39;t force the issue. If the console isn&#39;t
/// available on Windows, or if TERM=dumb, or if `NO_COLOR` is defined, for
/// example, then don&#39;t use colors.
</span>Auto,
<span class="doccomment">/// Never emit colors.
</span>Never,
}
<span class="doccomment">/// The default is `Auto`.
</span><span class="kw">impl </span>Default <span class="kw">for </span>ColorChoice {
<span class="kw">fn </span>default() -&gt; ColorChoice {
ColorChoice::Auto
}
}
<span class="kw">impl </span>FromStr <span class="kw">for </span>ColorChoice {
<span class="kw">type </span><span class="prelude-val">Err </span>= ColorChoiceParseError;
<span class="kw">fn </span>from_str(s: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;ColorChoice, ColorChoiceParseError&gt; {
<span class="kw">match </span>s.to_lowercase().as_str() {
<span class="string">&quot;always&quot; </span>=&gt; <span class="prelude-val">Ok</span>(ColorChoice::Always),
<span class="string">&quot;always-ansi&quot; </span>=&gt; <span class="prelude-val">Ok</span>(ColorChoice::AlwaysAnsi),
<span class="string">&quot;never&quot; </span>=&gt; <span class="prelude-val">Ok</span>(ColorChoice::Never),
<span class="string">&quot;auto&quot; </span>=&gt; <span class="prelude-val">Ok</span>(ColorChoice::Auto),
unknown =&gt; <span class="prelude-val">Err</span>(ColorChoiceParseError {
unknown_choice: unknown.to_string(),
}),
}
}
}
<span class="kw">impl </span>ColorChoice {
<span class="doccomment">/// Returns true if we should attempt to write colored output.
</span><span class="kw">fn </span>should_attempt_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
ColorChoice::Always =&gt; <span class="bool-val">true</span>,
ColorChoice::AlwaysAnsi =&gt; <span class="bool-val">true</span>,
ColorChoice::Never =&gt; <span class="bool-val">false</span>,
ColorChoice::Auto =&gt; <span class="self">self</span>.env_allows_color(),
}
}
<span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>env_allows_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span>env::var_os(<span class="string">&quot;TERM&quot;</span>) {
<span class="comment">// If TERM isn&#39;t set, then we are in a weird environment that
// probably doesn&#39;t support colors.
</span><span class="prelude-val">None </span>=&gt; <span class="kw">return </span><span class="bool-val">false</span>,
<span class="prelude-val">Some</span>(k) =&gt; {
<span class="kw">if </span>k == <span class="string">&quot;dumb&quot; </span>{
<span class="kw">return </span><span class="bool-val">false</span>;
}
}
}
<span class="comment">// If TERM != dumb, then the only way we don&#39;t allow colors at this
// point is if NO_COLOR is set.
</span><span class="kw">if </span>env::var_os(<span class="string">&quot;NO_COLOR&quot;</span>).is_some() {
<span class="kw">return </span><span class="bool-val">false</span>;
}
<span class="bool-val">true
</span>}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>env_allows_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="comment">// On Windows, if TERM isn&#39;t set, then we shouldn&#39;t automatically
// assume that colors aren&#39;t allowed. This is unlike Unix environments
// where TERM is more rigorously set.
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(k) = env::var_os(<span class="string">&quot;TERM&quot;</span>) {
<span class="kw">if </span>k == <span class="string">&quot;dumb&quot; </span>{
<span class="kw">return </span><span class="bool-val">false</span>;
}
}
<span class="comment">// If TERM != dumb, then the only way we don&#39;t allow colors at this
// point is if NO_COLOR is set.
</span><span class="kw">if </span>env::var_os(<span class="string">&quot;NO_COLOR&quot;</span>).is_some() {
<span class="kw">return </span><span class="bool-val">false</span>;
}
<span class="bool-val">true
</span>}
<span class="doccomment">/// Returns true if this choice should forcefully use ANSI color codes.
///
/// It&#39;s possible that ANSI is still the correct choice even if this
/// returns false.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>should_ansi(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
ColorChoice::Always =&gt; <span class="bool-val">false</span>,
ColorChoice::AlwaysAnsi =&gt; <span class="bool-val">true</span>,
ColorChoice::Never =&gt; <span class="bool-val">false</span>,
ColorChoice::Auto =&gt; {
<span class="kw">match </span>env::var(<span class="string">&quot;TERM&quot;</span>) {
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<span class="comment">// cygwin doesn&#39;t seem to support ANSI escape sequences
// and instead has its own variety. However, the Windows
// console API may be available.
</span><span class="prelude-val">Ok</span>(k) =&gt; k != <span class="string">&quot;dumb&quot; </span>&amp;&amp; k != <span class="string">&quot;cygwin&quot;</span>,
}
}
}
}
}
<span class="doccomment">/// An error that occurs when parsing a `ColorChoice` fails.
</span><span class="attribute">#[derive(Clone, Debug)]
</span><span class="kw">pub struct </span>ColorChoiceParseError {
unknown_choice: String,
}
<span class="kw">impl </span>std::error::Error <span class="kw">for </span>ColorChoiceParseError {}
<span class="kw">impl </span>fmt::Display <span class="kw">for </span>ColorChoiceParseError {
<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>fmt::Formatter) -&gt; fmt::Result {
<span class="macro">write!</span>(
f,
<span class="string">&quot;unrecognized color choice &#39;{}&#39;: valid choices are: \
always, always-ansi, never, auto&quot;</span>,
<span class="self">self</span>.unknown_choice,
)
}
}
<span class="doccomment">/// `std::io` implements `Stdout` and `Stderr` (and their `Lock` variants) as
/// separate types, which makes it difficult to abstract over them. We use
/// some simple internal enum types to work around this.
</span><span class="kw">enum </span>StandardStreamType {
Stdout,
Stderr,
StdoutBuffered,
StderrBuffered,
}
<span class="attribute">#[derive(Debug)]
</span><span class="kw">enum </span>IoStandardStream {
Stdout(io::Stdout),
Stderr(io::Stderr),
StdoutBuffered(io::BufWriter&lt;io::Stdout&gt;),
StderrBuffered(io::BufWriter&lt;io::Stderr&gt;),
}
<span class="kw">impl </span>IoStandardStream {
<span class="kw">fn </span>new(sty: StandardStreamType) -&gt; IoStandardStream {
<span class="kw">match </span>sty {
StandardStreamType::Stdout =&gt; {
IoStandardStream::Stdout(io::stdout())
}
StandardStreamType::Stderr =&gt; {
IoStandardStream::Stderr(io::stderr())
}
StandardStreamType::StdoutBuffered =&gt; {
<span class="kw">let </span>wtr = io::BufWriter::new(io::stdout());
IoStandardStream::StdoutBuffered(wtr)
}
StandardStreamType::StderrBuffered =&gt; {
<span class="kw">let </span>wtr = io::BufWriter::new(io::stderr());
IoStandardStream::StderrBuffered(wtr)
}
}
}
<span class="kw">fn </span>lock(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; IoStandardStreamLock&lt;<span class="lifetime">&#39;_</span>&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
IoStandardStream::Stdout(<span class="kw-2">ref </span>s) =&gt; {
IoStandardStreamLock::StdoutLock(s.lock())
}
IoStandardStream::Stderr(<span class="kw-2">ref </span>s) =&gt; {
IoStandardStreamLock::StderrLock(s.lock())
}
IoStandardStream::StdoutBuffered(<span class="kw">_</span>)
| IoStandardStream::StderrBuffered(<span class="kw">_</span>) =&gt; {
<span class="comment">// We don&#39;t permit this case to ever occur in the public API,
// so it&#39;s OK to panic.
</span><span class="macro">panic!</span>(<span class="string">&quot;cannot lock a buffered standard stream&quot;</span>)
}
}
}
}
<span class="kw">impl </span>io::Write <span class="kw">for </span>IoStandardStream {
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, b: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
IoStandardStream::Stdout(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
IoStandardStream::Stderr(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
IoStandardStream::StdoutBuffered(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
IoStandardStream::StderrBuffered(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
}
}
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
IoStandardStream::Stdout(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
IoStandardStream::Stderr(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
IoStandardStream::StdoutBuffered(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
IoStandardStream::StderrBuffered(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
}
}
}
<span class="comment">// Same rigmarole for the locked variants of the standard streams.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">enum </span>IoStandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
StdoutLock(io::StdoutLock&lt;<span class="lifetime">&#39;a</span>&gt;),
StderrLock(io::StderrLock&lt;<span class="lifetime">&#39;a</span>&gt;),
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; io::Write <span class="kw">for </span>IoStandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, b: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
IoStandardStreamLock::StdoutLock(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
IoStandardStreamLock::StderrLock(<span class="kw-2">ref mut </span>s) =&gt; s.write(b),
}
}
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
IoStandardStreamLock::StdoutLock(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
IoStandardStreamLock::StderrLock(<span class="kw-2">ref mut </span>s) =&gt; s.flush(),
}
}
}
<span class="doccomment">/// Satisfies `io::Write` and `WriteColor`, and supports optional coloring
/// to either of the standard output streams, stdout and stderr.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>StandardStream {
wtr: LossyStandardStream&lt;WriterInner&lt;IoStandardStream&gt;&gt;,
}
<span class="doccomment">/// `StandardStreamLock` is a locked reference to a `StandardStream`.
///
/// This implements the `io::Write` and `WriteColor` traits, and is constructed
/// via the `Write::lock` method.
///
/// The lifetime `&#39;a` refers to the lifetime of the corresponding
/// `StandardStream`.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>StandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
wtr: LossyStandardStream&lt;WriterInnerLock&lt;<span class="lifetime">&#39;a</span>, IoStandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt;&gt;&gt;,
}
<span class="doccomment">/// Like `StandardStream`, but does buffered writing.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>BufferedStandardStream {
wtr: LossyStandardStream&lt;WriterInner&lt;IoStandardStream&gt;&gt;,
}
<span class="doccomment">/// WriterInner is a (limited) generic representation of a writer. It is
/// limited because W should only ever be stdout/stderr on Windows.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">enum </span>WriterInner&lt;W&gt; {
NoColor(NoColor&lt;W&gt;),
Ansi(Ansi&lt;W&gt;),
<span class="attribute">#[cfg(windows)]
</span>Windows {
wtr: W,
console: Mutex&lt;wincon::Console&gt;,
},
}
<span class="doccomment">/// WriterInnerLock is a (limited) generic representation of a writer. It is
/// limited because W should only ever be stdout/stderr on Windows.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">enum </span>WriterInnerLock&lt;<span class="lifetime">&#39;a</span>, W&gt; {
NoColor(NoColor&lt;W&gt;),
Ansi(Ansi&lt;W&gt;),
<span class="doccomment">/// What a gross hack. On Windows, we need to specify a lifetime for the
/// console when in a locked state, but obviously don&#39;t need to do that
/// on Unix, which makes the `&#39;a` unused. To satisfy the compiler, we need
/// a PhantomData.
</span><span class="attribute">#[allow(dead_code)]
</span>Unreachable(::std::marker::PhantomData&lt;<span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>()&gt;),
<span class="attribute">#[cfg(windows)]
</span>Windows {
wtr: W,
console: MutexGuard&lt;<span class="lifetime">&#39;a</span>, wincon::Console&gt;,
},
}
<span class="kw">impl </span>StandardStream {
<span class="doccomment">/// Create a new `StandardStream` with the given color preferences that
/// writes to standard output.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing via
/// the `WriteColor` trait.
</span><span class="kw">pub fn </span>stdout(choice: ColorChoice) -&gt; StandardStream {
<span class="kw">let </span>wtr = WriterInner::create(StandardStreamType::Stdout, choice);
StandardStream { wtr: LossyStandardStream::new(wtr) }
}
<span class="doccomment">/// Create a new `StandardStream` with the given color preferences that
/// writes to standard error.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing via
/// the `WriteColor` trait.
</span><span class="kw">pub fn </span>stderr(choice: ColorChoice) -&gt; StandardStream {
<span class="kw">let </span>wtr = WriterInner::create(StandardStreamType::Stderr, choice);
StandardStream { wtr: LossyStandardStream::new(wtr) }
}
<span class="doccomment">/// Lock the underlying writer.
///
/// The lock guard returned also satisfies `io::Write` and
/// `WriteColor`.
///
/// This method is **not reentrant**. It may panic if `lock` is called
/// while a `StandardStreamLock` is still alive.
</span><span class="kw">pub fn </span>lock(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; StandardStreamLock&lt;<span class="lifetime">&#39;_</span>&gt; {
StandardStreamLock::from_stream(<span class="self">self</span>)
}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; StandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>from_stream(stream: <span class="kw-2">&amp;</span>StandardStream) -&gt; StandardStreamLock&lt;<span class="lifetime">&#39;_</span>&gt; {
<span class="kw">let </span>locked = <span class="kw">match </span><span class="kw-2">*</span>stream.wtr.get_ref() {
WriterInner::NoColor(<span class="kw-2">ref </span>w) =&gt; {
WriterInnerLock::NoColor(NoColor(w.<span class="number">0</span>.lock()))
}
WriterInner::Ansi(<span class="kw-2">ref </span>w) =&gt; {
WriterInnerLock::Ansi(Ansi(w.<span class="number">0</span>.lock()))
}
};
StandardStreamLock { wtr: stream.wtr.wrap(locked) }
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>from_stream(stream: <span class="kw-2">&amp;</span>StandardStream) -&gt; StandardStreamLock {
<span class="kw">let </span>locked = <span class="kw">match </span><span class="kw-2">*</span>stream.wtr.get_ref() {
WriterInner::NoColor(<span class="kw-2">ref </span>w) =&gt; {
WriterInnerLock::NoColor(NoColor(w.<span class="number">0</span>.lock()))
}
WriterInner::Ansi(<span class="kw-2">ref </span>w) =&gt; {
WriterInnerLock::Ansi(Ansi(w.<span class="number">0</span>.lock()))
}
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { <span class="kw-2">ref </span>wtr, <span class="kw-2">ref </span>console } =&gt; {
WriterInnerLock::Windows {
wtr: wtr.lock(),
console: console.lock().unwrap(),
}
}
};
StandardStreamLock { wtr: stream.wtr.wrap(locked) }
}
}
<span class="kw">impl </span>BufferedStandardStream {
<span class="doccomment">/// Create a new `BufferedStandardStream` with the given color preferences
/// that writes to standard output via a buffered writer.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing via
/// the `WriteColor` trait.
</span><span class="kw">pub fn </span>stdout(choice: ColorChoice) -&gt; BufferedStandardStream {
<span class="kw">let </span>wtr =
WriterInner::create(StandardStreamType::StdoutBuffered, choice);
BufferedStandardStream { wtr: LossyStandardStream::new(wtr) }
}
<span class="doccomment">/// Create a new `BufferedStandardStream` with the given color preferences
/// that writes to standard error via a buffered writer.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing via
/// the `WriteColor` trait.
</span><span class="kw">pub fn </span>stderr(choice: ColorChoice) -&gt; BufferedStandardStream {
<span class="kw">let </span>wtr =
WriterInner::create(StandardStreamType::StderrBuffered, choice);
BufferedStandardStream { wtr: LossyStandardStream::new(wtr) }
}
}
<span class="kw">impl </span>WriterInner&lt;IoStandardStream&gt; {
<span class="doccomment">/// Create a new inner writer for a standard stream with the given color
/// preferences.
</span><span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>create(
sty: StandardStreamType,
choice: ColorChoice,
) -&gt; WriterInner&lt;IoStandardStream&gt; {
<span class="kw">if </span>choice.should_attempt_color() {
WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
} <span class="kw">else </span>{
WriterInner::NoColor(NoColor(IoStandardStream::new(sty)))
}
}
<span class="doccomment">/// Create a new inner writer for a standard stream with the given color
/// preferences.
///
/// If coloring is desired and a Windows console could not be found, then
/// ANSI escape sequences are used instead.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>create(
sty: StandardStreamType,
choice: ColorChoice,
) -&gt; WriterInner&lt;IoStandardStream&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>con = <span class="kw">match </span>sty {
StandardStreamType::Stdout =&gt; wincon::Console::stdout(),
StandardStreamType::Stderr =&gt; wincon::Console::stderr(),
StandardStreamType::StdoutBuffered =&gt; wincon::Console::stdout(),
StandardStreamType::StderrBuffered =&gt; wincon::Console::stderr(),
};
<span class="kw">let </span>is_console_virtual = con
.as_mut()
.map(|con| con.set_virtual_terminal_processing(<span class="bool-val">true</span>).is_ok())
.unwrap_or(<span class="bool-val">false</span>);
<span class="kw">if </span>choice.should_attempt_color() {
<span class="kw">if </span>choice.should_ansi() || is_console_virtual {
WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
} <span class="kw">else if let </span><span class="prelude-val">Ok</span>(console) = con {
WriterInner::Windows {
wtr: IoStandardStream::new(sty),
console: Mutex::new(console),
}
} <span class="kw">else </span>{
WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
}
} <span class="kw">else </span>{
WriterInner::NoColor(NoColor(IoStandardStream::new(sty)))
}
}
}
<span class="kw">impl </span>io::Write <span class="kw">for </span>StandardStream {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, b: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.wtr.write(b)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.flush()
}
}
<span class="kw">impl </span>WriteColor <span class="kw">for </span>StandardStream {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.supports_color()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.set_color(spec)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.reset()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.is_synchronous()
}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; io::Write <span class="kw">for </span>StandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, b: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.wtr.write(b)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.flush()
}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; WriteColor <span class="kw">for </span>StandardStreamLock&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.supports_color()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.set_color(spec)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.reset()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.is_synchronous()
}
}
<span class="kw">impl </span>io::Write <span class="kw">for </span>BufferedStandardStream {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, b: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.wtr.write(b)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.flush()
}
}
<span class="kw">impl </span>WriteColor <span class="kw">for </span>BufferedStandardStream {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.supports_color()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="kw">if </span><span class="self">self</span>.is_synchronous() {
<span class="self">self</span>.wtr.flush()<span class="question-mark">?</span>;
}
<span class="self">self</span>.wtr.set_color(spec)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.reset()
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.is_synchronous()
}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; io::Write <span class="kw">for </span>WriterInner&lt;W&gt; {
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.write(buf),
WriterInner::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.write(buf),
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { <span class="kw-2">ref mut </span>wtr, .. } =&gt; wtr.write(buf),
}
}
<span class="attribute">#[inline(always)]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.flush(),
WriterInner::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.flush(),
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { <span class="kw-2">ref mut </span>wtr, .. } =&gt; wtr.flush(),
}
}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; WriteColor <span class="kw">for </span>WriterInner&lt;W&gt; {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
WriterInner::Ansi(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { .. } =&gt; <span class="bool-val">true</span>,
}
}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.set_color(spec),
WriterInner::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.set_color(spec),
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { <span class="kw-2">ref mut </span>wtr, <span class="kw-2">ref </span>console } =&gt; {
wtr.flush()<span class="question-mark">?</span>;
<span class="kw">let </span><span class="kw-2">mut </span>console = console.lock().unwrap();
spec.write_console(<span class="kw-2">&amp;mut *</span>console)
}
}
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.reset(),
WriterInner::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.reset(),
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { <span class="kw-2">ref mut </span>wtr, <span class="kw-2">ref mut </span>console } =&gt; {
wtr.flush()<span class="question-mark">?</span>;
console.lock().unwrap().reset()<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(())
}
}
}
<span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInner::NoColor(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
WriterInner::Ansi(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<span class="attribute">#[cfg(windows)]
</span>WriterInner::Windows { .. } =&gt; <span class="bool-val">true</span>,
}
}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>, W: io::Write&gt; io::Write <span class="kw">for </span>WriterInnerLock&lt;<span class="lifetime">&#39;a</span>, W&gt; {
<span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.write(buf),
WriterInnerLock::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.write(buf),
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { <span class="kw-2">ref mut </span>wtr, .. } =&gt; wtr.write(buf),
}
}
<span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.flush(),
WriterInnerLock::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.flush(),
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { <span class="kw-2">ref mut </span>wtr, .. } =&gt; wtr.flush(),
}
}
}
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>, W: io::Write&gt; WriteColor <span class="kw">for </span>WriterInnerLock&lt;<span class="lifetime">&#39;a</span>, W&gt; {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
WriterInnerLock::Ansi(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { .. } =&gt; <span class="bool-val">true</span>,
}
}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.set_color(spec),
WriterInnerLock::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.set_color(spec),
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { <span class="kw-2">ref mut </span>wtr, <span class="kw-2">ref mut </span>console } =&gt; {
wtr.flush()<span class="question-mark">?</span>;
spec.write_console(console)
}
}
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.reset(),
WriterInnerLock::Ansi(<span class="kw-2">ref mut </span>wtr) =&gt; wtr.reset(),
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { <span class="kw-2">ref mut </span>wtr, <span class="kw-2">ref mut </span>console } =&gt; {
wtr.flush()<span class="question-mark">?</span>;
console.reset()<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(())
}
}
}
<span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
WriterInnerLock::Unreachable(<span class="kw">_</span>) =&gt; <span class="macro">unreachable!</span>(),
WriterInnerLock::NoColor(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
WriterInnerLock::Ansi(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
<span class="attribute">#[cfg(windows)]
</span>WriterInnerLock::Windows { .. } =&gt; <span class="bool-val">true</span>,
}
}
}
<span class="doccomment">/// Writes colored buffers to stdout or stderr.
///
/// Writable buffers can be obtained by calling `buffer` on a `BufferWriter`.
///
/// This writer works with terminals that support ANSI escape sequences or
/// with a Windows console.
///
/// It is intended for a `BufferWriter` to be put in an `Arc` and written to
/// from multiple threads simultaneously.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>BufferWriter {
stream: LossyStandardStream&lt;IoStandardStream&gt;,
printed: AtomicBool,
separator: <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt;,
color_choice: ColorChoice,
<span class="attribute">#[cfg(windows)]
</span>console: <span class="prelude-ty">Option</span>&lt;Mutex&lt;wincon::Console&gt;&gt;,
}
<span class="kw">impl </span>BufferWriter {
<span class="doccomment">/// Create a new `BufferWriter` that writes to a standard stream with the
/// given color preferences.
///
/// The specific color/style settings can be configured when writing to
/// the buffers themselves.
</span><span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>create(sty: StandardStreamType, choice: ColorChoice) -&gt; BufferWriter {
BufferWriter {
stream: LossyStandardStream::new(IoStandardStream::new(sty)),
printed: AtomicBool::new(<span class="bool-val">false</span>),
separator: <span class="prelude-val">None</span>,
color_choice: choice,
}
}
<span class="doccomment">/// Create a new `BufferWriter` that writes to a standard stream with the
/// given color preferences.
///
/// If coloring is desired and a Windows console could not be found, then
/// ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing to
/// the buffers themselves.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>create(sty: StandardStreamType, choice: ColorChoice) -&gt; BufferWriter {
<span class="kw">let </span><span class="kw-2">mut </span>con = <span class="kw">match </span>sty {
StandardStreamType::Stdout =&gt; wincon::Console::stdout(),
StandardStreamType::Stderr =&gt; wincon::Console::stderr(),
StandardStreamType::StdoutBuffered =&gt; wincon::Console::stdout(),
StandardStreamType::StderrBuffered =&gt; wincon::Console::stderr(),
}
.ok();
<span class="kw">let </span>is_console_virtual = con
.as_mut()
.map(|con| con.set_virtual_terminal_processing(<span class="bool-val">true</span>).is_ok())
.unwrap_or(<span class="bool-val">false</span>);
<span class="comment">// If we can enable ANSI on Windows, then we don&#39;t need the console
// anymore.
</span><span class="kw">if </span>is_console_virtual {
con = <span class="prelude-val">None</span>;
}
<span class="kw">let </span>stream = LossyStandardStream::new(IoStandardStream::new(sty));
BufferWriter {
stream,
printed: AtomicBool::new(<span class="bool-val">false</span>),
separator: <span class="prelude-val">None</span>,
color_choice: choice,
console: con.map(Mutex::new),
}
}
<span class="doccomment">/// Create a new `BufferWriter` that writes to stdout with the given
/// color preferences.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing to
/// the buffers themselves.
</span><span class="kw">pub fn </span>stdout(choice: ColorChoice) -&gt; BufferWriter {
BufferWriter::create(StandardStreamType::Stdout, choice)
}
<span class="doccomment">/// Create a new `BufferWriter` that writes to stderr with the given
/// color preferences.
///
/// On Windows, if coloring is desired and a Windows console could not be
/// found, then ANSI escape sequences are used instead.
///
/// The specific color/style settings can be configured when writing to
/// the buffers themselves.
</span><span class="kw">pub fn </span>stderr(choice: ColorChoice) -&gt; BufferWriter {
BufferWriter::create(StandardStreamType::Stderr, choice)
}
<span class="doccomment">/// If set, the separator given is printed between buffers. By default, no
/// separator is printed.
///
/// The default value is `None`.
</span><span class="kw">pub fn </span>separator(<span class="kw-2">&amp;mut </span><span class="self">self</span>, sep: <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt;) {
<span class="self">self</span>.separator = sep;
}
<span class="doccomment">/// Creates a new `Buffer` with the current color preferences.
///
/// A `Buffer` satisfies both `io::Write` and `WriteColor`. A `Buffer` can
/// be printed using the `print` method.
</span><span class="attribute">#[cfg(not(windows))]
</span><span class="kw">pub fn </span>buffer(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Buffer {
Buffer::new(<span class="self">self</span>.color_choice)
}
<span class="doccomment">/// Creates a new `Buffer` with the current color preferences.
///
/// A `Buffer` satisfies both `io::Write` and `WriteColor`. A `Buffer` can
/// be printed using the `print` method.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">pub fn </span>buffer(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Buffer {
Buffer::new(<span class="self">self</span>.color_choice, <span class="self">self</span>.console.is_some())
}
<span class="doccomment">/// Prints the contents of the given buffer.
///
/// It is safe to call this from multiple threads simultaneously. In
/// particular, all buffers are written atomically. No interleaving will
/// occur.
</span><span class="kw">pub fn </span>print(<span class="kw-2">&amp;</span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>Buffer) -&gt; io::Result&lt;()&gt; {
<span class="kw">if </span>buf.is_empty() {
<span class="kw">return </span><span class="prelude-val">Ok</span>(());
}
<span class="kw">let </span><span class="kw-2">mut </span>stream = <span class="self">self</span>.stream.wrap(<span class="self">self</span>.stream.get_ref().lock());
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>sep) = <span class="self">self</span>.separator {
<span class="kw">if </span><span class="self">self</span>.printed.load(Ordering::SeqCst) {
stream.write_all(sep)<span class="question-mark">?</span>;
stream.write_all(<span class="string">b&quot;\n&quot;</span>)<span class="question-mark">?</span>;
}
}
<span class="kw">match </span>buf.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref </span>b) =&gt; stream.write_all(<span class="kw-2">&amp;</span>b.<span class="number">0</span>)<span class="question-mark">?</span>,
BufferInner::Ansi(<span class="kw-2">ref </span>b) =&gt; stream.write_all(<span class="kw-2">&amp;</span>b.<span class="number">0</span>)<span class="question-mark">?</span>,
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref </span>b) =&gt; {
<span class="comment">// We guarantee by construction that we have a console here.
// Namely, a BufferWriter is the only way to produce a Buffer.
</span><span class="kw">let </span>console_mutex = <span class="self">self
</span>.console
.as_ref()
.expect(<span class="string">&quot;got Windows buffer but have no Console&quot;</span>);
<span class="kw">let </span><span class="kw-2">mut </span>console = console_mutex.lock().unwrap();
b.print(<span class="kw-2">&amp;mut *</span>console, <span class="kw-2">&amp;mut </span>stream)<span class="question-mark">?</span>;
}
}
<span class="self">self</span>.printed.store(<span class="bool-val">true</span>, Ordering::SeqCst);
<span class="prelude-val">Ok</span>(())
}
}
<span class="doccomment">/// Write colored text to memory.
///
/// `Buffer` is a platform independent abstraction for printing colored text to
/// an in memory buffer. When the buffer is printed using a `BufferWriter`, the
/// color information will be applied to the output device (a tty on Unix and a
/// console on Windows).
///
/// A `Buffer` is typically created by calling the `BufferWriter.buffer`
/// method, which will take color preferences and the environment into
/// account. However, buffers can also be manually created using `no_color`,
/// `ansi` or `console` (on Windows).
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>Buffer(BufferInner);
<span class="doccomment">/// BufferInner is an enumeration of different buffer types.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">enum </span>BufferInner {
<span class="doccomment">/// No coloring information should be applied. This ignores all coloring
/// directives.
</span>NoColor(NoColor&lt;Vec&lt;u8&gt;&gt;),
<span class="doccomment">/// Apply coloring using ANSI escape sequences embedded into the buffer.
</span>Ansi(Ansi&lt;Vec&lt;u8&gt;&gt;),
<span class="doccomment">/// Apply coloring using the Windows console APIs. This buffer saves
/// color information in memory and only interacts with the console when
/// the buffer is printed.
</span><span class="attribute">#[cfg(windows)]
</span>Windows(WindowsBuffer),
}
<span class="kw">impl </span>Buffer {
<span class="doccomment">/// Create a new buffer with the given color settings.
</span><span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>new(choice: ColorChoice) -&gt; Buffer {
<span class="kw">if </span>choice.should_attempt_color() {
Buffer::ansi()
} <span class="kw">else </span>{
Buffer::no_color()
}
}
<span class="doccomment">/// Create a new buffer with the given color settings.
///
/// On Windows, one can elect to create a buffer capable of being written
/// to a console. Only enable it if a console is available.
///
/// If coloring is desired and `console` is false, then ANSI escape
/// sequences are used instead.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>new(choice: ColorChoice, console: bool) -&gt; Buffer {
<span class="kw">if </span>choice.should_attempt_color() {
<span class="kw">if </span>!console || choice.should_ansi() {
Buffer::ansi()
} <span class="kw">else </span>{
Buffer::console()
}
} <span class="kw">else </span>{
Buffer::no_color()
}
}
<span class="doccomment">/// Create a buffer that drops all color information.
</span><span class="kw">pub fn </span>no_color() -&gt; Buffer {
Buffer(BufferInner::NoColor(NoColor(<span class="macro">vec!</span>[])))
}
<span class="doccomment">/// Create a buffer that uses ANSI escape sequences.
</span><span class="kw">pub fn </span>ansi() -&gt; Buffer {
Buffer(BufferInner::Ansi(Ansi(<span class="macro">vec!</span>[])))
}
<span class="doccomment">/// Create a buffer that can be written to a Windows console.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">pub fn </span>console() -&gt; Buffer {
Buffer(BufferInner::Windows(WindowsBuffer::new()))
}
<span class="doccomment">/// Returns true if and only if this buffer is empty.
</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 the length of this buffer in bytes.
</span><span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref </span>b) =&gt; b.<span class="number">0</span>.len(),
BufferInner::Ansi(<span class="kw-2">ref </span>b) =&gt; b.<span class="number">0</span>.len(),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref </span>b) =&gt; b.buf.len(),
}
}
<span class="doccomment">/// Clears this buffer.
</span><span class="kw">pub fn </span>clear(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>b) =&gt; b.<span class="number">0</span>.clear(),
BufferInner::Ansi(<span class="kw-2">ref mut </span>b) =&gt; b.<span class="number">0</span>.clear(),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>b) =&gt; b.clear(),
}
}
<span class="doccomment">/// Consume this buffer and return the underlying raw data.
///
/// On Windows, this unrecoverably drops all color information associated
/// with the buffer.
</span><span class="kw">pub fn </span>into_inner(<span class="self">self</span>) -&gt; Vec&lt;u8&gt; {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(b) =&gt; b.<span class="number">0</span>,
BufferInner::Ansi(b) =&gt; b.<span class="number">0</span>,
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(b) =&gt; b.buf,
}
}
<span class="doccomment">/// Return the underlying data of the buffer.
</span><span class="kw">pub fn </span>as_slice(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[u8] {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref </span>b) =&gt; <span class="kw-2">&amp;</span>b.<span class="number">0</span>,
BufferInner::Ansi(<span class="kw-2">ref </span>b) =&gt; <span class="kw-2">&amp;</span>b.<span class="number">0</span>,
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref </span>b) =&gt; <span class="kw-2">&amp;</span>b.buf,
}
}
<span class="doccomment">/// Return the underlying data of the buffer as a mutable slice.
</span><span class="kw">pub fn </span>as_mut_slice(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>[u8] {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>b) =&gt; <span class="kw-2">&amp;mut </span>b.<span class="number">0</span>,
BufferInner::Ansi(<span class="kw-2">ref mut </span>b) =&gt; <span class="kw-2">&amp;mut </span>b.<span class="number">0</span>,
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>b) =&gt; <span class="kw-2">&amp;mut </span>b.buf,
}
}
}
<span class="kw">impl </span>io::Write <span class="kw">for </span>Buffer {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>w) =&gt; w.write(buf),
BufferInner::Ansi(<span class="kw-2">ref mut </span>w) =&gt; w.write(buf),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>w) =&gt; w.write(buf),
}
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>w) =&gt; w.flush(),
BufferInner::Ansi(<span class="kw-2">ref mut </span>w) =&gt; w.flush(),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>w) =&gt; w.flush(),
}
}
}
<span class="kw">impl </span>WriteColor <span class="kw">for </span>Buffer {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw">_</span>) =&gt; <span class="bool-val">false</span>,
BufferInner::Ansi(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
}
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>w) =&gt; w.set_color(spec),
BufferInner::Ansi(<span class="kw-2">ref mut </span>w) =&gt; w.set_color(spec),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>w) =&gt; w.set_color(spec),
}
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="kw">match </span><span class="self">self</span>.<span class="number">0 </span>{
BufferInner::NoColor(<span class="kw-2">ref mut </span>w) =&gt; w.reset(),
BufferInner::Ansi(<span class="kw-2">ref mut </span>w) =&gt; w.reset(),
<span class="attribute">#[cfg(windows)]
</span>BufferInner::Windows(<span class="kw-2">ref mut </span>w) =&gt; w.reset(),
}
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
}
<span class="doccomment">/// Satisfies `WriteColor` but ignores all color options.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>NoColor&lt;W&gt;(W);
<span class="kw">impl</span>&lt;W: Write&gt; NoColor&lt;W&gt; {
<span class="doccomment">/// Create a new writer that satisfies `WriteColor` but drops all color
/// information.
</span><span class="kw">pub fn </span>new(wtr: W) -&gt; NoColor&lt;W&gt; {
NoColor(wtr)
}
<span class="doccomment">/// Consume this `NoColor` value and return the inner writer.
</span><span class="kw">pub fn </span>into_inner(<span class="self">self</span>) -&gt; W {
<span class="self">self</span>.<span class="number">0
</span>}
<span class="doccomment">/// Return a reference to the inner writer.
</span><span class="kw">pub fn </span>get_ref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>W {
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0
</span>}
<span class="doccomment">/// Return a mutable reference to the inner writer.
</span><span class="kw">pub fn </span>get_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>W {
<span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0
</span>}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; io::Write <span class="kw">for </span>NoColor&lt;W&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.<span class="number">0</span>.write(buf)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.<span class="number">0</span>.flush()
}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; WriteColor <span class="kw">for </span>NoColor&lt;W&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, <span class="kw">_</span>: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
}
<span class="doccomment">/// Satisfies `WriteColor` using standard ANSI escape sequences.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>Ansi&lt;W&gt;(W);
<span class="kw">impl</span>&lt;W: Write&gt; Ansi&lt;W&gt; {
<span class="doccomment">/// Create a new writer that satisfies `WriteColor` using standard ANSI
/// escape sequences.
</span><span class="kw">pub fn </span>new(wtr: W) -&gt; Ansi&lt;W&gt; {
Ansi(wtr)
}
<span class="doccomment">/// Consume this `Ansi` value and return the inner writer.
</span><span class="kw">pub fn </span>into_inner(<span class="self">self</span>) -&gt; W {
<span class="self">self</span>.<span class="number">0
</span>}
<span class="doccomment">/// Return a reference to the inner writer.
</span><span class="kw">pub fn </span>get_ref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>W {
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0
</span>}
<span class="doccomment">/// Return a mutable reference to the inner writer.
</span><span class="kw">pub fn </span>get_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>W {
<span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0
</span>}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; io::Write <span class="kw">for </span>Ansi&lt;W&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.<span class="number">0</span>.write(buf)
}
<span class="comment">// Adding this method here is not required because it has a default impl,
// but it seems to provide a perf improvement in some cases when using
// a `BufWriter` with lots of writes.
//
// See https://github.com/BurntSushi/termcolor/pull/56 for more details
// and a minimized example.
</span><span class="attribute">#[inline]
</span><span class="kw">fn </span>write_all(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.<span class="number">0</span>.write_all(buf)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.<span class="number">0</span>.flush()
}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; WriteColor <span class="kw">for </span>Ansi&lt;W&gt; {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">true
</span>}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="kw">if </span>spec.reset {
<span class="self">self</span>.reset()<span class="question-mark">?</span>;
}
<span class="kw">if </span>spec.bold {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[1m&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if </span>spec.dimmed {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[2m&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if </span>spec.italic {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[3m&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if </span>spec.underline {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[4m&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if </span>spec.strikethrough {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[9m&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>c) = spec.fg_color {
<span class="self">self</span>.write_color(<span class="bool-val">true</span>, c, spec.intense)<span class="question-mark">?</span>;
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>c) = spec.bg_color {
<span class="self">self</span>.write_color(<span class="bool-val">false</span>, c, spec.intense)<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.write_str(<span class="string">&quot;\x1B[0m&quot;</span>)
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; Ansi&lt;W&gt; {
<span class="kw">fn </span>write_str(<span class="kw-2">&amp;mut </span><span class="self">self</span>, s: <span class="kw-2">&amp;</span>str) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.write_all(s.as_bytes())
}
<span class="kw">fn </span>write_color(
<span class="kw-2">&amp;mut </span><span class="self">self</span>,
fg: bool,
c: <span class="kw-2">&amp;</span>Color,
intense: bool,
) -&gt; io::Result&lt;()&gt; {
<span class="macro">macro_rules! </span>write_intense {
(<span class="macro-nonterminal">$clr</span>:expr) =&gt; {
<span class="kw">if </span>fg {
<span class="self">self</span>.write_str(<span class="macro">concat!</span>(<span class="string">&quot;\x1B[38;5;&quot;</span>, <span class="macro-nonterminal">$clr</span>, <span class="string">&quot;m&quot;</span>))
} <span class="kw">else </span>{
<span class="self">self</span>.write_str(<span class="macro">concat!</span>(<span class="string">&quot;\x1B[48;5;&quot;</span>, <span class="macro-nonterminal">$clr</span>, <span class="string">&quot;m&quot;</span>))
}
};
}
<span class="macro">macro_rules! </span>write_normal {
(<span class="macro-nonterminal">$clr</span>:expr) =&gt; {
<span class="kw">if </span>fg {
<span class="self">self</span>.write_str(<span class="macro">concat!</span>(<span class="string">&quot;\x1B[3&quot;</span>, <span class="macro-nonterminal">$clr</span>, <span class="string">&quot;m&quot;</span>))
} <span class="kw">else </span>{
<span class="self">self</span>.write_str(<span class="macro">concat!</span>(<span class="string">&quot;\x1B[4&quot;</span>, <span class="macro-nonterminal">$clr</span>, <span class="string">&quot;m&quot;</span>))
}
};
}
<span class="macro">macro_rules! </span>write_var_ansi_code {
(<span class="macro-nonterminal">$pre</span>:expr, $(<span class="macro-nonterminal">$code</span>:expr),+) =&gt; {{
<span class="comment">// The loop generates at worst a literal of the form
// &#39;255,255,255m&#39; which is 12-bytes.
// The largest `pre` expression we currently use is 7 bytes.
// This gives us the maximum of 19-bytes for our work buffer.
</span><span class="kw">let </span>pre_len = <span class="macro-nonterminal">$pre</span>.len();
<span class="macro">assert!</span>(pre_len &lt;= <span class="number">7</span>);
<span class="kw">let </span><span class="kw-2">mut </span>fmt = [<span class="number">0u8</span>; <span class="number">19</span>];
fmt[..pre_len].copy_from_slice(<span class="macro-nonterminal">$pre</span>);
<span class="kw">let </span><span class="kw-2">mut </span>i = pre_len - <span class="number">1</span>;
$(
<span class="kw">let </span>c1: u8 = (<span class="macro-nonterminal">$code </span>/ <span class="number">100</span>) % <span class="number">10</span>;
<span class="kw">let </span>c2: u8 = (<span class="macro-nonterminal">$code </span>/ <span class="number">10</span>) % <span class="number">10</span>;
<span class="kw">let </span>c3: u8 = <span class="macro-nonterminal">$code </span>% <span class="number">10</span>;
<span class="kw">let </span><span class="kw-2">mut </span>printed = <span class="bool-val">false</span>;
<span class="kw">if </span>c1 != <span class="number">0 </span>{
printed = <span class="bool-val">true</span>;
i += <span class="number">1</span>;
fmt[i] = <span class="string">b&#39;0&#39; </span>+ c1;
}
<span class="kw">if </span>c2 != <span class="number">0 </span>|| printed {
i += <span class="number">1</span>;
fmt[i] = <span class="string">b&#39;0&#39; </span>+ c2;
}
<span class="comment">// If we received a zero value we must still print a value.
</span>i += <span class="number">1</span>;
fmt[i] = <span class="string">b&#39;0&#39; </span>+ c3;
i += <span class="number">1</span>;
fmt[i] = <span class="string">b&#39;;&#39;</span>;
)+
fmt[i] = <span class="string">b&#39;m&#39;</span>;
<span class="self">self</span>.write_all(<span class="kw-2">&amp;</span>fmt[<span class="number">0</span>..i+<span class="number">1</span>])
}}
}
<span class="macro">macro_rules! </span>write_custom {
(<span class="macro-nonterminal">$ansi256</span>:expr) =&gt; {
<span class="kw">if </span>fg {
<span class="macro">write_var_ansi_code!</span>(<span class="string">b&quot;\x1B[38;5;&quot;</span>, <span class="macro-nonterminal">$ansi256</span>)
} <span class="kw">else </span>{
<span class="macro">write_var_ansi_code!</span>(<span class="string">b&quot;\x1B[48;5;&quot;</span>, <span class="macro-nonterminal">$ansi256</span>)
}
};
(<span class="macro-nonterminal">$r</span>:expr, <span class="macro-nonterminal">$g</span>:expr, <span class="macro-nonterminal">$b</span>:expr) =&gt; {{
<span class="kw">if </span>fg {
<span class="macro">write_var_ansi_code!</span>(<span class="string">b&quot;\x1B[38;2;&quot;</span>, <span class="macro-nonterminal">$r</span>, <span class="macro-nonterminal">$g</span>, <span class="macro-nonterminal">$b</span>)
} <span class="kw">else </span>{
<span class="macro">write_var_ansi_code!</span>(<span class="string">b&quot;\x1B[48;2;&quot;</span>, <span class="macro-nonterminal">$r</span>, <span class="macro-nonterminal">$g</span>, <span class="macro-nonterminal">$b</span>)
}
}};
}
<span class="kw">if </span>intense {
<span class="kw">match </span><span class="kw-2">*</span>c {
Color::Black =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;8&quot;</span>),
Color::Blue =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;12&quot;</span>),
Color::Green =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;10&quot;</span>),
Color::Red =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;9&quot;</span>),
Color::Cyan =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;14&quot;</span>),
Color::Magenta =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;13&quot;</span>),
Color::Yellow =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;11&quot;</span>),
Color::White =&gt; <span class="macro">write_intense!</span>(<span class="string">&quot;15&quot;</span>),
Color::Ansi256(c) =&gt; <span class="macro">write_custom!</span>(c),
Color::Rgb(r, g, b) =&gt; <span class="macro">write_custom!</span>(r, g, b),
Color::__Nonexhaustive =&gt; <span class="macro">unreachable!</span>(),
}
} <span class="kw">else </span>{
<span class="kw">match </span><span class="kw-2">*</span>c {
Color::Black =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;0&quot;</span>),
Color::Blue =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;4&quot;</span>),
Color::Green =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;2&quot;</span>),
Color::Red =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;1&quot;</span>),
Color::Cyan =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;6&quot;</span>),
Color::Magenta =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;5&quot;</span>),
Color::Yellow =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;3&quot;</span>),
Color::White =&gt; <span class="macro">write_normal!</span>(<span class="string">&quot;7&quot;</span>),
Color::Ansi256(c) =&gt; <span class="macro">write_custom!</span>(c),
Color::Rgb(r, g, b) =&gt; <span class="macro">write_custom!</span>(r, g, b),
Color::__Nonexhaustive =&gt; <span class="macro">unreachable!</span>(),
}
}
}
}
<span class="kw">impl </span>WriteColor <span class="kw">for </span>io::Sink {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, <span class="kw">_</span>: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="prelude-val">Ok</span>(())
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="prelude-val">Ok</span>(())
}
}
<span class="doccomment">/// An in-memory buffer that provides Windows console coloring.
///
/// This doesn&#39;t actually communicate with the Windows console. Instead, it
/// acts like a normal buffer but also saves the color information associated
/// with positions in the buffer. It is only when the buffer is written to the
/// console that coloring is actually applied.
///
/// This is roughly isomorphic to the ANSI based approach (i.e.,
/// `Ansi&lt;Vec&lt;u8&gt;&gt;`), except with ANSI, the color information is embedded
/// directly into the buffer.
///
/// Note that there is no way to write something generic like
/// `WindowsConsole&lt;W: io::Write&gt;` since coloring on Windows is tied
/// specifically to the console APIs, and therefore can&#39;t work on arbitrary
/// writers.
</span><span class="attribute">#[cfg(windows)]
#[derive(Clone, Debug)]
</span><span class="kw">struct </span>WindowsBuffer {
<span class="doccomment">/// The actual content that should be printed.
</span>buf: Vec&lt;u8&gt;,
<span class="doccomment">/// A sequence of position oriented color specifications. Namely, each
/// element is a position and a color spec, where the color spec should
/// be applied at the position inside of `buf`.
///
/// A missing color spec implies the underlying console should be reset.
</span>colors: Vec&lt;(usize, <span class="prelude-ty">Option</span>&lt;ColorSpec&gt;)&gt;,
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">impl </span>WindowsBuffer {
<span class="doccomment">/// Create a new empty buffer for Windows console coloring.
</span><span class="kw">fn </span>new() -&gt; WindowsBuffer {
WindowsBuffer { buf: <span class="macro">vec!</span>[], colors: <span class="macro">vec!</span>[] }
}
<span class="doccomment">/// Push the given color specification into this buffer.
///
/// This has the effect of setting the given color information at the
/// current position in the buffer.
</span><span class="kw">fn </span>push(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="prelude-ty">Option</span>&lt;ColorSpec&gt;) {
<span class="kw">let </span>pos = <span class="self">self</span>.buf.len();
<span class="self">self</span>.colors.push((pos, spec));
}
<span class="doccomment">/// Print the contents to the given stream handle, and use the console
/// for coloring.
</span><span class="kw">fn </span>print(
<span class="kw-2">&amp;</span><span class="self">self</span>,
console: <span class="kw-2">&amp;mut </span>wincon::Console,
stream: <span class="kw-2">&amp;mut </span>LossyStandardStream&lt;IoStandardStreamLock&gt;,
) -&gt; io::Result&lt;()&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>last = <span class="number">0</span>;
<span class="kw">for </span><span class="kw-2">&amp;</span>(pos, <span class="kw-2">ref </span>spec) <span class="kw">in </span><span class="kw-2">&amp;</span><span class="self">self</span>.colors {
stream.write_all(<span class="kw-2">&amp;</span><span class="self">self</span>.buf[last..pos])<span class="question-mark">?</span>;
stream.flush()<span class="question-mark">?</span>;
last = pos;
<span class="kw">match </span><span class="kw-2">*</span>spec {
<span class="prelude-val">None </span>=&gt; console.reset()<span class="question-mark">?</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref </span>spec) =&gt; spec.write_console(console)<span class="question-mark">?</span>,
}
}
stream.write_all(<span class="kw-2">&amp;</span><span class="self">self</span>.buf[last..])<span class="question-mark">?</span>;
stream.flush()
}
<span class="doccomment">/// Clear the buffer.
</span><span class="kw">fn </span>clear(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.buf.clear();
<span class="self">self</span>.colors.clear();
}
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">impl </span>io::Write <span class="kw">for </span>WindowsBuffer {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.buf.extend_from_slice(buf);
<span class="prelude-val">Ok</span>(buf.len())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="prelude-val">Ok</span>(())
}
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">impl </span>WriteColor <span class="kw">for </span>WindowsBuffer {
<span class="attribute">#[inline]
</span><span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">true
</span>}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.push(<span class="prelude-val">Some</span>(spec.clone()));
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.push(<span class="prelude-val">None</span>);
<span class="prelude-val">Ok</span>(())
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="bool-val">false
</span>}
}
<span class="doccomment">/// A color specification.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>ColorSpec {
fg_color: <span class="prelude-ty">Option</span>&lt;Color&gt;,
bg_color: <span class="prelude-ty">Option</span>&lt;Color&gt;,
bold: bool,
intense: bool,
underline: bool,
dimmed: bool,
italic: bool,
reset: bool,
strikethrough: bool,
}
<span class="kw">impl </span>Default <span class="kw">for </span>ColorSpec {
<span class="kw">fn </span>default() -&gt; ColorSpec {
ColorSpec {
fg_color: <span class="prelude-val">None</span>,
bg_color: <span class="prelude-val">None</span>,
bold: <span class="bool-val">false</span>,
intense: <span class="bool-val">false</span>,
underline: <span class="bool-val">false</span>,
dimmed: <span class="bool-val">false</span>,
italic: <span class="bool-val">false</span>,
reset: <span class="bool-val">true</span>,
strikethrough: <span class="bool-val">false</span>,
}
}
}
<span class="kw">impl </span>ColorSpec {
<span class="doccomment">/// Create a new color specification that has no colors or styles.
</span><span class="kw">pub fn </span>new() -&gt; ColorSpec {
ColorSpec::default()
}
<span class="doccomment">/// Get the foreground color.
</span><span class="kw">pub fn </span>fg(<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>Color&gt; {
<span class="self">self</span>.fg_color.as_ref()
}
<span class="doccomment">/// Set the foreground color.
</span><span class="kw">pub fn </span>set_fg(<span class="kw-2">&amp;mut </span><span class="self">self</span>, color: <span class="prelude-ty">Option</span>&lt;Color&gt;) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.fg_color = color;
<span class="self">self
</span>}
<span class="doccomment">/// Get the background color.
</span><span class="kw">pub fn </span>bg(<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>Color&gt; {
<span class="self">self</span>.bg_color.as_ref()
}
<span class="doccomment">/// Set the background color.
</span><span class="kw">pub fn </span>set_bg(<span class="kw-2">&amp;mut </span><span class="self">self</span>, color: <span class="prelude-ty">Option</span>&lt;Color&gt;) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.bg_color = color;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is bold or not.
///
/// Note that the bold setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>bold(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.bold
}
<span class="doccomment">/// Set whether the text is bolded or not.
///
/// Note that the bold setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_bold(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.bold = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is dimmed or not.
///
/// Note that the dimmed setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>dimmed(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.dimmed
}
<span class="doccomment">/// Set whether the text is dimmed or not.
///
/// Note that the dimmed setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_dimmed(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.dimmed = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is italic or not.
///
/// Note that the italic setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>italic(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.italic
}
<span class="doccomment">/// Set whether the text is italicized or not.
///
/// Note that the italic setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_italic(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.italic = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is underline or not.
///
/// Note that the underline setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>underline(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.underline
}
<span class="doccomment">/// Set whether the text is underlined or not.
///
/// Note that the underline setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_underline(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.underline = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is strikethrough or not.
///
/// Note that the strikethrough setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>strikethrough(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.strikethrough
}
<span class="doccomment">/// Set whether the text is strikethrough or not.
///
/// Note that the strikethrough setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_strikethrough(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.strikethrough = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether reset is enabled or not.
///
/// reset is enabled by default. When disabled and using ANSI escape
/// sequences, a &quot;reset&quot; code will be emitted every time a `ColorSpec`&#39;s
/// settings are applied.
///
/// Note that the reset setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>reset(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.reset
}
<span class="doccomment">/// Set whether to reset the terminal whenever color settings are applied.
///
/// reset is enabled by default. When disabled and using ANSI escape
/// sequences, a &quot;reset&quot; code will be emitted every time a `ColorSpec`&#39;s
/// settings are applied.
///
/// Typically this is useful if callers have a requirement to more
/// scrupulously manage the exact sequence of escape codes that are emitted
/// when using ANSI for colors.
///
/// Note that the reset setting has no effect in a Windows console.
</span><span class="kw">pub fn </span>set_reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.reset = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Get whether this is intense or not.
///
/// On Unix-like systems, this will output the ANSI escape sequence
/// that will print a high-intensity version of the color
/// specified.
///
/// On Windows systems, this will output the ANSI escape sequence
/// that will print a brighter version of the color specified.
</span><span class="kw">pub fn </span>intense(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.intense
}
<span class="doccomment">/// Set whether the text is intense or not.
///
/// On Unix-like systems, this will output the ANSI escape sequence
/// that will print a high-intensity version of the color
/// specified.
///
/// On Windows systems, this will output the ANSI escape sequence
/// that will print a brighter version of the color specified.
</span><span class="kw">pub fn </span>set_intense(<span class="kw-2">&amp;mut </span><span class="self">self</span>, yes: bool) -&gt; <span class="kw-2">&amp;mut </span>ColorSpec {
<span class="self">self</span>.intense = yes;
<span class="self">self
</span>}
<span class="doccomment">/// Returns true if this color specification has no colors or styles.
</span><span class="kw">pub fn </span>is_none(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.fg_color.is_none()
&amp;&amp; <span class="self">self</span>.bg_color.is_none()
&amp;&amp; !<span class="self">self</span>.bold
&amp;&amp; !<span class="self">self</span>.underline
&amp;&amp; !<span class="self">self</span>.dimmed
&amp;&amp; !<span class="self">self</span>.italic
&amp;&amp; !<span class="self">self</span>.intense
&amp;&amp; !<span class="self">self</span>.strikethrough
}
<span class="doccomment">/// Clears this color specification so that it has no color/style settings.
</span><span class="kw">pub fn </span>clear(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.fg_color = <span class="prelude-val">None</span>;
<span class="self">self</span>.bg_color = <span class="prelude-val">None</span>;
<span class="self">self</span>.bold = <span class="bool-val">false</span>;
<span class="self">self</span>.underline = <span class="bool-val">false</span>;
<span class="self">self</span>.intense = <span class="bool-val">false</span>;
<span class="self">self</span>.dimmed = <span class="bool-val">false</span>;
<span class="self">self</span>.italic = <span class="bool-val">false</span>;
<span class="self">self</span>.strikethrough = <span class="bool-val">false</span>;
}
<span class="doccomment">/// Writes this color spec to the given Windows console.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>write_console(<span class="kw-2">&amp;</span><span class="self">self</span>, console: <span class="kw-2">&amp;mut </span>wincon::Console) -&gt; io::Result&lt;()&gt; {
<span class="kw">let </span>fg_color = <span class="self">self</span>.fg_color.and_then(|c| c.to_windows(<span class="self">self</span>.intense));
<span class="kw">if let </span><span class="prelude-val">Some</span>((intense, color)) = fg_color {
console.fg(intense, color)<span class="question-mark">?</span>;
}
<span class="kw">let </span>bg_color = <span class="self">self</span>.bg_color.and_then(|c| c.to_windows(<span class="self">self</span>.intense));
<span class="kw">if let </span><span class="prelude-val">Some</span>((intense, color)) = bg_color {
console.bg(intense, color)<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="doccomment">/// The set of available colors for the terminal foreground/background.
///
/// The `Ansi256` and `Rgb` colors will only output the correct codes when
/// paired with the `Ansi` `WriteColor` implementation.
///
/// The `Ansi256` and `Rgb` color types are not supported when writing colors
/// on Windows using the console. If they are used on Windows, then they are
/// silently ignored and no colors will be emitted.
///
/// This set may expand over time.
///
/// This type has a `FromStr` impl that can parse colors from their human
/// readable form. The format is as follows:
///
/// 1. Any of the explicitly listed colors in English. They are matched
/// case insensitively.
/// 2. A single 8-bit integer, in either decimal or hexadecimal format.
/// 3. A triple of 8-bit integers separated by a comma, where each integer is
/// in decimal or hexadecimal format.
///
/// Hexadecimal numbers are written with a `0x` prefix.
</span><span class="attribute">#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>Color {
Black,
Blue,
Green,
Red,
Cyan,
Magenta,
Yellow,
White,
Ansi256(u8),
Rgb(u8, u8, u8),
<span class="attribute">#[doc(hidden)]
</span>__Nonexhaustive,
}
<span class="kw">impl </span>Color {
<span class="doccomment">/// Translate this color to a wincon::Color.
</span><span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>to_windows(
<span class="self">self</span>,
intense: bool,
) -&gt; <span class="prelude-ty">Option</span>&lt;(wincon::Intense, wincon::Color)&gt; {
<span class="kw">use </span>wincon::Intense::{No, Yes};
<span class="kw">let </span>color = <span class="kw">match </span><span class="self">self </span>{
Color::Black =&gt; wincon::Color::Black,
Color::Blue =&gt; wincon::Color::Blue,
Color::Green =&gt; wincon::Color::Green,
Color::Red =&gt; wincon::Color::Red,
Color::Cyan =&gt; wincon::Color::Cyan,
Color::Magenta =&gt; wincon::Color::Magenta,
Color::Yellow =&gt; wincon::Color::Yellow,
Color::White =&gt; wincon::Color::White,
Color::Ansi256(<span class="number">0</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Black)),
Color::Ansi256(<span class="number">1</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Red)),
Color::Ansi256(<span class="number">2</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Green)),
Color::Ansi256(<span class="number">3</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Yellow)),
Color::Ansi256(<span class="number">4</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Blue)),
Color::Ansi256(<span class="number">5</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Magenta)),
Color::Ansi256(<span class="number">6</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::Cyan)),
Color::Ansi256(<span class="number">7</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((No, wincon::Color::White)),
Color::Ansi256(<span class="number">8</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Black)),
Color::Ansi256(<span class="number">9</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Red)),
Color::Ansi256(<span class="number">10</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Green)),
Color::Ansi256(<span class="number">11</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Yellow)),
Color::Ansi256(<span class="number">12</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Blue)),
Color::Ansi256(<span class="number">13</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Magenta)),
Color::Ansi256(<span class="number">14</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::Cyan)),
Color::Ansi256(<span class="number">15</span>) =&gt; <span class="kw">return </span><span class="prelude-val">Some</span>((Yes, wincon::Color::White)),
Color::Ansi256(<span class="kw">_</span>) =&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
Color::Rgb(<span class="kw">_</span>, <span class="kw">_</span>, <span class="kw">_</span>) =&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
Color::__Nonexhaustive =&gt; <span class="macro">unreachable!</span>(),
};
<span class="kw">let </span>intense = <span class="kw">if </span>intense { Yes } <span class="kw">else </span>{ No };
<span class="prelude-val">Some</span>((intense, color))
}
<span class="doccomment">/// Parses a numeric color string, either ANSI or RGB.
</span><span class="kw">fn </span>from_str_numeric(s: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;Color, ParseColorError&gt; {
<span class="comment">// The &quot;ansi256&quot; format is a single number (decimal or hex)
// corresponding to one of 256 colors.
//
// The &quot;rgb&quot; format is a triple of numbers (decimal or hex) delimited
// by a comma corresponding to one of 256^3 colors.
</span><span class="kw">fn </span>parse_number(s: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Option</span>&lt;u8&gt; {
<span class="kw">use </span>std::u8;
<span class="kw">if </span>s.starts_with(<span class="string">&quot;0x&quot;</span>) {
u8::from_str_radix(<span class="kw-2">&amp;</span>s[<span class="number">2</span>..], <span class="number">16</span>).ok()
} <span class="kw">else </span>{
u8::from_str_radix(s, <span class="number">10</span>).ok()
}
}
<span class="kw">let </span>codes: Vec&lt;<span class="kw-2">&amp;</span>str&gt; = s.split(<span class="string">&#39;,&#39;</span>).collect();
<span class="kw">if </span>codes.len() == <span class="number">1 </span>{
<span class="kw">if let </span><span class="prelude-val">Some</span>(n) = parse_number(<span class="kw-2">&amp;</span>codes[<span class="number">0</span>]) {
<span class="prelude-val">Ok</span>(Color::Ansi256(n))
} <span class="kw">else </span>{
<span class="kw">if </span>s.chars().all(|c| c.is_digit(<span class="number">16</span>)) {
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidAnsi256,
given: s.to_string(),
})
} <span class="kw">else </span>{
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidName,
given: s.to_string(),
})
}
}
} <span class="kw">else if </span>codes.len() == <span class="number">3 </span>{
<span class="kw">let </span><span class="kw-2">mut </span>v = <span class="macro">vec!</span>[];
<span class="kw">for </span>code <span class="kw">in </span>codes {
<span class="kw">let </span>n = parse_number(code).ok_or_else(|| ParseColorError {
kind: ParseColorErrorKind::InvalidRgb,
given: s.to_string(),
})<span class="question-mark">?</span>;
v.push(n);
}
<span class="prelude-val">Ok</span>(Color::Rgb(v[<span class="number">0</span>], v[<span class="number">1</span>], v[<span class="number">2</span>]))
} <span class="kw">else </span>{
<span class="prelude-val">Err</span>(<span class="kw">if </span>s.contains(<span class="string">&quot;,&quot;</span>) {
ParseColorError {
kind: ParseColorErrorKind::InvalidRgb,
given: s.to_string(),
}
} <span class="kw">else </span>{
ParseColorError {
kind: ParseColorErrorKind::InvalidName,
given: s.to_string(),
}
})
}
}
}
<span class="doccomment">/// An error from parsing an invalid color specification.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>ParseColorError {
kind: ParseColorErrorKind,
given: String,
}
<span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">enum </span>ParseColorErrorKind {
InvalidName,
InvalidAnsi256,
InvalidRgb,
}
<span class="kw">impl </span>ParseColorError {
<span class="doccomment">/// Return the string that couldn&#39;t be parsed as a valid color.
</span><span class="kw">pub fn </span>invalid(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>str {
<span class="kw-2">&amp;</span><span class="self">self</span>.given
}
}
<span class="kw">impl </span>error::Error <span class="kw">for </span>ParseColorError {
<span class="kw">fn </span>description(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>str {
<span class="kw">use </span><span class="self">self</span>::ParseColorErrorKind::<span class="kw-2">*</span>;
<span class="kw">match </span><span class="self">self</span>.kind {
InvalidName =&gt; <span class="string">&quot;unrecognized color name&quot;</span>,
InvalidAnsi256 =&gt; <span class="string">&quot;invalid ansi256 color number&quot;</span>,
InvalidRgb =&gt; <span class="string">&quot;invalid RGB color triple&quot;</span>,
}
}
}
<span class="kw">impl </span>fmt::Display <span class="kw">for </span>ParseColorError {
<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>fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; fmt::Result {
<span class="kw">use </span><span class="self">self</span>::ParseColorErrorKind::<span class="kw-2">*</span>;
<span class="kw">match </span><span class="self">self</span>.kind {
InvalidName =&gt; <span class="macro">write!</span>(
f,
<span class="string">&quot;unrecognized color name &#39;{}&#39;. Choose from: \
black, blue, green, red, cyan, magenta, yellow, \
white&quot;</span>,
<span class="self">self</span>.given
),
InvalidAnsi256 =&gt; <span class="macro">write!</span>(
f,
<span class="string">&quot;unrecognized ansi256 color number, \
should be &#39;[0-255]&#39; (or a hex number), but is &#39;{}&#39;&quot;</span>,
<span class="self">self</span>.given
),
InvalidRgb =&gt; <span class="macro">write!</span>(
f,
<span class="string">&quot;unrecognized RGB color triple, \
should be &#39;[0-255],[0-255],[0-255]&#39; (or a hex \
triple), but is &#39;{}&#39;&quot;</span>,
<span class="self">self</span>.given
),
}
}
}
<span class="kw">impl </span>FromStr <span class="kw">for </span>Color {
<span class="kw">type </span><span class="prelude-val">Err </span>= ParseColorError;
<span class="kw">fn </span>from_str(s: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;Color, ParseColorError&gt; {
<span class="kw">match </span><span class="kw-2">&amp;*</span>s.to_lowercase() {
<span class="string">&quot;black&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Black),
<span class="string">&quot;blue&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Blue),
<span class="string">&quot;green&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Green),
<span class="string">&quot;red&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Red),
<span class="string">&quot;cyan&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Cyan),
<span class="string">&quot;magenta&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Magenta),
<span class="string">&quot;yellow&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::Yellow),
<span class="string">&quot;white&quot; </span>=&gt; <span class="prelude-val">Ok</span>(Color::White),
<span class="kw">_ </span>=&gt; Color::from_str_numeric(s),
}
}
}
<span class="attribute">#[derive(Debug)]
</span><span class="kw">struct </span>LossyStandardStream&lt;W&gt; {
wtr: W,
<span class="attribute">#[cfg(windows)]
</span>is_console: bool,
}
<span class="kw">impl</span>&lt;W: io::Write&gt; LossyStandardStream&lt;W&gt; {
<span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>new(wtr: W) -&gt; LossyStandardStream&lt;W&gt; {
LossyStandardStream { wtr }
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>new(wtr: W) -&gt; LossyStandardStream&lt;W&gt; {
<span class="kw">let </span>is_console = wincon::Console::stdout().is_ok()
|| wincon::Console::stderr().is_ok();
LossyStandardStream { wtr, is_console }
}
<span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>wrap&lt;Q: io::Write&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, wtr: Q) -&gt; LossyStandardStream&lt;Q&gt; {
LossyStandardStream::new(wtr)
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>wrap&lt;Q: io::Write&gt;(<span class="kw-2">&amp;</span><span class="self">self</span>, wtr: Q) -&gt; LossyStandardStream&lt;Q&gt; {
LossyStandardStream { wtr, is_console: <span class="self">self</span>.is_console }
}
<span class="kw">fn </span>get_ref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>W {
<span class="kw-2">&amp;</span><span class="self">self</span>.wtr
}
}
<span class="kw">impl</span>&lt;W: WriteColor&gt; WriteColor <span class="kw">for </span>LossyStandardStream&lt;W&gt; {
<span class="kw">fn </span>supports_color(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.supports_color()
}
<span class="kw">fn </span>set_color(<span class="kw-2">&amp;mut </span><span class="self">self</span>, spec: <span class="kw-2">&amp;</span>ColorSpec) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.set_color(spec)
}
<span class="kw">fn </span>reset(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.reset()
}
<span class="kw">fn </span>is_synchronous(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.wtr.is_synchronous()
}
}
<span class="kw">impl</span>&lt;W: io::Write&gt; io::Write <span class="kw">for </span>LossyStandardStream&lt;W&gt; {
<span class="attribute">#[cfg(not(windows))]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="self">self</span>.wtr.write(buf)
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">if </span><span class="self">self</span>.is_console {
write_lossy_utf8(<span class="kw-2">&amp;mut </span><span class="self">self</span>.wtr, buf)
} <span class="kw">else </span>{
<span class="self">self</span>.wtr.write(buf)
}
}
<span class="kw">fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; io::Result&lt;()&gt; {
<span class="self">self</span>.wtr.flush()
}
}
<span class="attribute">#[cfg(windows)]
</span><span class="kw">fn </span>write_lossy_utf8&lt;W: io::Write&gt;(<span class="kw-2">mut </span>w: W, buf: <span class="kw-2">&amp;</span>[u8]) -&gt; io::Result&lt;usize&gt; {
<span class="kw">match </span>::std::str::from_utf8(buf) {
<span class="prelude-val">Ok</span>(s) =&gt; w.write(s.as_bytes()),
<span class="prelude-val">Err</span>(<span class="kw-2">ref </span>e) <span class="kw">if </span>e.valid_up_to() == <span class="number">0 </span>=&gt; {
w.write(<span class="string">b&quot;\xEF\xBF\xBD&quot;</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="number">1</span>)
}
<span class="prelude-val">Err</span>(e) =&gt; w.write(<span class="kw-2">&amp;</span>buf[..e.valid_up_to()]),
}
}
<span class="attribute">#[cfg(test)]
</span><span class="kw">mod </span>tests {
<span class="kw">use super</span>::{
Ansi, Color, ColorSpec, ParseColorError, ParseColorErrorKind,
StandardStream, WriteColor,
};
<span class="kw">fn </span>assert_is_send&lt;T: Send&gt;() {}
<span class="attribute">#[test]
</span><span class="kw">fn </span>standard_stream_is_send() {
assert_is_send::&lt;StandardStream&gt;();
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_simple_parse_ok() {
<span class="kw">let </span>color = <span class="string">&quot;green&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Green));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_256_parse_ok() {
<span class="kw">let </span>color = <span class="string">&quot;7&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Ansi256(<span class="number">7</span>)));
<span class="kw">let </span>color = <span class="string">&quot;32&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Ansi256(<span class="number">32</span>)));
<span class="kw">let </span>color = <span class="string">&quot;0xFF&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Ansi256(<span class="number">0xFF</span>)));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_256_parse_err_out_of_range() {
<span class="kw">let </span>color = <span class="string">&quot;256&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(
color,
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidAnsi256,
given: <span class="string">&quot;256&quot;</span>.to_string(),
})
);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_rgb_parse_ok() {
<span class="kw">let </span>color = <span class="string">&quot;0,0,0&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Rgb(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>)));
<span class="kw">let </span>color = <span class="string">&quot;0,128,255&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Rgb(<span class="number">0</span>, <span class="number">128</span>, <span class="number">255</span>)));
<span class="kw">let </span>color = <span class="string">&quot;0x0,0x0,0x0&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Rgb(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>)));
<span class="kw">let </span>color = <span class="string">&quot;0x33,0x66,0xFF&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(color, <span class="prelude-val">Ok</span>(Color::Rgb(<span class="number">0x33</span>, <span class="number">0x66</span>, <span class="number">0xFF</span>)));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_rgb_parse_err_out_of_range() {
<span class="kw">let </span>color = <span class="string">&quot;0,0,256&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(
color,
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidRgb,
given: <span class="string">&quot;0,0,256&quot;</span>.to_string(),
})
);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_rgb_parse_err_bad_format() {
<span class="kw">let </span>color = <span class="string">&quot;0,0&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(
color,
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidRgb,
given: <span class="string">&quot;0,0&quot;</span>.to_string(),
})
);
<span class="kw">let </span>color = <span class="string">&quot;not_a_color&quot;</span>.parse::&lt;Color&gt;();
<span class="macro">assert_eq!</span>(
color,
<span class="prelude-val">Err</span>(ParseColorError {
kind: ParseColorErrorKind::InvalidName,
given: <span class="string">&quot;not_a_color&quot;</span>.to_string(),
})
);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_var_ansi_write_rgb() {
<span class="kw">let </span><span class="kw-2">mut </span>buf = Ansi::new(<span class="macro">vec!</span>[]);
<span class="kw">let _ </span>= buf.write_color(<span class="bool-val">true</span>, <span class="kw-2">&amp;</span>Color::Rgb(<span class="number">254</span>, <span class="number">253</span>, <span class="number">255</span>), <span class="bool-val">false</span>);
<span class="macro">assert_eq!</span>(buf.<span class="number">0</span>, <span class="string">b&quot;\x1B[38;2;254;253;255m&quot;</span>);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_reset() {
<span class="kw">let </span>spec = ColorSpec::new();
<span class="kw">let </span><span class="kw-2">mut </span>buf = Ansi::new(<span class="macro">vec!</span>[]);
buf.set_color(<span class="kw-2">&amp;</span>spec).unwrap();
<span class="macro">assert_eq!</span>(buf.<span class="number">0</span>, <span class="string">b&quot;\x1B[0m&quot;</span>);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_no_reset() {
<span class="kw">let </span><span class="kw-2">mut </span>spec = ColorSpec::new();
spec.set_reset(<span class="bool-val">false</span>);
<span class="kw">let </span><span class="kw-2">mut </span>buf = Ansi::new(<span class="macro">vec!</span>[]);
buf.set_color(<span class="kw-2">&amp;</span>spec).unwrap();
<span class="macro">assert_eq!</span>(buf.<span class="number">0</span>, <span class="string">b&quot;&quot;</span>);
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_var_ansi_write_256() {
<span class="kw">let </span><span class="kw-2">mut </span>buf = Ansi::new(<span class="macro">vec!</span>[]);
<span class="kw">let _ </span>= buf.write_color(<span class="bool-val">false</span>, <span class="kw-2">&amp;</span>Color::Ansi256(<span class="number">7</span>), <span class="bool-val">false</span>);
<span class="macro">assert_eq!</span>(buf.<span class="number">0</span>, <span class="string">b&quot;\x1B[48;5;7m&quot;</span>);
<span class="kw">let </span><span class="kw-2">mut </span>buf = Ansi::new(<span class="macro">vec!</span>[]);
<span class="kw">let _ </span>= buf.write_color(<span class="bool-val">false</span>, <span class="kw-2">&amp;</span>Color::Ansi256(<span class="number">208</span>), <span class="bool-val">false</span>);
<span class="macro">assert_eq!</span>(buf.<span class="number">0</span>, <span class="string">b&quot;\x1B[48;5;208m&quot;</span>);
}
<span class="kw">fn </span>all_attributes() -&gt; Vec&lt;ColorSpec&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>result = <span class="macro">vec!</span>[];
<span class="kw">for </span>fg <span class="kw">in </span><span class="macro">vec!</span>[<span class="prelude-val">None</span>, <span class="prelude-val">Some</span>(Color::Red)] {
<span class="kw">for </span>bg <span class="kw">in </span><span class="macro">vec!</span>[<span class="prelude-val">None</span>, <span class="prelude-val">Some</span>(Color::Red)] {
<span class="kw">for </span>bold <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">for </span>underline <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">for </span>intense <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">for </span>italic <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">for </span>strikethrough <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">for </span>dimmed <span class="kw">in </span><span class="macro">vec!</span>[<span class="bool-val">false</span>, <span class="bool-val">true</span>] {
<span class="kw">let </span><span class="kw-2">mut </span>color = ColorSpec::new();
color.set_fg(fg);
color.set_bg(bg);
color.set_bold(bold);
color.set_underline(underline);
color.set_intense(intense);
color.set_italic(italic);
color.set_dimmed(dimmed);
color.set_strikethrough(strikethrough);
result.push(color);
}
}
}
}
}
}
}
}
result
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_is_none() {
<span class="kw">for </span>(i, color) <span class="kw">in </span>all_attributes().iter().enumerate() {
<span class="macro">assert_eq!</span>(
i == <span class="number">0</span>,
color.is_none(),
<span class="string">&quot;{:?} =&gt; {}&quot;</span>,
color,
color.is_none()
)
}
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>test_clear() {
<span class="kw">for </span>color <span class="kw">in </span>all_attributes() {
<span class="kw">let </span><span class="kw-2">mut </span>color1 = color.clone();
color1.clear();
<span class="macro">assert!</span>(color1.is_none(), <span class="string">&quot;{:?} =&gt; {:?}&quot;</span>, color, color1);
}
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="termcolor" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>