5 releases

new 0.1.4 Mar 29, 2023
0.1.3 May 15, 2022
0.1.2 May 15, 2022
0.1.1 May 5, 2022
0.1.0 May 5, 2022

#271 in Rust patterns

Download history 65/week @ 2022-12-06 23/week @ 2022-12-13 14/week @ 2022-12-20 48/week @ 2022-12-27 17/week @ 2023-01-03 16/week @ 2023-01-10 29/week @ 2023-01-17 48/week @ 2023-01-24 52/week @ 2023-01-31 48/week @ 2023-02-07 28/week @ 2023-02-14 34/week @ 2023-02-21 16/week @ 2023-02-28 15/week @ 2023-03-07 18/week @ 2023-03-14 44/week @ 2023-03-21

93 downloads per month
Used in entrait

MIT license



A crate for targeting and accessing actual implementation.

Take an example trait:

trait ScrapeTheInternet {
    fn scrape_the_internet(&self) -> Vec<Website>;

The trait represents some abstract computation. The trait exports a method signature that can be implemented by types. In this case, we can imagine what a true implementation of the trait will do: Actually scrape the internet.

implementation provides the [Impl] type as an implementation target for traits having the following semantics:

  • The trait has only one actual, true implementation.
  • Other implementations of the trait may exist, but these are interpreted as fake, mocked in some way.

implementation enables a standardized way of writing these actual implementations in a way that allows the actual Self-receiver type to be unknown.


To define the actual, generic implementation of ScrapeTheInternet, we can write the following impl:

impl<T> ScrapeTheInternet for implementation::Impl<T> {
    fn scrape_the_internet(&self) -> Vec<Website> {
        todo!("find all the web pages, etc")

This code implements the trait for [Impl], and by doing that we have asserted that it is the actual, true implementation.

The implementation is fully generic, and works for any T.

use implementation::Impl;

struct MyType;

let websites = Impl::new(MyType).scrape_the_internet();

Trait bounds

The advantage of keeping trait implementations generic, is that the self type might live in a downstream crate. Let's say we need to access a configuration parameter from scrape_the_internet. E.g. the maximum number of pages to scrape:

use implementation::Impl;

trait GetMaxNumberOfPages {
    fn get_max_number_of_pages(&self) -> Option<usize>;

impl<T> ScrapeTheInternet for Impl<T>
    where Impl<T>: GetMaxNumberOfPages
    fn scrape_the_internet(&self) -> Vec<Website> {
        let max_number_of_pages = self.get_max_number_of_pages();
        todo!("find all the web pages, etc")

Now, for this to work, Impl<T> also needs to implement GetMaxNumberOfPages (for the same T that is going to be used).

GetMaxNumberOfPages would likely be implemented for a specific T rather than a generic one, since that T would typically be some configuration holding that number:

struct Config {
    max_number_of_pages: Option<usize>

impl GetMaxNumberOfPages for implementation::Impl<Config> {
    fn get_max_number_of_pages(&self) -> Option<usize> {


This crate is the solution to a trait coherence problem.

Given the trait above, we would like to provide an actual and a mocked implementation. We might know what its actual implementation looks like as an algorithm, but not what type it should be implemented for. There could be several reasons to have a generic Self:

  • The Self type might live in a downstream crate
  • It is actually designed to work generically

If we had used a generic Self type (impl<T> DoSomething for T), the trait would be unable to also have distinct fake implementations, because that would break the coherence rules: A generic ("blanket") impl and a specialized impl are not allowed to exist at the same time, because that would lead to ambiguity.

To solve that, a concrete type is needed as implementation target. But that type is allowed to be generic internally. It's just the root level that needs to be a concretely named type.

That type is the [Impl] type.

When we use this implementation, we can create as many fake implementations as we want.

License: MIT

No runtime deps