How to use AsyncRead compatibility layer with Futures 0.3


#1

I want to use tokio_codec::FramedRead to break a type implementing AsyncRead into frames, however, I could not find any equivalent implementation of tokio_codec for Futures 0.3

Futures 0.3 have a compatibility util allowing to convert types from Futures 0.3 to Futures 0.1. The relevant code can be seen here:

I plan to use it as follows:

use futures_util::compat::{Compat, Stream01CompatExt, Executor01CompatExt, Future01CompatExt};
use tokio_codec::FramedRead;
use frame_codec::FrameCodec;
/* ... */
let reader = FramedRead::new(async_reader.compat(), FrameCodec::new())

However, I didn’t manage to make this code compile.
Note that the code at compat03as01.rs requires the io-compat feature to be enabled.
The relevant part of my Cargo.toml:

futures-preview = "0.3.0-alpha.7"
futures-util-preview = {version = "0.3.0-alpha.7", features = ["compat", "io-compat"]}

Trying to compile results with the following error:

$ cargo test
error: failed to select a version for `futures-util-preview`.
    ... required by package `cswitch-utils v0.1.0 (/home/real/projects/d/cswitch/components/utils)`
    ... which is depended on by `cswitch-crypto v0.1.0 (/home/real/projects/d/cswitch/components/crypto)`
    ... which is depended on by `cswitch-secure-channel v0.1.0 (/home/real/projects/d/cswitch/components/secure_channel)`
versions that meet the requirements `= 0.3.0-alpha.7` are: 0.3.0-alpha.7

the package `cswitch-utils` depends on `futures-util-preview`, with features: `io-compat` but `futures-util-preview` does not have these features.


failed to select a version for `futures-util-preview` which could resolve this conflict

If I omit the io-compat feature from Cargo.toml, I get a different compile error. The relevant part of the error message:

error[E0599]: no method named `compat` found for type `async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>>` in the current scope                                                       
   --> components/utils/src/async_adapter.rs:242:51                                                                                                                                                                
    |                                                                                                                                                                                                              
10  | pub struct AsyncReader<M> {                                                                                                                                                                                  
    | ------------------------- method `compat` not found for this                                                                                                                                                 
...                                                                                                                                                                                                                
242 |         let reader = FramedRead::new(async_reader.compat(), FrameCodec::new())                                                                                                                               
    |                                                   ^^^^^^                                                                                                                                                     
    |                                                                                                                                                                                                              
    = note: the method `compat` exists but the following trait bounds were not satisfied:                                                                                                                          
            `async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Stream01CompatExt`                                                                            
            `async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures::SinkExt`                                                                                                   
            `async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Future01CompatExt`                                                                            
            `async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Executor01CompatExt`                                                                          
            `&async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Stream01CompatExt`                                                                           
            `&async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures::SinkExt`                                                                                                  
            `&async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Future01CompatExt`                                                                           
            `&async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Executor01CompatExt`                                                                         
            `&mut async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Stream01CompatExt`                                                                       
            `&mut async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures::SinkExt`                                                                                              
            `&mut async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Future01CompatExt`                                                                       
            `&mut async_adapter::AsyncReader<futures::channel::mpsc::Receiver<std::vec::Vec<u8>>> : futures_util::compat::Executor01CompatExt`                                                                     
    = help: items from traits can only be used if the trait is implemented and in scope                                                                                                                            
    = note: the following traits define an item `compat`, perhaps you need to implement one of them:                                                                                                               
            candidate #1: `futures::TryFutureExt`                                                                                                                                                                  
            candidate #2: `futures::TryStreamExt`                                                                                                                                                                  
            candidate #3: `futures::SinkExt`                                                                                                                                                                       
            candidate #4: `futures_util::compat::Executor01CompatExt`                                                                                                                                              
            candidate #5: `futures_util::compat::Future01CompatExt`                                                                                                                                                
            candidate #6: `futures_util::compat::Stream01CompatExt`      

I might be missing something trivial here.
Any ideas are welcome!


#2

Note that io-compat is not available in the 0.3.0-alpha.7 release, it was only just merged 5 days ago. You can depend on futures-util-preview = { git = "https://github.com/rust-lang-nursery/futures-rs", features = ["io-compat"] } to get access to it before there’s a new release, but there is at least 1 bug in the compat layer as implemented in alpha.7 and master.


#3

@Nemo157: Thanks! It’s great to know. In that case I have something to look forward to (: