fusio_core/dynamic/
mod.rs

1pub mod error;
2
3use alloc::{boxed::Box, vec::Vec};
4use core::pin::Pin;
5
6use error::{BoxedError, Error};
7
8use crate::{
9    buf::slice::{Buf, BufMut},
10    IoBuf, IoBufMut, MaybeSend, MaybeSendFuture, MaybeSync, Read, Write,
11};
12
13pub trait DynWrite: MaybeSend {
14    //! Dyn compatible(object safety) version of [`Write`].
15    //! All implementations of [`Write`] has already implemented this trait.
16    //! Also, all implementations of [`DynWrite`] has already implemented [`Write`].
17    //! User should not use this trait directly.
18
19    fn write_all(
20        &mut self,
21        buf: Buf,
22    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, Buf)> + '_>>;
23
24    fn flush(&mut self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<(), BoxedError>> + '_>>;
25
26    fn close(&mut self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<(), BoxedError>> + '_>>;
27}
28
29impl<W: Write> DynWrite for W {
30    fn write_all(
31        &mut self,
32        buf: Buf,
33    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, Buf)> + '_>> {
34        Box::pin(async move {
35            let (result, slice) = W::write_all(self, buf).await;
36            (result.map_err(Into::into), slice)
37        })
38    }
39
40    fn flush(&mut self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<(), BoxedError>> + '_>> {
41        Box::pin(async move { W::flush(self).await.map_err(Into::into) })
42    }
43
44    fn close(&mut self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<(), BoxedError>> + '_>> {
45        Box::pin(async move { W::close(self).await.map_err(Into::into) })
46    }
47}
48
49impl<'write> Write for Box<dyn DynWrite + 'write> {
50    type Error = Error;
51
52    async fn write_all<B: IoBuf>(&mut self, buf: B) -> (Result<(), Self::Error>, B) {
53        let (result, buf) =
54            DynWrite::write_all(self.as_mut(), unsafe { buf.slice_unchecked(..) }).await;
55        (result.map_err(Into::into), unsafe {
56            B::recover_from_slice(buf)
57        })
58    }
59
60    async fn flush(&mut self) -> Result<(), Self::Error> {
61        DynWrite::flush(self.as_mut()).await.map_err(Into::into)
62    }
63
64    async fn close(&mut self) -> Result<(), Self::Error> {
65        DynWrite::close(self.as_mut()).await.map_err(Into::into)
66    }
67}
68
69pub trait DynRead: MaybeSend + MaybeSync {
70    //! Dyn compatible(object safety) version of [`Read`].
71    //! Same as [`DynWrite`].
72
73    fn read_exact_at(
74        &mut self,
75        buf: BufMut,
76        pos: u64,
77    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, BufMut)> + '_>>;
78
79    fn read_to_end_at(
80        &mut self,
81        buf: Vec<u8>,
82        pos: u64,
83    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, Vec<u8>)> + '_>>;
84
85    fn size(&self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<u64, BoxedError>> + '_>>;
86}
87
88impl<R> DynRead for R
89where
90    R: Read,
91{
92    fn read_exact_at(
93        &mut self,
94        buf: BufMut,
95        pos: u64,
96    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, BufMut)> + '_>> {
97        Box::pin(async move {
98            let (result, buf) = R::read_exact_at(self, buf, pos).await;
99            (result.map_err(Into::into), buf)
100        })
101    }
102
103    fn read_to_end_at(
104        &mut self,
105        buf: Vec<u8>,
106        pos: u64,
107    ) -> Pin<Box<dyn MaybeSendFuture<Output = (Result<(), BoxedError>, Vec<u8>)> + '_>> {
108        Box::pin(async move {
109            let (result, buf) = R::read_to_end_at(self, buf, pos).await;
110            (result.map_err(Into::into), buf)
111        })
112    }
113
114    fn size(&self) -> Pin<Box<dyn MaybeSendFuture<Output = Result<u64, BoxedError>> + '_>> {
115        Box::pin(async move { R::size(self).await.map_err(Into::into) })
116    }
117}
118
119impl<'read> Read for Box<dyn DynRead + 'read> {
120    type Error = Error;
121
122    async fn read_exact_at<B: IoBufMut>(&mut self, buf: B, pos: u64) -> (Result<(), Error>, B) {
123        let (result, buf) =
124            DynRead::read_exact_at(self.as_mut(), unsafe { buf.slice_mut_unchecked(..) }, pos)
125                .await;
126        (result.map_err(Into::into), unsafe {
127            B::recover_from_slice_mut(buf)
128        })
129    }
130
131    async fn read_to_end_at(&mut self, buf: Vec<u8>, pos: u64) -> (Result<(), Error>, Vec<u8>) {
132        let (result, buf) = DynRead::read_to_end_at(self.as_mut(), buf, pos).await;
133        (result.map_err(Into::into), buf)
134    }
135
136    async fn size(&self) -> Result<u64, Error> {
137        DynRead::size(self.as_ref()).await.map_err(Into::into)
138    }
139}