i would like to add tls support using tokio-tls to the following function, and i want it to be generic, when i changed the return type from Result<TcpStream> to Result<T> in this code
You are trying to return a concrete type when your function expects you to return a generic type. Why do you want the type to be generic? Should the user be able to select the type when calling _connect_timeout::<T>()? Then you have to use T in the function body to create the object you want to return. You can implement a trait such as From<TcpStream> to construct a T inside the function:
Basically the issue is that T is chosen by the caller, so if the caller chooses T to be some other type than TcpStream, it will fail to match up the types. You will probably either have to ask the user to provide you with the stream, or create your own trait with a method for connecting.
I am not well versed in tokio, so I can not give you a direct solution, but maybe you should implement the function once for each kind of stream you want to return, and then do what @alice said and declare your own trait with all of the functions you use in the _connect_timeout variants, then you can implement it for all of the different streams you are looking to return:
trait MyStream {
fn connect<A: ToSocketAddr>(addr: A) -> Result<Self>;
...
}
impl MyStream for HttpStream { ... }
impl MyStream for HttpsStream { ... }
impl MyStream for TcpStream { ... }
async fn _connect_timeout<T>(&self) -> Result<T>
where
T: AsyncRead + AsyncWrite + Unpin + MyStream,
{
let stream = timeout(
self.connect_timeout,
T::connect(self.url.socket_addrs(|| None)?[0])
).await??;
Ok(stream)
}
...
let stream = a._connect_timeout::<HttpsStream>()?;