fusio_core/
lib.rs

1#![no_std]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6pub mod buf;
7#[cfg(feature = "alloc")]
8mod dynamic;
9mod maybe;
10
11use core::future::Future;
12
13pub use buf::{IoBuf, IoBufMut};
14#[cfg(feature = "alloc")]
15pub use dynamic::{
16    error::{BoxedError, Error},
17    DynRead, DynWrite,
18};
19pub use maybe::{MaybeOwned, MaybeSend, MaybeSendFuture, MaybeSync};
20
21pub trait Write: MaybeSend {
22    //! The core trait for writing data,
23    //! it is similar to [`std::io::Write`], but it takes the ownership of the buffer,
24    //! because completion-based IO requires the buffer to be pinned and should be safe to
25    //! cancellation.
26    //!
27    //! [`Write`] represents "sequential write all and overwrite" semantics,
28    //! which means each buffer will be written to the file sequentially and overwrite the previous
29    //! file when closed.
30    //!
31    //! Contents are not be garanteed to be written to the file until the [`Write::close`] method is
32    //! called, [`Write::flush`] may be used to flush the data to the file in some
33    //! implementations, but not all implementations will do so.
34    //!
35    //! Whether the operation is successful or not, the buffer will be returned,
36    //! fusio promises that the returned buffer will be the same as the input buffer.
37    //!
38    //! # Dyn Compatibility
39    //! This trait is not dyn compatible.
40    //! If you want to use [`Write`] trait in a dynamic way, you could use [`DynWrite`] trait.
41
42    type Error: core::error::Error + Send + Sync + 'static;
43
44    fn write_all<B: IoBuf>(
45        &mut self,
46        buf: B,
47    ) -> impl Future<Output = (Result<(), Self::Error>, B)> + MaybeSend;
48
49    fn flush(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend;
50
51    fn close(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend;
52}
53
54pub trait Read: MaybeSend + MaybeSync {
55    //! The core trait for reading data,
56    //! it is similar to [`std::io::Read`],
57    //! but it takes the ownership of the buffer,
58    //! because completion-based IO requires the buffer to be pinned and should be safe to
59    //! cancellation.
60    //!
61    //! [`Read`] represents "random exactly read" semantics,
62    //! which means the read operation will start at the specified position, and the buffer will be
63    //! exactly filled with the data read.
64    //!
65    //! The buffer will be returned with the result, whether the operation is successful or not,
66    //! fusio promises that the returned buffer will be the same as the input buffer.
67    //!
68    //! If you want sequential reading, try [`SeqRead`].
69    //!
70    //! # Dyn Compatibility
71    //! This trait is not dyn compatible.
72    //! If you want to use [`Read`] trait in a dynamic way, you could use [`DynRead`] trait.
73
74    type Error: core::error::Error + Send + Sync + 'static;
75
76    fn read_exact_at<B: IoBufMut>(
77        &mut self,
78        buf: B,
79        pos: u64,
80    ) -> impl Future<Output = (Result<(), Self::Error>, B)> + MaybeSend;
81
82    #[cfg(feature = "alloc")]
83    fn read_to_end_at(
84        &mut self,
85        buf: alloc::vec::Vec<u8>,
86        pos: u64,
87    ) -> impl Future<Output = (Result<(), Self::Error>, alloc::vec::Vec<u8>)> + MaybeSend;
88
89    fn size(&self) -> impl Future<Output = Result<u64, Self::Error>> + MaybeSend;
90}
91
92impl<R: Read> Read for &mut R {
93    type Error = R::Error;
94
95    fn read_exact_at<B: IoBufMut>(
96        &mut self,
97        buf: B,
98        pos: u64,
99    ) -> impl Future<Output = (Result<(), Self::Error>, B)> + MaybeSend {
100        R::read_exact_at(self, buf, pos)
101    }
102
103    #[cfg(feature = "alloc")]
104    fn read_to_end_at(
105        &mut self,
106        buf: alloc::vec::Vec<u8>,
107        pos: u64,
108    ) -> impl Future<Output = (Result<(), Self::Error>, alloc::vec::Vec<u8>)> + MaybeSend {
109        R::read_to_end_at(self, buf, pos)
110    }
111
112    fn size(&self) -> impl Future<Output = Result<u64, Self::Error>> + MaybeSend {
113        R::size(self)
114    }
115}
116
117impl<W: Write> Write for &mut W {
118    type Error = W::Error;
119
120    fn write_all<B: IoBuf>(
121        &mut self,
122        buf: B,
123    ) -> impl Future<Output = (Result<(), Self::Error>, B)> + MaybeSend {
124        W::write_all(self, buf)
125    }
126
127    fn flush(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend {
128        W::flush(self)
129    }
130
131    fn close(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend {
132        W::close(self)
133    }
134}