[pbs-devel] [RFC pxar 3/3] remove futures-io feature

Fabian Grünbichler f.gruenbichler at proxmox.com
Tue Jan 12 14:58:30 CET 2021


we don't use it, and it adds unnecessary duplication/complexity.

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---

Notes:
    I am not particularly fond of FileContents::poll_read scaling the buffer Vec
    like that..

 Cargo.toml          |   6 +--
 debian/control      |  78 ++++++++++----------------------
 src/accessor/aio.rs |  42 ++++-------------
 src/decoder/aio.rs  | 108 --------------------------------------------
 src/encoder/aio.rs  |  81 ---------------------------------
 src/encoder/mod.rs  |  21 ++-------
 6 files changed, 37 insertions(+), 299 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 875de7a..703525e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -53,16 +53,14 @@ tokio = { version = "1.0", optional = true, default-features = false }
 libc = "0.2"
 
 [features]
-default = [ "futures-io", "tokio-io" ]
-futures-io = [ "futures" ]
+default = [ "tokio-io" ]
 tokio-io = [ "tokio" ]
 tokio-fs = [ "tokio-io", "tokio/fs" ]
 
-full = [ "tokio-fs", "futures-io" ]
+full = [ "tokio-fs"]
 
 async-example = [
     "anyhow",
-    "futures-io",
     "tokio-io",
     "tokio-fs",
     "tokio/rt-multi-thread",
diff --git a/debian/control b/debian/control
index 0409da8..dbbd0d6 100644
--- a/debian/control
+++ b/debian/control
@@ -9,10 +9,9 @@ Build-Depends: debhelper (>= 11),
  librust-bitflags-1+default-dev (>= 1.2.1-~~) <!nocheck>,
  librust-endian-trait-0.6+arrays-dev <!nocheck>,
  librust-endian-trait-0.6+default-dev <!nocheck>,
- librust-futures-0.3+default-dev (>= 0.3.1-~~) <!nocheck>,
  librust-libc-0.2+default-dev <!nocheck>,
  librust-siphasher-0.3+default-dev <!nocheck>,
- librust-tokio-0.2-dev (>= 0.2.10-~~) <!nocheck>
+ librust-tokio-1-dev <!nocheck>
 Maintainer: Proxmox Support Team <support at proxmox.com>
 Standards-Version: 4.4.1
 Vcs-Git: 
@@ -29,13 +28,11 @@ Depends:
  librust-libc-0.2+default-dev,
  librust-siphasher-0.3+default-dev
 Recommends:
- librust-pxar+default-dev (= ${binary:Version})
+ librust-pxar+tokio-dev (= ${binary:Version})
 Suggests:
  librust-pxar+anyhow-dev (= ${binary:Version}),
  librust-pxar+async-example-dev (= ${binary:Version}),
- librust-pxar+full-dev (= ${binary:Version}),
  librust-pxar+futures-dev (= ${binary:Version}),
- librust-pxar+tokio-dev (= ${binary:Version}),
  librust-pxar+tokio-fs-dev (= ${binary:Version})
 Provides:
  librust-pxar+test-harness-dev (= ${binary:Version}),
@@ -70,13 +67,11 @@ Multi-Arch: same
 Depends:
  ${misc:Depends},
  librust-pxar-dev (= ${binary:Version}),
- librust-pxar+futures-io-dev (= ${binary:Version}),
  librust-pxar+tokio-io-dev (= ${binary:Version}),
  librust-pxar+tokio-fs-dev (= ${binary:Version}),
  librust-anyhow-1+default-dev,
- librust-tokio-0.2+io-driver-dev (>= 0.2.10-~~),
- librust-tokio-0.2+macros-dev (>= 0.2.10-~~),
- librust-tokio-0.2+rt-threaded-dev (>= 0.2.10-~~)
+ librust-tokio-1+macros-dev,
+ librust-tokio-1+rt-multi-thread-dev
 Provides:
  librust-pxar-0+async-example-dev (= ${binary:Version}),
  librust-pxar-0.6+async-example-dev (= ${binary:Version}),
@@ -85,38 +80,6 @@ Description: Proxmox Archive format support library - feature "async-example"
  This metapackage enables feature "async-example" for the Rust pxar crate, by
  pulling in any additional dependencies needed by that feature.
 
-Package: librust-pxar+default-dev
-Architecture: any
-Multi-Arch: same
-Depends:
- ${misc:Depends},
- librust-pxar-dev (= ${binary:Version}),
- librust-pxar+futures-io-dev (= ${binary:Version}),
- librust-pxar+tokio-io-dev (= ${binary:Version})
-Provides:
- librust-pxar-0+default-dev (= ${binary:Version}),
- librust-pxar-0.6+default-dev (= ${binary:Version}),
- librust-pxar-0.6.2+default-dev (= ${binary:Version})
-Description: Proxmox Archive format support library - feature "default"
- This metapackage enables feature "default" for the Rust pxar crate, by pulling
- in any additional dependencies needed by that feature.
-
-Package: librust-pxar+full-dev
-Architecture: any
-Multi-Arch: same
-Depends:
- ${misc:Depends},
- librust-pxar-dev (= ${binary:Version}),
- librust-pxar+tokio-fs-dev (= ${binary:Version}),
- librust-pxar+futures-io-dev (= ${binary:Version})
-Provides:
- librust-pxar-0+full-dev (= ${binary:Version}),
- librust-pxar-0.6+full-dev (= ${binary:Version}),
- librust-pxar-0.6.2+full-dev (= ${binary:Version})
-Description: Proxmox Archive format support library - feature "full"
- This metapackage enables feature "full" for the Rust pxar crate, by pulling in
- any additional dependencies needed by that feature.
-
 Package: librust-pxar+futures-dev
 Architecture: any
 Multi-Arch: same
@@ -125,18 +88,12 @@ Depends:
  librust-pxar-dev (= ${binary:Version}),
  librust-futures-0.3+default-dev (>= 0.3.1-~~)
 Provides:
- librust-pxar+futures-io-dev (= ${binary:Version}),
  librust-pxar-0+futures-dev (= ${binary:Version}),
- librust-pxar-0+futures-io-dev (= ${binary:Version}),
  librust-pxar-0.6+futures-dev (= ${binary:Version}),
- librust-pxar-0.6+futures-io-dev (= ${binary:Version}),
- librust-pxar-0.6.2+futures-dev (= ${binary:Version}),
- librust-pxar-0.6.2+futures-io-dev (= ${binary:Version})
-Description: Proxmox Archive format support library - feature "futures" and 1 more
+ librust-pxar-0.6.2+futures-dev (= ${binary:Version})
+Description: Proxmox Archive format support library - feature "futures"
  This metapackage enables feature "futures" for the Rust pxar crate, by pulling
  in any additional dependencies needed by that feature.
- .
- Additionally, this package also provides the "futures-io" feature.
 
 Package: librust-pxar+tokio-dev
 Architecture: any
@@ -144,20 +101,25 @@ Multi-Arch: same
 Depends:
  ${misc:Depends},
  librust-pxar-dev (= ${binary:Version}),
- librust-tokio-0.2-dev (>= 0.2.10-~~)
+ librust-tokio-1-dev
 Provides:
+ librust-pxar+default-dev (= ${binary:Version}),
  librust-pxar+tokio-io-dev (= ${binary:Version}),
  librust-pxar-0+tokio-dev (= ${binary:Version}),
+ librust-pxar-0+default-dev (= ${binary:Version}),
  librust-pxar-0+tokio-io-dev (= ${binary:Version}),
  librust-pxar-0.6+tokio-dev (= ${binary:Version}),
+ librust-pxar-0.6+default-dev (= ${binary:Version}),
  librust-pxar-0.6+tokio-io-dev (= ${binary:Version}),
  librust-pxar-0.6.2+tokio-dev (= ${binary:Version}),
+ librust-pxar-0.6.2+default-dev (= ${binary:Version}),
  librust-pxar-0.6.2+tokio-io-dev (= ${binary:Version})
-Description: Proxmox Archive format support library - feature "tokio" and 1 more
+Description: Proxmox Archive format support library - feature "tokio" and 2 more
  This metapackage enables feature "tokio" for the Rust pxar crate, by pulling in
  any additional dependencies needed by that feature.
  .
- Additionally, this package also provides the "tokio-io" feature.
+ Additionally, this package also provides the "default", and "tokio-io"
+ features.
 
 Package: librust-pxar+tokio-fs-dev
 Architecture: any
@@ -166,11 +128,17 @@ Depends:
  ${misc:Depends},
  librust-pxar-dev (= ${binary:Version}),
  librust-pxar+tokio-io-dev (= ${binary:Version}),
- librust-tokio-0.2+fs-dev (>= 0.2.10-~~)
+ librust-tokio-1+fs-dev
 Provides:
+ librust-pxar+full-dev (= ${binary:Version}),
  librust-pxar-0+tokio-fs-dev (= ${binary:Version}),
+ librust-pxar-0+full-dev (= ${binary:Version}),
  librust-pxar-0.6+tokio-fs-dev (= ${binary:Version}),
- librust-pxar-0.6.2+tokio-fs-dev (= ${binary:Version})
-Description: Proxmox Archive format support library - feature "tokio-fs"
+ librust-pxar-0.6+full-dev (= ${binary:Version}),
+ librust-pxar-0.6.2+tokio-fs-dev (= ${binary:Version}),
+ librust-pxar-0.6.2+full-dev (= ${binary:Version})
+Description: Proxmox Archive format support library - feature "tokio-fs" and 1 more
  This metapackage enables feature "tokio-fs" for the Rust pxar crate, by pulling
  in any additional dependencies needed by that feature.
+ .
+ Additionally, this package also provides the "full" feature.
diff --git a/src/accessor/aio.rs b/src/accessor/aio.rs
index dd017ae..c48ca8f 100644
--- a/src/accessor/aio.rs
+++ b/src/accessor/aio.rs
@@ -348,20 +348,19 @@ pub struct FileContents<T> {
 unsafe impl<T: Send> Send for FileContents<T> {}
 unsafe impl<T: Sync> Sync for FileContents<T> {}
 
-#[cfg(any(feature = "futures-io", feature = "tokio-io"))]
-impl<T: Clone + ReadAt> FileContents<T> {
-    /// Similar implementation exists for SeqReadAtAdapter in mod.rs
-    fn do_poll_read(
+#[cfg(feature = "tokio-io")]
+impl<T: Clone + ReadAt> tokio::io::AsyncRead for FileContents<T> {
+    fn poll_read(
         self: Pin<&mut Self>,
         cx: &mut Context,
-        dest: &mut [u8],
-    ) -> Poll<io::Result<usize>> {
+        dest: &mut tokio::io::ReadBuf,
+    ) -> Poll<io::Result<()>> {
         let this = unsafe { Pin::into_inner_unchecked(self) };
         loop {
             match this.future.take() {
                 None => {
                     let mut buffer = mem::take(&mut this.buffer);
-                    util::scale_read_buffer(&mut buffer, dest.len());
+                    util::scale_read_buffer(&mut buffer, dest.remaining());
                     let reader: accessor::FileContentsImpl<T> = this.inner.clone();
                     let at = this.at;
                     let future: Pin<Box<dyn Future<Output = io::Result<ReadResult>>>> =
@@ -384,9 +383,9 @@ impl<T: Clone + ReadAt> FileContents<T> {
                     Poll::Ready(Ok(ReadResult { len: got, buffer })) => {
                         this.buffer = buffer;
                         this.at += got as u64;
-                        let len = got.min(dest.len());
-                        dest[..len].copy_from_slice(&this.buffer[..len]);
-                        return Poll::Ready(Ok(len));
+                        let len = got.min(dest.remaining());
+                        dest.put_slice(&this.buffer[..len]);
+                        return Poll::Ready(Ok(()));
                     }
                 },
             }
@@ -394,29 +393,6 @@ impl<T: Clone + ReadAt> FileContents<T> {
     }
 }
 
-#[cfg(feature = "futures-io")]
-impl<T: Clone + ReadAt> futures::io::AsyncRead for FileContents<T> {
-    fn poll_read(
-        self: Pin<&mut Self>,
-        cx: &mut Context,
-        buf: &mut [u8],
-    ) -> Poll<io::Result<usize>> {
-        Self::do_poll_read(self, cx, buf)
-    }
-}
-
-#[cfg(feature = "tokio-io")]
-impl<T: Clone + ReadAt> tokio::io::AsyncRead for FileContents<T> {
-    fn poll_read(
-        self: Pin<&mut Self>,
-        cx: &mut Context,
-        buf: &mut tokio::io::ReadBuf,
-    ) -> Poll<io::Result<()>> {
-        Self::do_poll_read(self, cx, &mut buf.initialize_unfilled())
-            .map_ok(|bytes| { buf.set_filled(bytes); () })
-    }
-}
-
 impl<T: Clone + ReadAt> ReadAt for FileContents<T> {
     fn start_read_at<'a>(
         self: Pin<&'a Self>,
diff --git a/src/decoder/aio.rs b/src/decoder/aio.rs
index 1a5f5ea..82030b0 100644
--- a/src/decoder/aio.rs
+++ b/src/decoder/aio.rs
@@ -16,15 +16,6 @@ pub struct Decoder<T> {
     inner: decoder::DecoderImpl<T>,
 }
 
-#[cfg(feature = "futures-io")]
-impl<T: futures::io::AsyncRead> Decoder<FuturesReader<T>> {
-    /// Decode a `pxar` archive from a `futures::io::AsyncRead` input.
-    #[inline]
-    pub async fn from_futures(input: T) -> io::Result<Self> {
-        Decoder::new(FuturesReader::new(input)).await
-    }
-}
-
 #[cfg(feature = "tokio-io")]
 impl<T: tokio::io::AsyncRead> Decoder<TokioReader<T>> {
     /// Decode a `pxar` archive from a `tokio::io::AsyncRead` input.
@@ -69,107 +60,8 @@ impl<T: SeqRead> Decoder<T> {
     pub fn enable_goodbye_entries(&mut self, on: bool) {
         self.inner.with_goodbye_tables = on;
     }
-
-    /// Turn this decoder into a `Stream`.
-    #[cfg(feature = "futures-io")]
-    pub fn into_stream(self) -> DecoderStream<T> {
-        DecoderStream::new(self)
-    }
-}
-
-#[cfg(feature = "futures-io")]
-mod stream {
-    use std::future::Future;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::{Context, Poll};
-
-    use super::{Entry, SeqRead};
-
-    /// A wrapper for the async decoder implementing `futures::stream::Stream`.
-    ///
-    /// As long as streams are poll-based this wrapper is required to turn `async fn next()` into
-    /// `Stream`'s `poll_next()` interface.
-    #[allow(clippy::type_complexity)] // yeah no
-    pub struct DecoderStream<T> {
-        inner: super::Decoder<T>,
-        future: Option<Pin<Box<dyn Future<Output = Option<io::Result<Entry>>>>>>,
-    }
-
-    impl<T> DecoderStream<T> {
-        pub fn new(inner: super::Decoder<T>) -> Self {
-            Self {
-                inner,
-                future: None,
-            }
-        }
-    }
-
-    impl<T: SeqRead> futures::stream::Stream for DecoderStream<T> {
-        type Item = io::Result<Entry>;
-
-        fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
-            let this = unsafe { self.get_unchecked_mut() };
-            loop {
-                if let Some(mut fut) = this.future.take() {
-                    match fut.as_mut().poll(cx) {
-                        Poll::Ready(res) => return Poll::Ready(res),
-                        Poll::Pending => {
-                            this.future = Some(fut);
-                            return Poll::Pending;
-                        }
-                    }
-                }
-                unsafe {
-                    let fut: Box<dyn Future<Output = _>> = Box::new(this.inner.next());
-                    // Discard the lifetime:
-                    let fut: *mut (dyn Future<Output = Option<io::Result<Entry>>> + 'static) =
-                        core::mem::transmute(Box::into_raw(fut));
-                    let fut = Box::from_raw(fut);
-                    this.future = Some(Pin::new_unchecked(fut));
-                }
-            }
-        }
-    }
-}
-
-#[cfg(feature = "futures-io")]
-pub use stream::DecoderStream;
-
-#[cfg(feature = "futures-io")]
-mod fut {
-    use std::io;
-    use std::pin::Pin;
-    use std::task::{Context, Poll};
-
-    /// Read adapter for `futures::io::AsyncRead`
-    pub struct FuturesReader<T> {
-        inner: T,
-    }
-
-    impl<T: futures::io::AsyncRead> FuturesReader<T> {
-        pub fn new(inner: T) -> Self {
-            Self { inner }
-        }
-    }
-
-    impl<T: futures::io::AsyncRead> crate::decoder::SeqRead for FuturesReader<T> {
-        fn poll_seq_read(
-            self: Pin<&mut Self>,
-            cx: &mut Context,
-            buf: &mut [u8],
-        ) -> Poll<io::Result<usize>> {
-            unsafe {
-                self.map_unchecked_mut(|this| &mut this.inner)
-                    .poll_read(cx, buf)
-            }
-        }
-    }
 }
 
-#[cfg(feature = "futures-io")]
-use fut::FuturesReader;
-
 #[cfg(feature = "tokio-io")]
 mod tok {
     use std::io;
diff --git a/src/encoder/aio.rs b/src/encoder/aio.rs
index d989abd..908e019 100644
--- a/src/encoder/aio.rs
+++ b/src/encoder/aio.rs
@@ -9,11 +9,6 @@ use crate::encoder::{self, LinkOffset, SeqWrite};
 use crate::format;
 use crate::Metadata;
 
-// #[cfg(feature = "futures-io")]
-// use crate::decoder::aio::FuturesReader;
-// #[cfg(feature = "tokio-io")]
-// use crate::decoder::aio::TokioReader;
-
 /// Asynchronous `pxar` encoder.
 ///
 /// This is the `async` version of the `pxar` encoder.
@@ -22,18 +17,6 @@ pub struct Encoder<'a, T: SeqWrite + 'a> {
     inner: encoder::EncoderImpl<'a, T>,
 }
 
-#[cfg(feature = "futures-io")]
-impl<'a, T: futures::io::AsyncWrite + 'a> Encoder<'a, FuturesWriter<T>> {
-    /// Encode a `pxar` archive into a `futures::io::AsyncWrite` output.
-    #[inline]
-    pub async fn from_futures(
-        output: T,
-        metadata: &Metadata,
-    ) -> io::Result<Encoder<'a, FuturesWriter<T>>> {
-        Encoder::new(FuturesWriter::new(output), metadata).await
-    }
-}
-
 #[cfg(feature = "tokio-io")]
 impl<'a, T: tokio::io::AsyncWrite + 'a> Encoder<'a, TokioWriter<T>> {
     /// Encode a `pxar` archive into a `tokio::io::AsyncWrite` output.
@@ -214,21 +197,6 @@ impl<'a> File<'a> {
     }
 }
 
-#[cfg(feature = "futures-io")]
-impl<'a> futures::io::AsyncWrite for File<'a> {
-    fn poll_write(self: Pin<&mut Self>, cx: &mut Context, data: &[u8]) -> Poll<io::Result<usize>> {
-        unsafe { self.map_unchecked_mut(|this| &mut this.inner) }.poll_write(cx, data)
-    }
-
-    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
-        unsafe { self.map_unchecked_mut(|this| &mut this.inner) }.poll_flush(cx)
-    }
-
-    fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
-        unsafe { self.map_unchecked_mut(|this| &mut this.inner) }.poll_close(cx)
-    }
-}
-
 #[cfg(feature = "tokio-io")]
 impl<'a> tokio::io::AsyncWrite for File<'a> {
     fn poll_write(self: Pin<&mut Self>, cx: &mut Context, data: &[u8]) -> Poll<io::Result<usize>> {
@@ -244,55 +212,6 @@ impl<'a> tokio::io::AsyncWrite for File<'a> {
     }
 }
 
-/// Pxar encoder write adapter for `futures::io::AsyncWrite`.
-#[cfg(feature = "futures-io")]
-mod futures_writer {
-    use std::io;
-    use std::pin::Pin;
-    use std::task::{Context, Poll};
-
-    use crate::encoder::SeqWrite;
-
-    pub struct FuturesWriter<T> {
-        inner: Option<T>,
-    }
-
-    impl<T: futures::io::AsyncWrite> FuturesWriter<T> {
-        pub fn new(inner: T) -> Self {
-            Self { inner: Some(inner) }
-        }
-
-        fn inner_mut(&mut self) -> io::Result<Pin<&mut T>> {
-            let inner = self
-                .inner
-                .as_mut()
-                .ok_or_else(|| io_format_err!("write after close"))?;
-            Ok(unsafe { Pin::new_unchecked(inner) })
-        }
-
-        fn inner(self: Pin<&mut Self>) -> io::Result<Pin<&mut T>> {
-            unsafe { self.get_unchecked_mut() }.inner_mut()
-        }
-    }
-
-    impl<T: futures::io::AsyncWrite> SeqWrite for FuturesWriter<T> {
-        fn poll_seq_write(
-            self: Pin<&mut Self>,
-            cx: &mut Context,
-            buf: &[u8],
-        ) -> Poll<io::Result<usize>> {
-            let this = unsafe { self.get_unchecked_mut() };
-            this.inner_mut()?.poll_write(cx, buf)
-        }
-
-        fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
-            self.inner()?.poll_flush(cx)
-        }
-    }
-}
-
-pub use futures_writer::FuturesWriter;
-
 /// Pxar encoder write adapter for `tokio::io::AsyncWrite`.
 #[cfg(feature = "tokio-io")]
 mod tokio_writer {
diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs
index f186aa8..fdd04ae 100644
--- a/src/encoder/mod.rs
+++ b/src/encoder/mod.rs
@@ -818,7 +818,7 @@ impl<'a> FileImpl<'a> {
     }
 
     /// Poll write interface to more easily connect to tokio/futures.
-    #[cfg(any(feature = "tokio-io", feature = "futures-io"))]
+    #[cfg(feature = "tokio-io")]
     pub fn poll_write(
         self: Pin<&mut Self>,
         cx: &mut Context,
@@ -838,7 +838,7 @@ impl<'a> FileImpl<'a> {
     }
 
     /// Poll flush interface to more easily connect to tokio/futures.
-    #[cfg(any(feature = "tokio-io", feature = "futures-io"))]
+    #[cfg(feature = "tokio-io")]
     pub fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
         unsafe {
             self.map_unchecked_mut(|this| &mut this.output)
@@ -850,7 +850,7 @@ impl<'a> FileImpl<'a> {
     ///
     /// This just calls flush, though, since we're just a virtual writer writing to the file
     /// provided by our encoder.
-    #[cfg(any(feature = "tokio-io", feature = "futures-io"))]
+    #[cfg(feature = "tokio-io")]
     pub fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
         unsafe {
             self.map_unchecked_mut(|this| &mut this.output)
@@ -897,18 +897,3 @@ impl<'a> tokio::io::AsyncWrite for FileImpl<'a> {
         FileImpl::poll_close(self, cx)
     }
 }
-
-#[cfg(feature = "futures-io")]
-impl<'a> futures::io::AsyncWrite for FileImpl<'a> {
-    fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<io::Result<usize>> {
-        FileImpl::poll_write(self, cx, buf)
-    }
-
-    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
-        FileImpl::poll_flush(self, cx)
-    }
-
-    fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
-        FileImpl::poll_close(self, cx)
-    }
-}
-- 
2.20.1






More information about the pbs-devel mailing list