Attribute Macro entrait::entrait

source · []
#[entrait]
Expand description

The entrait attribute macro, used to generate traits and delegating implementations of them.

For functions

When used with a function, the macro must be given the name of a trait to generate. The macro will generate that trait, and connect it to the function by supplying an implementation for Impl, plus optional mock implementations.

Syntax
#[entrait($visibility? $TraitIdent)]
fn ...
  • $visibility: Optional visibility specifier for the generated trait. See the Rust documentation for valid values.
  • $TraitIdent: Any valid Rust identifier that starts with an upper-case character, used as the name of the new trait.

with options:

#[entrait($visibility? $TraitIdent, $option, ...)]
fn ...

For modules

Using the attribute on a module is used to group several non-private functions into one trait. Only non-private functions are considered by the macro.

Syntax
#[entrait($visibility? $TraitIdent)]
mod some_module {
    pub fn ...
}

For traits

When used with a trait, the macro will only provide a delegating implementation for Impl that delegates to another trait implementation. It can also optionally generate mock impls of the trait.

There are mainly two delegation modes:

  1. Specify a trait name to use as delegation target, resulting in an internal dependency.
  2. Don’t specify a trait name, resulting in a leaf dependency which has to delegate using the same trait, but for a different type.

When mocking is enabled, exporting the mocks is implicitly turned on (i.e. not gated by #[cfg(test)]).

Syntax
#[entrait($visibility? $TraitIdent?)]
trait ...

with options:

#[entrait($visibility? $TraitIdent?, $option, ...)]
trait ...
Example 1

Internal dependency, static dispatch (delegation bound: T: DelegateFoo<T>):

#[entrait(FooImpl, delegate_by = DelegateFoo)]
trait Foo {}

Note: The associated type DelegateFoo<T>::Target must implement FooImpl<T>.

Example 2

Leaf dependency, static dispatch (delegation bound: T: Foo):

#[entrait]
trait Foo {}
Example 3

Leaf dependency, dynamic dispatch (delegation bound: T: Borrow<dyn Foo>):

#[entrait(delegate_by = Borrow)]
trait Foo {}

Options

An option can be just $option or $option = $value. An option without value means true.

OptionTypeTargetDefaultDescription
no_depsboolfnfalseDisables the dependency parameter, so that the first parameter is just interpreted as a normal function parameter. Useful for reducing noise in some situations.
exportboolfn+modfalseIf mocks are generated, exports these mocks even in release builds. Only relevant for libraries.
unimockboolfn+mod+traitfalse1Used to turn off unimock implementation when the unimock feature is enabled.
mockallboolfn+mod+traitfalseEnable mockall mocks.
async_traitboolfn+mod+traitfalse2In the case of an async fn, use the async_trait macro on the resulting trait. Requires the async_trait entrait feature.
associated_futureboolfn+mod+traitfalse3In the case of an async fn, use an associated future to avoid heap allocation. Currently requires a nighlty Rust compiler, with feature(generic_associated_types) and feature(type_alias_impl_trait).
delegate_bySelf/Borrow/custom identtraitSelfControls the generated Impl<T> delegation of this trait. Self generates a T: Trait bound. Borrow generates a T: Borrow<dyn Trait> bound. Any other value generates a new trait with that name which controls the delegation.

  1. Enabled by default by turning on the unimock cargo feature. 

  2. Enabled by default by turning on the use-async-trait cargo feature. 

  3. Enabled by default by turning on the use-associated-future cargo feature.