trash_parallelism 0.1.102

Azzybana Raccoon's comprehensive parallelism library.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
<!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 `src\io\writers.rs`."><title>writers.rs - source</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-ca0dd0c4.css"><script id="default-settings" 
data-use_system_theme="false"
data-theme="trash"></script><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="trash_utilities" data-themes="trash" data-resource-suffix="" data-rustdoc-version="1.92.0-nightly (b925a865e 2025-10-09)" data-channel="nightly" data-search-js="search-8d3311b9.js" data-stringdex-js="stringdex-828709d0.js" data-settings-js="settings-c38705f0.js" ><script src="../../../static.files/storage-e2aeef58.js"></script><script defer src="../../../static.files/src-script-813739b1.js"></script><script defer src="../../../src-files.js"></script><script defer src="../../../static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="src-sidebar-title"><h2>Files</h2></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><section id="main-content" class="content"><div class="main-heading"><h1><div class="sub-heading">trash_utilities\io/</div>writers.rs</h1><rustdoc-toolbar></rustdoc-toolbar></div><div class="example-wrap digits-3"><pre class="rust"><code><a href=#1 id=1 data-nosnippet>1</a><span class="doccomment">//! Async file writers with buffering and compression.
<a href=#2 id=2 data-nosnippet>2</a>//!
<a href=#3 id=3 data-nosnippet>3</a>//! This module provides ergonomic async writers for various output destinations,
<a href=#4 id=4 data-nosnippet>4</a>//! with built-in buffering, compression, and serialization support.
<a href=#5 id=5 data-nosnippet>5</a>//!
<a href=#6 id=6 data-nosnippet>6</a>//! ## Features
<a href=#7 id=7 data-nosnippet>7</a>//!
<a href=#8 id=8 data-nosnippet>8</a>//! - **Buffered Writing**: Automatic buffering with configurable flush triggers
<a href=#9 id=9 data-nosnippet>9</a>//! - **Compression**: Integrated Brotli/gzip compression for file writers
<a href=#10 id=10 data-nosnippet>10</a>//! - **Serialization**: JSON/binary serialization using serde utilities
<a href=#11 id=11 data-nosnippet>11</a>//! - **Async Operations**: Non-blocking writes using smol and futures-lite
<a href=#12 id=12 data-nosnippet>12</a>//! - **Progress Tracking**: Optional progress callbacks and statistics
<a href=#13 id=13 data-nosnippet>13</a>
<a href=#14 id=14 data-nosnippet>14</a></span><span class="comment">// Standard library imports
<a href=#15 id=15 data-nosnippet>15</a>// (none needed)
<a href=#16 id=16 data-nosnippet>16</a>
<a href=#17 id=17 data-nosnippet>17</a>// External crate imports
<a href=#18 id=18 data-nosnippet>18</a></span><span class="kw">use </span>bytes::Bytes;
<a href=#19 id=19 data-nosnippet>19</a><span class="kw">use </span>futures_lite::{AsyncWriteExt, StreamExt};
<a href=#20 id=20 data-nosnippet>20</a>
<a href=#21 id=21 data-nosnippet>21</a><span class="doccomment">/// Async buffered file writer with compression support
<a href=#22 id=22 data-nosnippet>22</a>///
<a href=#23 id=23 data-nosnippet>23</a>/// Provides buffered writing with automatic flushing, optional compression,
<a href=#24 id=24 data-nosnippet>24</a>/// and progress tracking. Uses smol for async I/O operations.
<a href=#25 id=25 data-nosnippet>25</a></span><span class="attr">#[derive(Debug)]
<a href=#26 id=26 data-nosnippet>26</a></span><span class="kw">pub struct </span>AsyncFileWriter {
<a href=#27 id=27 data-nosnippet>27</a>    file: smol::fs::File,
<a href=#28 id=28 data-nosnippet>28</a>    buffer: Vec&lt;u8&gt;,
<a href=#29 id=29 data-nosnippet>29</a>    buffer_size: usize,
<a href=#30 id=30 data-nosnippet>30</a>    compressed: bool,
<a href=#31 id=31 data-nosnippet>31</a>    bytes_written: u64,
<a href=#32 id=32 data-nosnippet>32</a>}
<a href=#33 id=33 data-nosnippet>33</a>
<a href=#34 id=34 data-nosnippet>34</a><span class="kw">impl </span>AsyncFileWriter {
<a href=#35 id=35 data-nosnippet>35</a>    <span class="doccomment">/// Create a new async file writer with default settings
<a href=#36 id=36 data-nosnippet>36</a>    ///
<a href=#37 id=37 data-nosnippet>37</a>    /// # Parameters
<a href=#38 id=38 data-nosnippet>38</a>    /// - `path`: Path to the file to write
<a href=#39 id=39 data-nosnippet>39</a>    ///
<a href=#40 id=40 data-nosnippet>40</a>    /// # Returns
<a href=#41 id=41 data-nosnippet>41</a>    /// New `AsyncFileWriter` instance
<a href=#42 id=42 data-nosnippet>42</a>    ///
<a href=#43 id=43 data-nosnippet>43</a>    /// # Errors
<a href=#44 id=44 data-nosnippet>44</a>    /// Returns error if file cannot be created
<a href=#45 id=45 data-nosnippet>45</a>    </span><span class="kw">pub async fn </span>new(path: <span class="kw-2">&amp;</span>str) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, std::io::Error&gt; {
<a href=#46 id=46 data-nosnippet>46</a>        <span class="self">Self</span>::with_config(path, <span class="number">8192</span>, <span class="bool-val">false</span>).<span class="kw">await
<a href=#47 id=47 data-nosnippet>47</a>    </span>}
<a href=#48 id=48 data-nosnippet>48</a>
<a href=#49 id=49 data-nosnippet>49</a>    <span class="doccomment">/// Create a new async file writer with custom configuration
<a href=#50 id=50 data-nosnippet>50</a>    ///
<a href=#51 id=51 data-nosnippet>51</a>    /// # Parameters
<a href=#52 id=52 data-nosnippet>52</a>    /// - `path`: Path to the file to write
<a href=#53 id=53 data-nosnippet>53</a>    /// - `buffer_size`: Size of the write buffer in bytes
<a href=#54 id=54 data-nosnippet>54</a>    /// - `compressed`: Whether to compress data using Brotli
<a href=#55 id=55 data-nosnippet>55</a>    ///
<a href=#56 id=56 data-nosnippet>56</a>    /// # Returns
<a href=#57 id=57 data-nosnippet>57</a>    /// Configured `AsyncFileWriter` instance
<a href=#58 id=58 data-nosnippet>58</a>    ///
<a href=#59 id=59 data-nosnippet>59</a>    /// # Errors
<a href=#60 id=60 data-nosnippet>60</a>    /// Returns error if file cannot be created
<a href=#61 id=61 data-nosnippet>61</a>    </span><span class="kw">pub async fn </span>with_config(
<a href=#62 id=62 data-nosnippet>62</a>        path: <span class="kw-2">&amp;</span>str,
<a href=#63 id=63 data-nosnippet>63</a>        buffer_size: usize,
<a href=#64 id=64 data-nosnippet>64</a>        compressed: bool,
<a href=#65 id=65 data-nosnippet>65</a>    ) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, std::io::Error&gt; {
<a href=#66 id=66 data-nosnippet>66</a>        <span class="kw">let </span>file = smol::fs::File::create(path).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#67 id=67 data-nosnippet>67</a>        <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
<a href=#68 id=68 data-nosnippet>68</a>            file,
<a href=#69 id=69 data-nosnippet>69</a>            buffer: Vec::with_capacity(buffer_size),
<a href=#70 id=70 data-nosnippet>70</a>            buffer_size,
<a href=#71 id=71 data-nosnippet>71</a>            compressed,
<a href=#72 id=72 data-nosnippet>72</a>            bytes_written: <span class="number">0</span>,
<a href=#73 id=73 data-nosnippet>73</a>        })
<a href=#74 id=74 data-nosnippet>74</a>    }
<a href=#75 id=75 data-nosnippet>75</a>
<a href=#76 id=76 data-nosnippet>76</a>    <span class="doccomment">/// Write data to the buffer (async, non-blocking)
<a href=#77 id=77 data-nosnippet>77</a>    ///
<a href=#78 id=78 data-nosnippet>78</a>    /// Data is buffered until the buffer is full or `flush()` is called.
<a href=#79 id=79 data-nosnippet>79</a>    /// If compression is enabled, data is compressed before buffering.
<a href=#80 id=80 data-nosnippet>80</a>    ///
<a href=#81 id=81 data-nosnippet>81</a>    /// # Parameters
<a href=#82 id=82 data-nosnippet>82</a>    /// - `data`: Data to write
<a href=#83 id=83 data-nosnippet>83</a>    ///
<a href=#84 id=84 data-nosnippet>84</a>    /// # Returns
<a href=#85 id=85 data-nosnippet>85</a>    /// Success or I/O error
<a href=#86 id=86 data-nosnippet>86</a>    ///
<a href=#87 id=87 data-nosnippet>87</a>    /// # Errors
<a href=#88 id=88 data-nosnippet>88</a>    /// Returns error if compression fails or buffer write fails
<a href=#89 id=89 data-nosnippet>89</a>    </span><span class="kw">pub async fn </span>write(<span class="kw-2">&amp;mut </span><span class="self">self</span>, data: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#90 id=90 data-nosnippet>90</a>        <span class="kw">let </span>data_to_write = <span class="kw">if </span><span class="self">self</span>.compressed {
<a href=#91 id=91 data-nosnippet>91</a>            <span class="comment">// Compress data using our compression utilities
<a href=#92 id=92 data-nosnippet>92</a>            </span><span class="kw">crate</span>::io::utils::compress_brotli(data, <span class="number">6</span>)<span class="question-mark">?
<a href=#93 id=93 data-nosnippet>93</a>        </span>} <span class="kw">else </span>{
<a href=#94 id=94 data-nosnippet>94</a>            data.to_vec()
<a href=#95 id=95 data-nosnippet>95</a>        };
<a href=#96 id=96 data-nosnippet>96</a>
<a href=#97 id=97 data-nosnippet>97</a>        <span class="self">self</span>.buffer.extend_from_slice(<span class="kw-2">&amp;</span>data_to_write);
<a href=#98 id=98 data-nosnippet>98</a>
<a href=#99 id=99 data-nosnippet>99</a>        <span class="kw">if </span><span class="self">self</span>.buffer.len() &gt;= <span class="self">self</span>.buffer_size {
<a href=#100 id=100 data-nosnippet>100</a>            <span class="self">self</span>.flush().<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#101 id=101 data-nosnippet>101</a>        }
<a href=#102 id=102 data-nosnippet>102</a>
<a href=#103 id=103 data-nosnippet>103</a>        <span class="prelude-val">Ok</span>(())
<a href=#104 id=104 data-nosnippet>104</a>    }
<a href=#105 id=105 data-nosnippet>105</a>
<a href=#106 id=106 data-nosnippet>106</a>    <span class="doccomment">/// Write serialized data (async, non-blocking)
<a href=#107 id=107 data-nosnippet>107</a>    ///
<a href=#108 id=108 data-nosnippet>108</a>    /// Serializes the data to JSON and writes it with optional compression.
<a href=#109 id=109 data-nosnippet>109</a>    ///
<a href=#110 id=110 data-nosnippet>110</a>    /// # Type Parameters
<a href=#111 id=111 data-nosnippet>111</a>    /// - `T`: Type that implements serde Serialize
<a href=#112 id=112 data-nosnippet>112</a>    ///
<a href=#113 id=113 data-nosnippet>113</a>    /// # Parameters
<a href=#114 id=114 data-nosnippet>114</a>    /// - `data`: Data to serialize and write
<a href=#115 id=115 data-nosnippet>115</a>    ///
<a href=#116 id=116 data-nosnippet>116</a>    /// # Returns
<a href=#117 id=117 data-nosnippet>117</a>    /// Success or error
<a href=#118 id=118 data-nosnippet>118</a>    ///
<a href=#119 id=119 data-nosnippet>119</a>    /// # Errors
<a href=#120 id=120 data-nosnippet>120</a>    /// Returns error if serialization, compression, or writing fails
<a href=#121 id=121 data-nosnippet>121</a>    </span><span class="kw">pub async fn </span>write_json&lt;T: serde::Serialize&gt;(
<a href=#122 id=122 data-nosnippet>122</a>        <span class="kw-2">&amp;mut </span><span class="self">self</span>,
<a href=#123 id=123 data-nosnippet>123</a>        data: <span class="kw-2">&amp;</span>T,
<a href=#124 id=124 data-nosnippet>124</a>    ) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#125 id=125 data-nosnippet>125</a>        <span class="kw">let </span>json = serde_json::to_string(data)
<a href=#126 id=126 data-nosnippet>126</a>            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))<span class="question-mark">?</span>;
<a href=#127 id=127 data-nosnippet>127</a>        <span class="self">self</span>.write(json.as_bytes()).<span class="kw">await
<a href=#128 id=128 data-nosnippet>128</a>    </span>}
<a href=#129 id=129 data-nosnippet>129</a>
<a href=#130 id=130 data-nosnippet>130</a>    <span class="doccomment">/// Flush buffer to file (async, non-blocking)
<a href=#131 id=131 data-nosnippet>131</a>    ///
<a href=#132 id=132 data-nosnippet>132</a>    /// Forces all buffered data to be written to the file.
<a href=#133 id=133 data-nosnippet>133</a>    ///
<a href=#134 id=134 data-nosnippet>134</a>    /// # Returns
<a href=#135 id=135 data-nosnippet>135</a>    /// Success or I/O error
<a href=#136 id=136 data-nosnippet>136</a>    ///
<a href=#137 id=137 data-nosnippet>137</a>    /// # Errors
<a href=#138 id=138 data-nosnippet>138</a>    /// Returns error if file write fails
<a href=#139 id=139 data-nosnippet>139</a>    </span><span class="kw">pub async fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#140 id=140 data-nosnippet>140</a>        <span class="kw">if </span>!<span class="self">self</span>.buffer.is_empty() {
<a href=#141 id=141 data-nosnippet>141</a>            <span class="self">self</span>.file.write_all(<span class="kw-2">&amp;</span><span class="self">self</span>.buffer).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#142 id=142 data-nosnippet>142</a>            <span class="self">self</span>.bytes_written += <span class="self">self</span>.buffer.len() <span class="kw">as </span>u64;
<a href=#143 id=143 data-nosnippet>143</a>            <span class="self">self</span>.buffer.clear();
<a href=#144 id=144 data-nosnippet>144</a>        }
<a href=#145 id=145 data-nosnippet>145</a>        <span class="self">self</span>.file.flush().<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#146 id=146 data-nosnippet>146</a>        <span class="prelude-val">Ok</span>(())
<a href=#147 id=147 data-nosnippet>147</a>    }
<a href=#148 id=148 data-nosnippet>148</a>
<a href=#149 id=149 data-nosnippet>149</a>    <span class="doccomment">/// Get total bytes written to the file
<a href=#150 id=150 data-nosnippet>150</a>    </span><span class="attr">#[must_use]
<a href=#151 id=151 data-nosnippet>151</a>    </span><span class="kw">pub fn </span>bytes_written(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u64 {
<a href=#152 id=152 data-nosnippet>152</a>        <span class="self">self</span>.bytes_written
<a href=#153 id=153 data-nosnippet>153</a>    }
<a href=#154 id=154 data-nosnippet>154</a>
<a href=#155 id=155 data-nosnippet>155</a>    <span class="doccomment">/// Check if compression is enabled
<a href=#156 id=156 data-nosnippet>156</a>    </span><span class="attr">#[must_use]
<a href=#157 id=157 data-nosnippet>157</a>    </span><span class="kw">pub fn </span>is_compressed(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<a href=#158 id=158 data-nosnippet>158</a>        <span class="self">self</span>.compressed
<a href=#159 id=159 data-nosnippet>159</a>    }
<a href=#160 id=160 data-nosnippet>160</a>}
<a href=#161 id=161 data-nosnippet>161</a>
<a href=#162 id=162 data-nosnippet>162</a><span class="kw">impl </span>Drop <span class="kw">for </span>AsyncFileWriter {
<a href=#163 id=163 data-nosnippet>163</a>    <span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<a href=#164 id=164 data-nosnippet>164</a>        <span class="comment">// Note: This is sync, in practice you'd want an async drop
<a href=#165 id=165 data-nosnippet>165</a>        </span>futures_lite::future::block_on(<span class="kw">async </span>{
<a href=#166 id=166 data-nosnippet>166</a>            <span class="kw">let _ </span>= <span class="self">self</span>.flush().<span class="kw">await</span>;
<a href=#167 id=167 data-nosnippet>167</a>        });
<a href=#168 id=168 data-nosnippet>168</a>    }
<a href=#169 id=169 data-nosnippet>169</a>}
<a href=#170 id=170 data-nosnippet>170</a>
<a href=#171 id=171 data-nosnippet>171</a><span class="doccomment">/// Streaming file writer for large data sets
<a href=#172 id=172 data-nosnippet>172</a>///
<a href=#173 id=173 data-nosnippet>173</a>/// Optimized for streaming large amounts of data with minimal memory usage.
<a href=#174 id=174 data-nosnippet>174</a>/// Uses chunked writing and can integrate with async streams.
<a href=#175 id=175 data-nosnippet>175</a></span><span class="kw">pub struct </span>StreamingFileWriter {
<a href=#176 id=176 data-nosnippet>176</a>    file: smol::fs::File,
<a href=#177 id=177 data-nosnippet>177</a>    chunk_size: usize,
<a href=#178 id=178 data-nosnippet>178</a>    compressed: bool,
<a href=#179 id=179 data-nosnippet>179</a>    bytes_written: u64,
<a href=#180 id=180 data-nosnippet>180</a>}
<a href=#181 id=181 data-nosnippet>181</a>
<a href=#182 id=182 data-nosnippet>182</a><span class="kw">impl </span>StreamingFileWriter {
<a href=#183 id=183 data-nosnippet>183</a>    <span class="doccomment">/// Create a new streaming file writer
<a href=#184 id=184 data-nosnippet>184</a>    ///
<a href=#185 id=185 data-nosnippet>185</a>    /// # Parameters
<a href=#186 id=186 data-nosnippet>186</a>    /// - `path`: Path to the file to write
<a href=#187 id=187 data-nosnippet>187</a>    /// - `chunk_size`: Size of chunks to write at once
<a href=#188 id=188 data-nosnippet>188</a>    /// - `compressed`: Whether to compress chunks
<a href=#189 id=189 data-nosnippet>189</a>    ///
<a href=#190 id=190 data-nosnippet>190</a>    /// # Returns
<a href=#191 id=191 data-nosnippet>191</a>    /// New `StreamingFileWriter` instance
<a href=#192 id=192 data-nosnippet>192</a>    ///
<a href=#193 id=193 data-nosnippet>193</a>    /// # Errors
<a href=#194 id=194 data-nosnippet>194</a>    /// Returns error if file cannot be created
<a href=#195 id=195 data-nosnippet>195</a>    </span><span class="kw">pub async fn </span>new(
<a href=#196 id=196 data-nosnippet>196</a>        path: <span class="kw-2">&amp;</span>str,
<a href=#197 id=197 data-nosnippet>197</a>        chunk_size: usize,
<a href=#198 id=198 data-nosnippet>198</a>        compressed: bool,
<a href=#199 id=199 data-nosnippet>199</a>    ) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, std::io::Error&gt; {
<a href=#200 id=200 data-nosnippet>200</a>        <span class="kw">let </span>file = smol::fs::File::create(path).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#201 id=201 data-nosnippet>201</a>        <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
<a href=#202 id=202 data-nosnippet>202</a>            file,
<a href=#203 id=203 data-nosnippet>203</a>            chunk_size,
<a href=#204 id=204 data-nosnippet>204</a>            compressed,
<a href=#205 id=205 data-nosnippet>205</a>            bytes_written: <span class="number">0</span>,
<a href=#206 id=206 data-nosnippet>206</a>        })
<a href=#207 id=207 data-nosnippet>207</a>    }
<a href=#208 id=208 data-nosnippet>208</a>
<a href=#209 id=209 data-nosnippet>209</a>    <span class="doccomment">/// Write a chunk of data (async, non-blocking)
<a href=#210 id=210 data-nosnippet>210</a>    ///
<a href=#211 id=211 data-nosnippet>211</a>    /// Writes data immediately without buffering. Suitable for streaming.
<a href=#212 id=212 data-nosnippet>212</a>    ///
<a href=#213 id=213 data-nosnippet>213</a>    /// # Parameters
<a href=#214 id=214 data-nosnippet>214</a>    /// - `data`: Data chunk to write
<a href=#215 id=215 data-nosnippet>215</a>    ///
<a href=#216 id=216 data-nosnippet>216</a>    /// # Returns
<a href=#217 id=217 data-nosnippet>217</a>    /// Success or I/O error
<a href=#218 id=218 data-nosnippet>218</a>    ///
<a href=#219 id=219 data-nosnippet>219</a>    /// # Errors
<a href=#220 id=220 data-nosnippet>220</a>    /// Returns error if compression or writing fails
<a href=#221 id=221 data-nosnippet>221</a>    </span><span class="kw">pub async fn </span>write_chunk(<span class="kw-2">&amp;mut </span><span class="self">self</span>, data: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#222 id=222 data-nosnippet>222</a>        <span class="kw">let </span>data_to_write = <span class="kw">if </span><span class="self">self</span>.compressed {
<a href=#223 id=223 data-nosnippet>223</a>            <span class="kw">crate</span>::io::utils::compress_brotli(data, <span class="number">6</span>)<span class="question-mark">?
<a href=#224 id=224 data-nosnippet>224</a>        </span>} <span class="kw">else </span>{
<a href=#225 id=225 data-nosnippet>225</a>            data.to_vec()
<a href=#226 id=226 data-nosnippet>226</a>        };
<a href=#227 id=227 data-nosnippet>227</a>
<a href=#228 id=228 data-nosnippet>228</a>        <span class="self">self</span>.file.write_all(<span class="kw-2">&amp;</span>data_to_write).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#229 id=229 data-nosnippet>229</a>        <span class="self">self</span>.bytes_written += data_to_write.len() <span class="kw">as </span>u64;
<a href=#230 id=230 data-nosnippet>230</a>        <span class="prelude-val">Ok</span>(())
<a href=#231 id=231 data-nosnippet>231</a>    }
<a href=#232 id=232 data-nosnippet>232</a>
<a href=#233 id=233 data-nosnippet>233</a>    <span class="doccomment">/// Write from an async stream (async, non-blocking)
<a href=#234 id=234 data-nosnippet>234</a>    ///
<a href=#235 id=235 data-nosnippet>235</a>    /// Consumes an async stream and writes all chunks to the file.
<a href=#236 id=236 data-nosnippet>236</a>    ///
<a href=#237 id=237 data-nosnippet>237</a>    /// # Type Parameters
<a href=#238 id=238 data-nosnippet>238</a>    /// - `S`: Async stream type yielding byte chunks
<a href=#239 id=239 data-nosnippet>239</a>    ///
<a href=#240 id=240 data-nosnippet>240</a>    /// # Parameters
<a href=#241 id=241 data-nosnippet>241</a>    /// - `stream`: Async stream of byte data
<a href=#242 id=242 data-nosnippet>242</a>    ///
<a href=#243 id=243 data-nosnippet>243</a>    /// # Returns
<a href=#244 id=244 data-nosnippet>244</a>    /// Success or error
<a href=#245 id=245 data-nosnippet>245</a>    ///
<a href=#246 id=246 data-nosnippet>246</a>    /// # Errors
<a href=#247 id=247 data-nosnippet>247</a>    /// Returns error if reading from stream or writing fails
<a href=#248 id=248 data-nosnippet>248</a>    </span><span class="kw">pub async fn </span>write_from_stream&lt;S&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, <span class="kw-2">mut </span>stream: S) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt;
<a href=#249 id=249 data-nosnippet>249</a>    <span class="kw">where
<a href=#250 id=250 data-nosnippet>250</a>        </span>S: futures_lite::Stream&lt;Item = <span class="prelude-ty">Result</span>&lt;Bytes, std::io::Error&gt;&gt; + Unpin,
<a href=#251 id=251 data-nosnippet>251</a>    {
<a href=#252 id=252 data-nosnippet>252</a>        <span class="kw">while let </span><span class="prelude-val">Some</span>(chunk_result) = stream.next().<span class="kw">await </span>{
<a href=#253 id=253 data-nosnippet>253</a>            <span class="kw">let </span>chunk = chunk_result<span class="question-mark">?</span>;
<a href=#254 id=254 data-nosnippet>254</a>            <span class="self">self</span>.write_chunk(<span class="kw-2">&amp;</span>chunk).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#255 id=255 data-nosnippet>255</a>        }
<a href=#256 id=256 data-nosnippet>256</a>        <span class="self">self</span>.file.flush().<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#257 id=257 data-nosnippet>257</a>        <span class="prelude-val">Ok</span>(())
<a href=#258 id=258 data-nosnippet>258</a>    }
<a href=#259 id=259 data-nosnippet>259</a>
<a href=#260 id=260 data-nosnippet>260</a>    <span class="doccomment">/// Get total bytes written
<a href=#261 id=261 data-nosnippet>261</a>    </span><span class="attr">#[must_use]
<a href=#262 id=262 data-nosnippet>262</a>    </span><span class="kw">pub fn </span>bytes_written(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u64 {
<a href=#263 id=263 data-nosnippet>263</a>        <span class="self">self</span>.bytes_written
<a href=#264 id=264 data-nosnippet>264</a>    }
<a href=#265 id=265 data-nosnippet>265</a>
<a href=#266 id=266 data-nosnippet>266</a>    <span class="doccomment">/// Get the chunk size
<a href=#267 id=267 data-nosnippet>267</a>    </span><span class="attr">#[must_use]
<a href=#268 id=268 data-nosnippet>268</a>    </span><span class="kw">pub fn </span>chunk_size(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<a href=#269 id=269 data-nosnippet>269</a>        <span class="self">self</span>.chunk_size
<a href=#270 id=270 data-nosnippet>270</a>    }
<a href=#271 id=271 data-nosnippet>271</a>}
<a href=#272 id=272 data-nosnippet>272</a>
<a href=#273 id=273 data-nosnippet>273</a><span class="doccomment">/// Buffered writer with automatic compression and serialization
<a href=#274 id=274 data-nosnippet>274</a>///
<a href=#275 id=275 data-nosnippet>275</a>/// Advanced writer that combines buffering, compression, and serialization
<a href=#276 id=276 data-nosnippet>276</a>/// with progress tracking and error recovery.
<a href=#277 id=277 data-nosnippet>277</a></span><span class="kw">pub struct </span>AdvancedFileWriter {
<a href=#278 id=278 data-nosnippet>278</a>    inner: AsyncFileWriter,
<a href=#279 id=279 data-nosnippet>279</a>    progress_callback: <span class="prelude-ty">Option</span>&lt;Box&lt;<span class="kw">dyn </span>Fn(u64) + Send + Sync&gt;&gt;,
<a href=#280 id=280 data-nosnippet>280</a>    error_recovery: bool,
<a href=#281 id=281 data-nosnippet>281</a>}
<a href=#282 id=282 data-nosnippet>282</a>
<a href=#283 id=283 data-nosnippet>283</a><span class="kw">impl </span>AdvancedFileWriter {
<a href=#284 id=284 data-nosnippet>284</a>    <span class="doccomment">/// Create a new advanced file writer
<a href=#285 id=285 data-nosnippet>285</a>    ///
<a href=#286 id=286 data-nosnippet>286</a>    /// # Parameters
<a href=#287 id=287 data-nosnippet>287</a>    /// - `path`: Path to the file to write
<a href=#288 id=288 data-nosnippet>288</a>    /// - `buffer_size`: Size of the write buffer
<a href=#289 id=289 data-nosnippet>289</a>    /// - `compressed`: Whether to compress data
<a href=#290 id=290 data-nosnippet>290</a>    /// - `progress_callback`: Optional callback for progress updates
<a href=#291 id=291 data-nosnippet>291</a>    /// - `error_recovery`: Whether to attempt error recovery
<a href=#292 id=292 data-nosnippet>292</a>    ///
<a href=#293 id=293 data-nosnippet>293</a>    /// # Returns
<a href=#294 id=294 data-nosnippet>294</a>    /// New `AdvancedFileWriter` instance
<a href=#295 id=295 data-nosnippet>295</a>    ///
<a href=#296 id=296 data-nosnippet>296</a>    /// # Errors
<a href=#297 id=297 data-nosnippet>297</a>    /// Returns error if file cannot be created
<a href=#298 id=298 data-nosnippet>298</a>    </span><span class="kw">pub async fn </span>new(
<a href=#299 id=299 data-nosnippet>299</a>        path: <span class="kw-2">&amp;</span>str,
<a href=#300 id=300 data-nosnippet>300</a>        buffer_size: usize,
<a href=#301 id=301 data-nosnippet>301</a>        compressed: bool,
<a href=#302 id=302 data-nosnippet>302</a>        progress_callback: <span class="prelude-ty">Option</span>&lt;Box&lt;<span class="kw">dyn </span>Fn(u64) + Send + Sync&gt;&gt;,
<a href=#303 id=303 data-nosnippet>303</a>        error_recovery: bool,
<a href=#304 id=304 data-nosnippet>304</a>    ) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, std::io::Error&gt; {
<a href=#305 id=305 data-nosnippet>305</a>        <span class="kw">let </span>inner = AsyncFileWriter::with_config(path, buffer_size, compressed).<span class="kw">await</span><span class="question-mark">?</span>;
<a href=#306 id=306 data-nosnippet>306</a>        <span class="prelude-val">Ok</span>(<span class="self">Self </span>{
<a href=#307 id=307 data-nosnippet>307</a>            inner,
<a href=#308 id=308 data-nosnippet>308</a>            progress_callback,
<a href=#309 id=309 data-nosnippet>309</a>            error_recovery,
<a href=#310 id=310 data-nosnippet>310</a>        })
<a href=#311 id=311 data-nosnippet>311</a>    }
<a href=#312 id=312 data-nosnippet>312</a>
<a href=#313 id=313 data-nosnippet>313</a>    <span class="doccomment">/// Write data with progress tracking and error recovery
<a href=#314 id=314 data-nosnippet>314</a>    ///
<a href=#315 id=315 data-nosnippet>315</a>    /// # Parameters
<a href=#316 id=316 data-nosnippet>316</a>    /// - `data`: Data to write
<a href=#317 id=317 data-nosnippet>317</a>    ///
<a href=#318 id=318 data-nosnippet>318</a>    /// # Returns
<a href=#319 id=319 data-nosnippet>319</a>    /// Success or error
<a href=#320 id=320 data-nosnippet>320</a>    ///
<a href=#321 id=321 data-nosnippet>321</a>    /// # Errors
<a href=#322 id=322 data-nosnippet>322</a>    /// Returns error if writing fails (with optional recovery attempts)
<a href=#323 id=323 data-nosnippet>323</a>    </span><span class="kw">pub async fn </span>write_with_progress(<span class="kw-2">&amp;mut </span><span class="self">self</span>, data: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#324 id=324 data-nosnippet>324</a>        <span class="kw">let </span>result = <span class="self">self</span>.inner.write(data).<span class="kw">await</span>;
<a href=#325 id=325 data-nosnippet>325</a>
<a href=#326 id=326 data-nosnippet>326</a>        <span class="kw">if let </span><span class="prelude-val">Err</span>(<span class="kw-2">ref </span>e) = result
<a href=#327 id=327 data-nosnippet>327</a>            &amp;&amp; <span class="self">self</span>.error_recovery
<a href=#328 id=328 data-nosnippet>328</a>        {
<a href=#329 id=329 data-nosnippet>329</a>            <span class="comment">// Attempt recovery (could implement retry logic, backup writing, etc.)
<a href=#330 id=330 data-nosnippet>330</a>            </span><span class="macro">eprintln!</span>(<span class="string">"Write error, attempting recovery: {e}"</span>);
<a href=#331 id=331 data-nosnippet>331</a>            <span class="comment">// For now, just log - could implement more sophisticated recovery
<a href=#332 id=332 data-nosnippet>332</a>        </span>}
<a href=#333 id=333 data-nosnippet>333</a>
<a href=#334 id=334 data-nosnippet>334</a>        <span class="comment">// Update progress
<a href=#335 id=335 data-nosnippet>335</a>        </span><span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>callback) = <span class="self">self</span>.progress_callback {
<a href=#336 id=336 data-nosnippet>336</a>            callback(<span class="self">self</span>.inner.bytes_written());
<a href=#337 id=337 data-nosnippet>337</a>        }
<a href=#338 id=338 data-nosnippet>338</a>
<a href=#339 id=339 data-nosnippet>339</a>        result
<a href=#340 id=340 data-nosnippet>340</a>    }
<a href=#341 id=341 data-nosnippet>341</a>
<a href=#342 id=342 data-nosnippet>342</a>    <span class="doccomment">/// Write serialized data with progress tracking
<a href=#343 id=343 data-nosnippet>343</a>    ///
<a href=#344 id=344 data-nosnippet>344</a>    /// # Type Parameters
<a href=#345 id=345 data-nosnippet>345</a>    /// - `T`: Type that implements serde Serialize
<a href=#346 id=346 data-nosnippet>346</a>    ///
<a href=#347 id=347 data-nosnippet>347</a>    /// # Parameters
<a href=#348 id=348 data-nosnippet>348</a>    /// - `data`: Data to serialize and write
<a href=#349 id=349 data-nosnippet>349</a>    ///
<a href=#350 id=350 data-nosnippet>350</a>    /// # Returns
<a href=#351 id=351 data-nosnippet>351</a>    /// Success or error
<a href=#352 id=352 data-nosnippet>352</a>    ///
<a href=#353 id=353 data-nosnippet>353</a>    /// # Errors
<a href=#354 id=354 data-nosnippet>354</a>    /// Returns error if serialization or writing fails
<a href=#355 id=355 data-nosnippet>355</a>    </span><span class="kw">pub async fn </span>write_json_with_progress&lt;T: serde::Serialize&gt;(
<a href=#356 id=356 data-nosnippet>356</a>        <span class="kw-2">&amp;mut </span><span class="self">self</span>,
<a href=#357 id=357 data-nosnippet>357</a>        data: <span class="kw-2">&amp;</span>T,
<a href=#358 id=358 data-nosnippet>358</a>    ) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#359 id=359 data-nosnippet>359</a>        <span class="kw">let </span>json = serde_json::to_string(data)
<a href=#360 id=360 data-nosnippet>360</a>            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))<span class="question-mark">?</span>;
<a href=#361 id=361 data-nosnippet>361</a>        <span class="self">self</span>.write_with_progress(json.as_bytes()).<span class="kw">await
<a href=#362 id=362 data-nosnippet>362</a>    </span>}
<a href=#363 id=363 data-nosnippet>363</a>
<a href=#364 id=364 data-nosnippet>364</a>    <span class="doccomment">/// Flush all buffered data
<a href=#365 id=365 data-nosnippet>365</a>    ///
<a href=#366 id=366 data-nosnippet>366</a>    /// # Returns
<a href=#367 id=367 data-nosnippet>367</a>    /// Success or I/O error
<a href=#368 id=368 data-nosnippet>368</a>    ///
<a href=#369 id=369 data-nosnippet>369</a>    /// # Errors
<a href=#370 id=370 data-nosnippet>370</a>    /// Returns an I/O error if flushing the buffer fails.
<a href=#371 id=371 data-nosnippet>371</a>    </span><span class="kw">pub async fn </span>flush(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#372 id=372 data-nosnippet>372</a>        <span class="self">self</span>.inner.flush().<span class="kw">await
<a href=#373 id=373 data-nosnippet>373</a>    </span>}
<a href=#374 id=374 data-nosnippet>374</a>
<a href=#375 id=375 data-nosnippet>375</a>    <span class="doccomment">/// Get total bytes written
<a href=#376 id=376 data-nosnippet>376</a>    </span><span class="attr">#[must_use]
<a href=#377 id=377 data-nosnippet>377</a>    </span><span class="kw">pub fn </span>bytes_written(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u64 {
<a href=#378 id=378 data-nosnippet>378</a>        <span class="self">self</span>.inner.bytes_written()
<a href=#379 id=379 data-nosnippet>379</a>    }
<a href=#380 id=380 data-nosnippet>380</a>}
<a href=#381 id=381 data-nosnippet>381</a>
<a href=#382 id=382 data-nosnippet>382</a><span class="doccomment">/// Utility function for writing to stdout asynchronously
<a href=#383 id=383 data-nosnippet>383</a>///
<a href=#384 id=384 data-nosnippet>384</a>/// # Parameters
<a href=#385 id=385 data-nosnippet>385</a>/// - `data`: Data to write to stdout
<a href=#386 id=386 data-nosnippet>386</a>///
<a href=#387 id=387 data-nosnippet>387</a>/// # Returns
<a href=#388 id=388 data-nosnippet>388</a>/// Success or I/O error
<a href=#389 id=389 data-nosnippet>389</a>///
<a href=#390 id=390 data-nosnippet>390</a>/// # Errors
<a href=#391 id=391 data-nosnippet>391</a>/// Returns error if stdout write fails
<a href=#392 id=392 data-nosnippet>392</a></span><span class="kw">pub fn </span>write_stdout_async(data: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#393 id=393 data-nosnippet>393</a>    <span class="kw">use </span>std::io::Write;
<a href=#394 id=394 data-nosnippet>394</a>    <span class="kw">let </span><span class="kw-2">mut </span>stdout = std::io::stdout().lock();
<a href=#395 id=395 data-nosnippet>395</a>    stdout.write_all(data)<span class="question-mark">?</span>;
<a href=#396 id=396 data-nosnippet>396</a>    stdout.flush()<span class="question-mark">?</span>;
<a href=#397 id=397 data-nosnippet>397</a>    <span class="prelude-val">Ok</span>(())
<a href=#398 id=398 data-nosnippet>398</a>}
<a href=#399 id=399 data-nosnippet>399</a>
<a href=#400 id=400 data-nosnippet>400</a><span class="doccomment">/// Utility function for writing to stderr asynchronously
<a href=#401 id=401 data-nosnippet>401</a>///
<a href=#402 id=402 data-nosnippet>402</a>/// # Parameters
<a href=#403 id=403 data-nosnippet>403</a>/// - `data`: Data to write to stderr
<a href=#404 id=404 data-nosnippet>404</a>///
<a href=#405 id=405 data-nosnippet>405</a>/// # Returns
<a href=#406 id=406 data-nosnippet>406</a>/// Success or I/O error
<a href=#407 id=407 data-nosnippet>407</a>///
<a href=#408 id=408 data-nosnippet>408</a>/// # Errors
<a href=#409 id=409 data-nosnippet>409</a>/// Returns error if stderr write fails
<a href=#410 id=410 data-nosnippet>410</a></span><span class="kw">pub fn </span>write_stderr_async(data: <span class="kw-2">&amp;</span>[u8]) -&gt; <span class="prelude-ty">Result</span>&lt;(), std::io::Error&gt; {
<a href=#411 id=411 data-nosnippet>411</a>    <span class="kw">use </span>std::io::Write;
<a href=#412 id=412 data-nosnippet>412</a>    <span class="kw">let </span><span class="kw-2">mut </span>stderr = std::io::stderr().lock();
<a href=#413 id=413 data-nosnippet>413</a>    stderr.write_all(data)<span class="question-mark">?</span>;
<a href=#414 id=414 data-nosnippet>414</a>    stderr.flush()<span class="question-mark">?</span>;
<a href=#415 id=415 data-nosnippet>415</a>    <span class="prelude-val">Ok</span>(())
<a href=#416 id=416 data-nosnippet>416</a>}</code></pre></div></section></main></body></html>