Hiding implementation details for a type with switchable strategy

I'm mulling over a general problem, of providing an API with switchable strategies for a data structure, and how to accomplish this with a number of goals in mind:

  • Hide implementation details
  • Simple interface (No duplicated type parameters or too complicated trait bounds for users)
  • Composable (can be wrapped in another data structure with the same switchable parameter).

I've got a draft that we can play with, and my main problem is how to hide implementation details? I need a public trait to bound; is there a way to move the details of the Backend trait to a private trait?

The proof of concept is pretty representative of the real problem: A graph that can either use a Vec or a Vec with "tombstones" and a free list.

Rust Playground Link

I think the “reversed” trait implementations for trait Backend solve the problem of not duplicating type parameters to simulate HKT, so that's good.

The client code looks as simple as it should be, i.e. you can encode the strategy in the type with minimum hassle.

fn main() {
    let mut g: Graph<i32> = Graph::new();
    let mut h: Graph<i32, CompactVec> = Graph::new();

Hiding woes seem to be solved, given that the pub in private module pattern seems to be blessed as a feature, not a bug.

mod privates { // this module is private
    // this trait counts as public for "private in public API" checks
    pub trait Foo { }