2

I have a trait for readable and writable streams (like TcpStream):

pub trait MyTraitPool<T: Read + Write> {
    fn acquire(&self, &String) -> T;
    fn free(&self, T);
}

I want to implement that trait with TcpStream as T, so I would like to write

struct MyPool;

impl<T> MyTraitPool<T> for MyPool
    where T: Read + Write {

    fn acquire(&self, addr: &String) -> T {
        TcpStream::connect(addr.as_str()).unwrap()
    }

    fn free(&self, con: T) {
        con.shutdown(Shutdown::Both);
    }
}

I get the error "expected type parameter, found struct std::net::TcpStream" in the acquire method. As for the free method, I know that shutdown is TcpStream-specific, but I would like to have an implementation specific for TcpStreams at that point and hence be able to call TcpStream-specific methods. So how do I go about doing so?

As a side note: the implementation is just an example for what kind of things I would like to do, not for how the code operates later!

3
  • I'm getting different issues: "expected type parameter, found enum std::result::Result" (are you missing an unwrap in the code above?) and "no method named shutdown found for type T in the current scope" (assuming you are using only std::net::{TcpStream, Shutdown} and std::io::{Read, Write}). Commented Feb 1, 2017 at 13:42
  • @ljedrz the implementation above is only a sample, so I did not check for the return types or error management etc. (I wanted to keep the purpose simple and readable). The second problem is actually mentioned in the text above ;) Commented Feb 1, 2017 at 14:23
  • 1
    Ah yes, I wasn't reading carefully enough :). Nevertheless, it is always a good idea to provide code that reproduces the exact issue you are having upon compilation (MCVE) - it makes it much easier to find the solution applicable to your specific case. Commented Feb 1, 2017 at 14:30

1 Answer 1

1

Instead of making the MyTraitPool trait generic, you'd make your MyPool generic and you'd create an intermediate MyStream trait to offer you all methods you need:

trait MyStream: Read + Write {
    fn connect(&str) -> Self;
    fn shutdown(self);
}
impl MyStream for TcpStream {
    fn connect(addr: &str) -> Self { TcpStream::connect(addr) }
    fn shutdown(self) { TcpStream::shutdown(self, Shutdown::Both); }
}
impl<T: MyStream> MyTraitPool for MyPool<T> {
    fn acquire(&self, addr: &str) -> T {
        MyStream::connect(addr)
    }
    fn free(&self, con: T) {
        con.shutdown()
    }
}

Streams which do not actually need to shutdown, would simply leave the implementation empty.

Sign up to request clarification or add additional context in comments.

1 Comment

That looks like a good idea and I managed to make it compile, thank you a lot! I think I learned something new today :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.