async-compat
async-compat copied to clipboard
Expose the guard API to allow users to enter tokio runtime
I came across #21 which is similar to this issue but it seems like only the Drop
part of that issue was implemented.
What I have is an enum which contains two variants: one contains a File
from the async_fs
crate and one contains a Compat<TempFile>
from the async_tempfile
crate (which uses tokio), and I have implementations of AsyncRead
and AsyncSeek
for this enum which just calls the poll_read
function of the underlying types. I need to somehow enter the tokio runtime when the variant is the one containing the tempfile.
I could just document the fact that my type has to be used with compat
, but this is not great for two reasons: the users would have to put compat
everywhere they use my type, and also they would be unnecessarily entering a tokio runtime every single time the enum's variant is the one containing the async file.
Here's some code to better illustrate my point:
pub enum AssetFileReader<'r, R>
where
R: AsyncRead + AsyncSeek + Unpin,
{
// This "DirectFileReader" thing just holds a reference to an async File
// It also forwards the async File AsyncRead and AsyncSeek implementations
Normal(DirectFileReader<'r, R>),
Decompressed(Compat<TempFile>),
}
impl<'r, R: AsyncRead + AsyncSeek + Unpin> AsyncRead for AssetFileReader<'r, R> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> Poll<futures_lite::io::Result<usize>> {
let this = self.get_mut();
match this {
AssetFileReader::Normal(r) => Pin::new(r).poll_read(cx, buf),
AssetFileReader::Decompressed(r) => {
// This is perhaps what the API should look like?
let _guard = enter_tokio_runtime();
Pin::new(r).poll_read(cx, buf)
},
}
}
}
// The AsyncSeek implementation is similar