bitcoin_io/
bridge.rs

1// SPDX-License-Identifier: CC0-1.0
2
3use internals::rust_version;
4
5internals::transparent_newtype! {
6    /// A bridging wrapper providing the I/O traits for types that already implement `std` I/O traits.
7    #[derive(Debug)]
8    pub struct FromStd<T>(T);
9
10    impl<T> FromStd<T> {
11        /// Wraps a mutable reference to I/O type.
12        pub fn new_mut(inner: &mut _) -> &mut Self;
13
14        /// Wraps a boxed I/O type.
15        pub fn new_boxed(inner: Box<_>) -> Box<Self>;
16    }
17}
18
19impl<T> FromStd<T> {
20    /// Wraps an I/O type.
21    #[inline]
22    pub const fn new(inner: T) -> Self { Self(inner) }
23
24    /// Returns the wrapped value.
25    #[inline]
26    pub fn into_inner(self) -> T { self.0 }
27
28    /// Returns a reference to the wrapped value.
29    #[inline]
30    pub fn get_ref(&self) -> &T { &self.0 }
31
32    /// Returns a mutable reference to the wrapped value.
33    #[inline]
34    pub fn get_mut(&mut self) -> &mut T { &mut self.0 }
35
36    /// Returns a reference to the wrapped value.
37    #[inline]
38    #[deprecated(since = "0.3.0", note = "use `get_ref()` instead")]
39    pub fn inner(&self) -> &T { &self.0 }
40
41    /// Returns a mutable reference to the wrapped value.
42    #[inline]
43    #[deprecated(since = "0.3.0", note = "use `get_mut()` instead")]
44    pub fn inner_mut(&mut self) -> &mut T { &mut self.0 }
45}
46
47impl<T: std::io::Read> super::Read for FromStd<T> {
48    #[inline]
49    fn read(&mut self, buf: &mut [u8]) -> super::Result<usize> {
50        self.0.read(buf).map_err(Into::into)
51    }
52
53    #[inline]
54    fn read_exact(&mut self, buf: &mut [u8]) -> super::Result<()> {
55        self.0.read_exact(buf).map_err(Into::into)
56    }
57}
58
59impl<T: std::io::BufRead> super::BufRead for FromStd<T> {
60    #[inline]
61    fn fill_buf(&mut self) -> super::Result<&[u8]> { self.0.fill_buf().map_err(Into::into) }
62
63    #[inline]
64    fn consume(&mut self, amount: usize) { self.0.consume(amount) }
65}
66
67impl<T: std::io::Write> super::Write for FromStd<T> {
68    #[inline]
69    fn write(&mut self, buf: &[u8]) -> super::Result<usize> {
70        self.0.write(buf).map_err(Into::into)
71    }
72
73    #[inline]
74    fn flush(&mut self) -> super::Result<()> { self.0.flush().map_err(Into::into) }
75
76    #[inline]
77    fn write_all(&mut self, buf: &[u8]) -> super::Result<()> {
78        self.0.write_all(buf).map_err(Into::into)
79    }
80}
81
82// We also impl std traits so that mixing the calls is not annoying.
83
84impl<T: std::io::Read> std::io::Read for FromStd<T> {
85    #[inline]
86    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { self.0.read(buf) }
87
88    #[inline]
89    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { self.0.read_exact(buf) }
90}
91
92impl<T: std::io::BufRead> std::io::BufRead for FromStd<T> {
93    #[inline]
94    fn fill_buf(&mut self) -> std::io::Result<&[u8]> { self.0.fill_buf() }
95
96    #[inline]
97    fn consume(&mut self, amount: usize) { self.0.consume(amount) }
98}
99
100impl<T: std::io::Write> std::io::Write for FromStd<T> {
101    #[inline]
102    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { self.0.write(buf) }
103
104    #[inline]
105    fn flush(&mut self) -> std::io::Result<()> { self.0.flush() }
106
107    #[inline]
108    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { self.0.write_all(buf) }
109}
110
111internals::transparent_newtype! {
112    /// A bridging wrapper providing the std traits for types that already implement our traits.
113    #[derive(Debug)]
114    pub struct ToStd<T>(T);
115
116    impl<T> ToStd<T> {
117        /// Wraps a mutable reference to I/O type.
118        pub fn new_mut(inner: &mut _) -> &mut Self;
119
120        /// Wraps a boxed I/O type.
121        pub fn new_boxed(inner: Box<_>) -> Box<Self>;
122    }
123}
124
125impl<T> ToStd<T> {
126    /// Wraps an I/O type.
127    #[inline]
128    pub const fn new(inner: T) -> Self { Self(inner) }
129
130    /// Returns the wrapped value.
131    #[inline]
132    pub fn into_inner(self) -> T { self.0 }
133
134    /// Returns a reference to the wrapped value.
135    #[inline]
136    pub fn inner(&self) -> &T { &self.0 }
137
138    /// Returns a mutable reference to the wrapped value.
139    #[inline]
140    pub fn inner_mut(&mut self) -> &mut T { &mut self.0 }
141}
142
143impl<T: super::Read> std::io::Read for ToStd<T> {
144    #[inline]
145    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
146        self.0.read(buf).map_err(Into::into)
147    }
148
149    #[inline]
150    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
151        self.0.read_exact(buf).map_err(Into::into)
152    }
153}
154
155impl<T: super::BufRead> std::io::BufRead for ToStd<T> {
156    #[inline]
157    fn fill_buf(&mut self) -> std::io::Result<&[u8]> { self.0.fill_buf().map_err(Into::into) }
158
159    #[inline]
160    fn consume(&mut self, amount: usize) { self.0.consume(amount) }
161}
162
163impl<T: super::Write> std::io::Write for ToStd<T> {
164    #[inline]
165    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
166        self.0.write(buf).map_err(Into::into)
167    }
168
169    #[inline]
170    fn flush(&mut self) -> std::io::Result<()> { self.0.flush().map_err(Into::into) }
171
172    #[inline]
173    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
174        self.0.write_all(buf).map_err(Into::into)
175    }
176}
177
178// We also impl our traits so that mixing the calls is not annoying.
179
180impl<T: super::Read> super::Read for ToStd<T> {
181    #[inline]
182    fn read(&mut self, buf: &mut [u8]) -> super::Result<usize> { self.0.read(buf) }
183
184    #[inline]
185    fn read_exact(&mut self, buf: &mut [u8]) -> super::Result<()> { self.0.read_exact(buf) }
186}
187
188impl<T: super::BufRead> super::BufRead for ToStd<T> {
189    #[inline]
190    fn fill_buf(&mut self) -> super::Result<&[u8]> { self.0.fill_buf() }
191
192    #[inline]
193    fn consume(&mut self, amount: usize) { self.0.consume(amount) }
194}
195
196impl<T: super::Write> super::Write for ToStd<T> {
197    #[inline]
198    fn write(&mut self, buf: &[u8]) -> super::Result<usize> { self.0.write(buf) }
199
200    #[inline]
201    fn flush(&mut self) -> super::Result<()> { self.0.flush() }
202
203    #[inline]
204    fn write_all(&mut self, buf: &[u8]) -> super::Result<()> { self.0.write_all(buf) }
205}
206
207macro_rules! impl_our {
208    (impl$(<$($gen:ident $(: $gent:path)?),*>)? Read for $std_type:ty $(where $($where:tt)*)?) => {
209        impl$(<$($gen$(: $gent)?),*>)? super::Read for $std_type $(where $($where)*)? {
210            #[inline]
211            fn read(&mut self, buf: &mut [u8]) -> super::Result<usize> {
212                std::io::Read::read(self, buf).map_err(Into::into)
213            }
214
215            #[inline]
216            fn read_exact(&mut self, buf: &mut [u8]) -> super::Result<()> {
217                std::io::Read::read_exact(self, buf).map_err(Into::into)
218            }
219        }
220    };
221
222    (impl$(<$($gen:ident $(: $gent:path)?),*>)? BufRead for $std_type:ty $(where $($where:tt)*)?) => {
223        impl$(<$($gen$(: $gent)?),*>)? super::BufRead for $std_type $(where $($where)*)? {
224            #[inline]
225            fn fill_buf(&mut self) -> super::Result<&[u8]> {
226                std::io::BufRead::fill_buf(self).map_err(Into::into)
227            }
228
229            #[inline]
230            fn consume(&mut self, amount: usize) {
231                std::io::BufRead::consume(self, amount)
232            }
233        }
234    };
235
236    (impl$(<$($gen:ident $(: $gent:path)?),*>)? Write for $std_type:ty $(where $($where:tt)*)?) => {
237        impl$(<$($gen$(: $gent)?),*>)? super::Write for $std_type $(where $($where)*)? {
238            #[inline]
239            fn write(&mut self, buf: &[u8]) -> super::Result<usize> {
240                std::io::Write::write(self, buf).map_err(Into::into)
241            }
242
243            #[inline]
244            fn flush(&mut self) -> super::Result<()> {
245                std::io::Write::flush(self).map_err(Into::into)
246            }
247
248            #[inline]
249            fn write_all(&mut self, buf: &[u8]) -> super::Result<()> {
250                std::io::Write::write_all(self, buf).map_err(Into::into)
251            }
252        }
253    };
254}
255
256impl_our! {
257    impl<R: std::io::Read> Read for std::io::BufReader<R> where R: ?Sized
258}
259
260impl_our! {
261    impl<R: std::io::Read> BufRead for std::io::BufReader<R> where R: ?Sized
262}
263
264impl_our! {
265    impl<W: std::io::Write> Write for std::io::BufWriter<W> where W: ?Sized
266}
267
268impl_our! {
269    impl<W: std::io::Write> Write for std::io::LineWriter<W> where W: ?Sized
270}
271
272impl std::io::Write for super::Sink {
273    #[inline]
274    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { Ok(buf.len()) }
275
276    #[inline]
277    fn write_all(&mut self, _: &[u8]) -> std::io::Result<()> { Ok(()) }
278
279    #[inline]
280    fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
281}
282
283impl_our! {
284    impl<R: std::io::Read> Read for std::io::Take<R>
285}
286
287impl_our! {
288    impl<R: std::io::BufRead> BufRead for std::io::Take<R>
289}
290
291impl_our! {
292    impl<R1: std::io::Read, R2: std::io::Read> Read for std::io::Chain<R1, R2>
293}
294
295impl_our! {
296    impl<R1: std::io::BufRead, R2: std::io::BufRead> BufRead for std::io::Chain<R1, R2>
297}
298
299impl_our! {
300    impl<T: AsRef<[u8]>> Read for std::io::Cursor<T>
301}
302
303impl_our! {
304    impl<T: AsRef<[u8]>> BufRead for std::io::Cursor<T>
305}
306
307impl_our! {
308    impl Write for std::io::Cursor<std::vec::Vec<u8>>
309}
310
311impl_our! {
312    impl Write for std::io::Cursor<&'_ mut std::vec::Vec<u8>>
313}
314
315impl_our! {
316    impl Write for std::io::Cursor<std::boxed::Box<[u8]>>
317}
318
319impl_our! {
320    impl Read for std::io::Empty
321}
322
323impl_our! {
324    impl BufRead for std::io::Empty
325}
326
327impl_our! {
328    impl Write for std::io::Empty
329}
330
331// No idea why &Empty impls Write but not Read + BufRead
332impl_our! {
333    impl Write for &'_ std::io::Empty
334}
335
336impl_our! {
337    impl Read for std::sync::Arc<std::fs::File>
338}
339
340impl_our! {
341    impl Write for std::sync::Arc<std::fs::File>
342}
343
344impl_our! {
345    impl Read for std::io::Repeat
346}
347
348impl_our! {
349    impl Read for std::io::Stdin
350}
351
352rust_version! {
353    if >= 1.78 {
354        impl_our! {
355            impl Read for &'_ std::io::Stdin
356        }
357    }
358}
359
360impl_our! {
361    impl Write for std::io::Stdout
362}
363
364impl_our! {
365    impl Write for &'_ std::io::Stdout
366}
367
368impl_our! {
369    impl Write for std::io::Stderr
370}
371
372impl_our! {
373    impl Write for &'_ std::io::Stderr
374}
375
376impl_our! {
377    impl Read for std::io::StdinLock<'_>
378}
379
380impl_our! {
381    impl BufRead for std::io::StdinLock<'_>
382}
383
384impl_our! {
385    impl Read for std::fs::File
386}
387
388impl_our! {
389    impl Write for std::fs::File
390}
391
392impl_our! {
393    impl Read for &'_ std::fs::File
394}
395
396impl_our! {
397    impl Write for &'_ std::fs::File
398}
399
400impl_our! {
401    impl Read for std::net::TcpStream
402}
403
404impl_our! {
405    impl Write for std::net::TcpStream
406}
407
408impl_our! {
409    impl Read for &'_ std::net::TcpStream
410}
411
412impl_our! {
413    impl Write for &'_ std::net::TcpStream
414}
415
416#[cfg(target_family = "unix")]
417impl_our! {
418    impl Read for std::os::unix::net::UnixStream
419}
420
421#[cfg(target_family = "unix")]
422impl_our! {
423    impl Write for std::os::unix::net::UnixStream
424}
425
426#[cfg(target_family = "unix")]
427impl_our! {
428    impl Read for &'_ std::os::unix::net::UnixStream
429}
430
431#[cfg(target_family = "unix")]
432impl_our! {
433    impl Write for &'_ std::os::unix::net::UnixStream
434}
435
436impl_our! {
437    impl Read for std::process::ChildStderr
438}
439
440impl_our! {
441    impl Read for std::process::ChildStdout
442}
443
444impl_our! {
445    impl Write for std::process::ChildStdin
446}
447
448// No idea why other &ChildStd* are not implemented
449impl_our! {
450    impl Write for &'_ std::process::ChildStdin
451}
452
453rust_version! {
454    if >= 1.75 {
455        impl_our! {
456            impl Read for std::collections::VecDeque<u8>
457        }
458
459        impl_our! {
460            impl BufRead for std::collections::VecDeque<u8>
461        }
462    }
463}
464
465impl_our! {
466    impl Write for std::collections::VecDeque<u8>
467}