diff --git a/http-file/CHANGES.md b/http-file/CHANGES.md index 92d5b7b8..5bc54fe8 100644 --- a/http-file/CHANGES.md +++ b/http-file/CHANGES.md @@ -1,3 +1,4 @@ # unreleased 0.2.0 ## Change +- project compile on stable Rust channel with MSRV of 1.79 - update `tokio-uring` to `0.5.0` diff --git a/http-file/src/lib.rs b/http-file/src/lib.rs index 8ac441db..ff6d7044 100644 --- a/http-file/src/lib.rs +++ b/http-file/src/lib.rs @@ -1,7 +1,5 @@ //! local file serving with http. -#![feature(impl_trait_in_assoc_type)] - pub mod runtime; mod buf; diff --git a/http-file/src/runtime.rs b/http-file/src/runtime.rs index 6f1ab821..1980042f 100644 --- a/http-file/src/runtime.rs +++ b/http-file/src/runtime.rs @@ -58,6 +58,11 @@ pub(crate) use tokio_impl::TokioFs; #[cfg(feature = "tokio")] mod tokio_impl { + use core::{ + pin::Pin, + task::{Context, Poll}, + }; + use tokio::{ fs::File, io::{AsyncReadExt, AsyncSeekExt}, @@ -65,16 +70,30 @@ mod tokio_impl { use super::*; + type BoxFuture<'a, T> = Pin + Send + 'a>>; + + pub struct OpenFuture { + handle: tokio::task::JoinHandle, + } + + impl Future for OpenFuture { + type Output = F; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.get_mut().handle).poll(cx).map(|res| res.unwrap()) + } + } + #[derive(Clone)] pub struct TokioFs; impl AsyncFs for TokioFs { type File = TokioFile; - type OpenFuture = impl Future> + Send; + type OpenFuture = OpenFuture>; fn open(&self, path: PathBuf) -> Self::OpenFuture { - async { - tokio::task::spawn_blocking(move || { + OpenFuture { + handle: tokio::task::spawn_blocking(move || { let file = std::fs::File::open(path)?; let meta = file.metadata()?; let modified_time = meta.modified().ok(); @@ -84,9 +103,7 @@ mod tokio_impl { modified_time, len, }) - }) - .await - .unwrap() + }), } } } @@ -109,25 +126,25 @@ mod tokio_impl { impl ChunkRead for TokioFile { type SeekFuture<'f> - = impl Future> + Send + 'f + = BoxFuture<'f, io::Result<()>> where Self: 'f; - type Future = impl Future>> + Send; + type Future = BoxFuture<'static, io::Result>>; fn seek(&mut self, pos: SeekFrom) -> Self::SeekFuture<'_> { - async move { self.file.seek(pos).await.map(|_| ()) } + Box::pin(async move { self.file.seek(pos).await.map(|_| ()) }) } fn next(mut self, mut buf: BytesMut) -> Self::Future { - async { + Box::pin(async { let n = self.file.read_buf(&mut buf).await?; if n == 0 { Ok(None) } else { Ok(Some((self, buf, n))) } - } + }) } } } @@ -137,19 +154,26 @@ pub(crate) use tokio_uring_impl::TokioUringFs; #[cfg(feature = "tokio-uring")] mod tokio_uring_impl { + use core::{ + future::{ready, Ready}, + pin::Pin, + }; + use tokio_uring::fs::File; use super::*; + type BoxFuture<'f, T> = Pin + 'f>>; + #[derive(Clone)] pub struct TokioUringFs; impl AsyncFs for TokioUringFs { type File = TokioUringFile; - type OpenFuture = impl Future>; + type OpenFuture = BoxFuture<'static, io::Result>; fn open(&self, path: PathBuf) -> Self::OpenFuture { - async { + Box::pin(async { let file = File::open(path).await?; // SAFETY: fd is borrowed and lives longer than the unsafe block @@ -173,7 +197,7 @@ mod tokio_uring_impl { modified_time, len, }) - } + }) } } @@ -196,22 +220,22 @@ mod tokio_uring_impl { impl ChunkRead for TokioUringFile { type SeekFuture<'f> - = impl Future> + 'f + = Ready> where Self: 'f; - type Future = impl Future>>; + type Future = BoxFuture<'static, io::Result>>; fn seek(&mut self, pos: SeekFrom) -> Self::SeekFuture<'_> { let SeekFrom::Start(pos) = pos else { unreachable!("ChunkRead::seek only accept pos as SeekFrom::Start variant") }; self.pos += pos; - async { Ok(()) } + ready(Ok(())) } fn next(mut self, buf: BytesMut) -> Self::Future { - async { + Box::pin(async { let (res, buf) = self.file.read_at(buf, self.pos).await; let n = res?; if n == 0 { @@ -220,7 +244,7 @@ mod tokio_uring_impl { self.pos += n as u64; Ok(Some((self, buf, n))) } - } + }) } } } diff --git a/web/Cargo.toml b/web/Cargo.toml index 4e8679d0..4c553342 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -55,7 +55,7 @@ file = ["file-raw", "http-file/default"] # static file serving with io-uring file-io-uring = ["io-uring", "file", "http-file/tokio-uring"] # static file serving without default file system -file-raw = ["http-file", "nightly"] +file-raw = ["http-file"] # rate-limit middleware rate-limit = ["http-rate"]