Thrussh, tokio and futures


#1

Hi there,
I’m moving a little bit out of my league yet I suppose, trying to do something with a the thrussh crate (https://docs.rs/thrussh/0.19.4/thrussh/), which uses tokio, futures which is not easy for me.
Actually first I am trying to just decompose some of the given code inside my own code, meaning to split up example’s code to smaller functions. (the initial steps of splitting up actually gave me already some headaches, since you need to define the right traits in the fn and the future return correctly).

I don’t know if I really need to go all the way explaining it, building a small example, I want to try first by just give the error output, and hope to find easy answers (I want to give myself time to understand more about futures later).
Of course if the following doesn’t leave easy answers I might have to explain more.

no method named and_then found for type thrussh::client::ChannelOpen<R, H, thrussh::client::SessionChannel> in the current scope
–> src/net/connect_to/com_client.rs:130:14
|
130 | .and_then(|(session, channelid)| {
| ^^^^^^^^
|
= note: the method and_then exists but the following trait bounds were not satisfied:
thrussh::client::ChannelOpen<R, H, thrussh::client::SessionChannel> : futures::Future
`&mut thrussh::client::ChannelOpen<R, H, thrussh::client::SessionChannel> : futures::Future’

The code is this (" .and_then(|(session, channelid)| {" the problematic part)

fn do_session<R, H> (
    self,
    id: String,
    connection: client::Connection<R, H>,
) -> impl Future<Item = Self, Error = thrussh::HandlerError<()>>
where
    R: tokio_io::AsyncRead + tokio_io::AsyncWrite,
    H: client::Handler,
{
    info!("Session could be established!");
    connection
        .channel_open_session()
        .and_then(|(session, channelid)| {
            info!("Session could be opened, sending out!");

            // send real authentification
            let auth_data = DataSession::Auth {
                auth: DataAuth::new(id),
            };

            session
                .data(channelid, None, bincode::serialize(&auth_data).unwrap())
                .and_then(|(mut session, _)| {
                    session.disconnect(Disconnect::ByApplication, "Ciao", "");
                    session
                })
                .or_else(|e| {
                    error!("Session could not be opened!");
                    Err(e)
                })
        })
        .or_else(|e| {
            error!("Channel could not be openend!");
            Err(e)
        })
}

}

I hope this somehow looks readable. I assume it means ChannelOpen has no Future trait, am I correct?
But looking into the documentation I find something like:

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler, ChannelType> Future for ChannelOpen<R, H, ChannelType>

(from https://docs.rs/thrussh/0.16.2/thrussh/client/struct.ChannelOpen.html)
Is there something easy that I am missing (Tcp-Trait???), otherwise if this is not enough example code I will provide a hopefully better example another time. I’m already tired, I am trying already for some days to find something, and will go to bed.
Help will be appreciated, thank you guys
Sven


#2

You need to add + Tcp to that line. ChannelOpen implements Future only when those type bounds are satisfied, and they require the Tcp one.

Tcp is here looks like: https://docs.rs/thrussh/0.19.5/thrussh/trait.Tcp.html. It looks like the doc link you were looking at is for an older version that doesn’t have Tcp.


#3

Thanks a bunch, I might have l looked for a wrong Tcp trait or so … since I was looking for many other things, which I could solve, I was too blind to see and to make that step. :+1::+1: