0

I have this declaration:

impl<T: JobContext, R> TaskProcessor<T, R>
where
    R: hyper::service::Service<hyper::client::connect::dns::Name> + Clone + Send + Sync + 'static,
    R::Response: std::iter::Iterator<Item = std::net::SocketAddr>,
    R::Future: Send,
    R::Error: std::error::Error + Send + Sync,
{
}

I want to move the condition after where into its own trait so I could write something like:

impl<T: JobContext, R: DnsResolve> TaskProcessor<T, R> { }

What is the best way to do this?

let4be
  • 1,048
  • 11
  • 30
  • It looks like your question might be answered by the answers of [Is there any way to create a type alias for multiple traits?](https://stackoverflow.com/q/26070559/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 04 '21 at 20:44
  • 1
    I'd also mention that long `where` clauses are part of the job, and you get used to them pretty quickly. Unlike in Java where type signatures are primarily a chore, in Rust you'll find that they actually communicate useful information and contribute to readability. – Silvio Mayolo May 04 '21 at 20:46
  • I don't mind long declaration in one place, thing is I have nested types which kinda passthrough this `TaskProcessor` type(and it's `R`)... and rust won't allow me to compile unless I drag this long declaration in all of my types that use `TaskProcessor`. Copy-paste is bad – let4be May 04 '21 at 21:00
  • @Shepmaster my where clause has nested trait types(`Response`, `Future`, `Error`) defined inside `hyper::service::Service` and I have no idea how to reference them in a new trait. I would be very grateful for example... – let4be May 04 '21 at 21:03
  • One easy way is to import the items into scope. – Ibraheem Ahmed May 04 '21 at 21:24
  • @let4be You should be able to use the same `where` clause as in your original code, just with `Self` instead of `R`. `trait X: Y {}` is equivalent to `trait X where Self: Y {}`. – Francis Gagné May 04 '21 at 21:47
  • So how would I define the `DnsResolve` trait? Nothing I've been trying to do so far compiles... – let4be May 04 '21 at 23:00

1 Answers1

0

The following solved my problem

trait DnsResolve: hyper::service::Service<hyper::client::connect::dns::Name, Response: std::iter::Iterator<Item = std::net::SocketAddr>, Future: Send, Error: std::error::Error + Send + Sync> + Clone + Send + Sync + 'static
{
}

impl<T> DnsResolve for T where T: hyper::service::Service<hyper::client::connect::dns::Name, Response: std::iter::Iterator<Item = std::net::SocketAddr>, Future: Send, Error: std::error::Error + Send + Sync> + Clone + Send + Sync + 'static,
{
}

But this uses unstable feature

https://rust-lang.github.io/rfcs/2289-associated-type-bounds.html

https://github.com/rust-lang/rust/issues/52662

And I had to compile my code using nightly rustc... which I don't really like

This topic is quite complicated for me, is there any way around the associated type bounds in stable rust?

let4be
  • 1,048
  • 11
  • 30