fusio_core/dynamic/
mod.rs

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