Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TryStream on rule get prevent the use of stream combinators #91

Open
Stormshield-robinc opened this issue Feb 5, 2025 · 1 comment
Open

Comments

@Stormshield-robinc
Copy link

Hi,

I stumble on a annoying problem while trying to list rules for both ipv4 and ipv6.
I wanted to merge both requests into the same Stream with a futures::stream::select, but rust cannot figure out that the resulting Stream is also a TryStream

use futures::TryStreamExt;

pub async fn get_rules() {
    let (connection, handle, _) = rtnetlink::new_connection().unwrap();

    let rules4 = handle.rule().get(rtnetlink::IpVersion::V4).execute();
    let rules6 = handle.rule().get(rtnetlink::IpVersion::V6).execute();

    let mut rules = futures::stream::select(rules4, rules6);

    while let Some(rule) = rules.try_next().await.unwrap() {
    }
}
error[E0599]: the method `try_next` exists for struct `Select<impl TryStream<Ok = RuleMessage, Error = Error>, ...>`, but its trait bounds were not satisfied
  --> src/lib.rs:11:34
   |
11 |       while let Some(rule) = rules.try_next().await.unwrap() {
   |                                    ^^^^^^^^
   |
  ::: /home/Stormshield-robinc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.31/src/stream/select.rs:8:1
   |
8  | / pin_project! {
9  | |     /// Stream for the [`select()`] function.
10 | |     #[derive(Debug)]
11 | |     #[must_use = "streams do nothing unless polled"]
...  |
15 | |     }
16 | | }
   | |_- doesn't satisfy `_: TryStreamExt` or `_: TryStream`
   |
   = note: the full type name has been written to '/home/Stormshield-robinc/bin/rust_bin/target/debug/deps/rust_bin-1fde713015a894f5.long-type-8387156802266828194.txt'
   = note: consider using `--verbose` to print the full type name to the console
   = note: the following trait bounds were not satisfied:
           `futures::stream::Select<impl TryStream<Ok = netlink_packet_route::rule::message::RuleMessage, Error = rtnetlink::Error>, impl TryStream<Ok = netlink_packet_route::rule::message::RuleMessage, Error = rtnetlink::Error>>: TryStream`
           which is required by `futures::stream::Select<impl TryStream<Ok = netlink_packet_route::rule::message::RuleMessage, Error = rtnetlink::Error>, impl TryStream<Ok = netlink_packet_route::rule::message::RuleMessage, Error = rtnetlink::Error>>: TryStreamExt`

Since the rule get signature is

pub fn execute(self) -> impl TryStream<Ok = RuleMessage, Error = Error>

it does not constrain the Stream::Item to a Result, which later on wont let rust understand that the Select is also compatbile with a TrySelect.

I think that changing the signature to Stream would fix this issue without breaking the interface. I can submit a PR if this is ok for you

@cathay4t
Copy link
Member

I need proof on API stability on changing impl TryStream to impl Stream. Otherwise, please add new functions as:

impl RuleGetRequest {
    pub fn execute_stream(self) -> impl Stream<Item=Result<RuleMessage, Error>> {
    }
}

Another approach would be find a way to allow select on two TryStream, maybe asking in https://github.com/rust-lang/futures-rs ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants