bitcoin_io/
bridge.rs

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