Disclaimer: There rage in this question accumulated over a year.
TLDR: Is possible to encapsulate Session<RoundRobin<TcpConnectionPool<NoneAuthenticator>>>
into Box<Session<IReallyDontCareHowYouSolveYourProblems>>
Many libraries use a long tree of generics to resolve their dependencies. For instance:
cdrs cassandra driver:
Session<RoundRobin<TcpConnectionPool<NoneAuthenticator>>>,
rs-tui:
Terminal<TermionBackend<AlternateScreen<MouseTerminal<RawTerminal<Stdout>>>>>
Now, if you try to send those references around, I need to pass all those types, or create an alias, or convert it into a generic.
This is especially painful if you try to use a trait to split abstractions to be able to compose it dynamically, like:
trait Repository { fn get(id: u32) -> String }
struct FileRepository { base_path: String }; impl Repository for FileRepo { .. }
struct CassandraRepository { session : Session }; impl CassandraRepository for Cassandra { ... }
fn do_stuff(repo: Box<dyn Repository>) { repo.get(0) }
All the the code I found around, are using hardcoded alias:
type CurrentSession = Session<RoundRobin<TcpConnectionPool>>;
That basically means, If want not to use a Static password, I need to re-compile my whole application and generate a new build. I don't even understand how can I support password/anonymous configuration without 2 different builds.
If you choose the generic path, now you need to define your structures as generic too.
pub struct CassandraRepository
{
session: Session,
}
A now, everywhere where I try to use or store this struct, I need a type. And this keeps going and going until you end one type for each library and compiler errors that you have no clue how to workaround.
This is something I really get frustrated with every time I try to building anything using any complex library.
I reject to accept that is just the way to do it. I should be able to change configuration without have a completely different build, I should be able to add new libraries without the need to change every function in my program to support new T.
Now come to my question. Can I somehow encapsulate this and hide the inner generic types?
struct CassandraSession {
session: Box<dyn Session<_>>
}