Skip to main content

bitcoin_io/
bridge.rs

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