More elegant way to call "generic" methods on a struct?

Thanks for the pointers @H2CO3 ! I actually tried some variations of both of these but couldn't quite get them to work for me (undoubtedly as a result of my own ignorance).

For option 1, would that involve having FtpConnection<Stream>? I guess not - more likely FtpConnection<T> where T is either FtpStream or NativeTlsFtpStream? (or just a true/false const bool that determines whether TLS is enabled?). I tried some of these, but specifically struggled with instantiating FtpConnection::new() from a URL string; since Rust insisted that I need to specify the generic in that instantiation statement. Yet the code calling FtpConnection::new() shouldn't care what stream type is being used.

For option 2, it seemed that Box<dyn Xyz> only works where Xyz is a trait rather than a struct. In this case FtpStream is a struct. But my understanding is probably lacking here. Looks like I should wrap my head around the discussion in What's the best approach to dynamic types chosen at runtime? Box, or enum, or something else?.

Either way, if you're able to point me to any bits of code that use the above approaches in practice that would be hugely appreciated!