bitcoin_io/
bridge.rs

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