fusio_core/dynamic/
mod.rs1pub 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 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 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}