TL; DR: I am trying to hide implementation details of a generic type. When using it, I don't need to know what are the bound of that type:
// This function doesn't need to know what trait T implements
pub fn usage<T: WhateverImplementationDetails>(wrapper: &Wrapper<T>) {
wrapper.nice_public_function();
}
I would like much more to be able to just write something like (pseudo Rust)
pub fn usage(wrapper: &Wrapper<_>) {
wrapper.nice_public_function();
}
Note: if Wrapper
itself was a trait, I could have used any of those syntax, effectively hiding that there is an impl<T> Wrapper for WhateverImplementationDetails<T>
.
pub fn usage<T: Wrapper>(wrapper: &T);
pub fn usagewrapper(& impl Wrapper);
pub fn usagewrapper(& dyn Wrapper);
This pattern can be really useful for wrapper class over a trait, since the wrapped trait isn't visible at all from the public interface of the wrapper, and it's guaranteed that to be able to compile, the caller of the function will implement use a type that implement that trait for the generic parameter of the wrapper.
// used only internally by the methods of `Wrapper<T: WhateverImplementationDetails>`
trait WhateverImplementationDetails {
fn foo();
fn bar();
}
// The public wrapper ...
pub struct Wrapper<T: WhateverImplementationDetails>{
forward: WhateverImplementationDetails;
}
// ... and the public API that the wrapper exposes
impl<T: WhateverImplementationDetails> Wrapper<T> {
// no public methods exposes `WhateverImplementationDetails`
pub fn nice_public_function(&self) {
// uses WhateverImplementationDetails only internally
self.forward.foo();
self.forward.bar();
}
}
// This function doesn't need to know what trait T implements, but AFAIK Rust syntax requires to write it
pub fn usage<T: WhateverImplementationDetails>(wrapper: &Wrapper<T>) {
wrapper.nice_public_function();
}
pub struct WhateverImplementationDetailsImpl; // nice name btw!
impl WhateverImplementationDetails for WhateverImplementationDetailsImpl { /* ... */ }
const SPECIFIC_IMPLEMENTATION: Wrapper<WhateverImplementationDetailsImpl> = Wrapper{ forward: WhateverImplementationDetails};
pub fn main() {
// At call site, it's guaranteed that the trait will be implemented for the generic parameter,
// otherwise it could not compile
usage(&SPECIFIC_IMPLEMENTATION);
}