0
votes

I'm trying to use the streamdeck-rs crate, and I'm having trouble getting the example code to work.

My implementation is basically the exact example given:

use futures::future::Future;
use std::env;
use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;

//the fields of these structs doesn't matter
struct GlobalSettings {}
struct ActionSettings {}
struct MessageToSd {}
struct MessageFromSd {}

fn register() {
    let params = RegistrationParams::from_args(env::args()).unwrap();
    let connect =
        StreamDeckSocket::<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>::connect(
            params.port,
            params.event,
            params.uuid,
        );
    tokio::run(
        connect
            .map_err(|e| println!("connection failed: {:?}", e))
            .and_then(|socket| {
                socket
                    .for_each(|message| println!("recieved: {:?}", message))
                    .map_err(|e| println!("read error: {:?}", e))
            }),
    );
}

My error message changes based on what I'm importing, but it's always a variant of "the method for_each exists but the following trait bounds were not satisfied". With the imports I listed now, my error message is:

error[E0599]: no method named `for_each` found for type `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>` in the current scope
  --> src/main.rs:37:35
   |
37 |         .and_then(|socket| socket.for_each(|message| println!("recieved: {:?}", message))
   |                                   ^^^^^^^^
   |
   = note: the method `for_each` exists but the following trait bounds were not satisfied:
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : std::iter::Iterator`

I can import future::Stream:

use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;
use std::env;
use futures::future::Future;
use futures::Stream;
//rest same as before

And I get this error:

error[E0599]: no method named `for_each` found for type `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>` in the current scope
  --> src/main.rs:37:35
   |
37 |         .and_then(|socket| socket.for_each(|message| println!("recieved: {:?}", message))
   |                                   ^^^^^^^^
   |
   = note: the method `for_each` exists but the following trait bounds were not satisfied:
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : futures::stream::Stream`
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : std::iter::Iterator`
           `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : futures::stream::Stream`



warning: unused import: `futures::Stream`

Note the warning about the unused import, too.

Because StreamDeckSocket is defined in the crate, I can't implement any traits on it.

I know this question exists in a few forms, but, from what I understand, those answers are only applicable if there is a missing trait implementation in the crate I'm using.

1
You definitely want thefor_each() method from futures::Stream, so you need to bring that trait in scope. If this leads to further errors, please add them to the question, so we can figure out how to resolve them. - Sven Marnach
@SvenMarnach added more details about the futures::Stream errors - Max
What versions of streamdeck_rs and futures are you using? From a quick look at the documentation, it appears that StreamDeckSocket should be implementing Stream. - Sven Marnach
Also note that some of your structs need to #[derive(Deserialize)]. - Sven Marnach

1 Answers

1
votes

The example code snippet isn't quite right, but very close:

  • the structures need to #[derive(Deserialize, Debug)]
  • according to the documentation, the closure passed to the for_each has the wrong type.

The following compiles:

use futures::future::Future;
use futures::stream::Stream;
use serde::Deserialize;
use std::env;
use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;

#[derive(Deserialize, Debug)]
struct GlobalSettings {}

#[derive(Deserialize, Debug)]
struct ActionSettings {}

#[derive(Deserialize, Debug)]
struct MessageToSd {}

#[derive(Deserialize, Debug)]
struct MessageFromSd {}

fn main() {
    let params = RegistrationParams::from_args(env::args()).unwrap();
    let connect =
        StreamDeckSocket::<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>::connect(
            params.port,
            params.event,
            params.uuid,
        );
    tokio::run(
        connect
            .map_err(|e| println!("connection failed: {:?}", e))
            .and_then(|socket| {
                socket
                    .for_each(|message| {
                        println!("recieved: {:?}", message);
                        Ok(())
                    })
                    .map_err(|e| println!("read error: {:?}", e))
            }),
    );
}