macro_rules! contract {
(
// Client => Connection generic
$($client:ident => $conn_name:ident),+;
// Contract to implement => Implementing struct, type of connection access
$contract:path => $struct:ident, $type:ident;
$($id:ident => $bound:path),*;
$($b:item)*
) => { ... };
}Expand description
Used to implement a contract for any adapter used by business level services and reducing boilerplate associated with adapter generics.
The following syntax is accepted:
contract! {
// Specifies which clients will use which type of connections
Postgres => PgConnection;
// Implements Contract for Implementor and specifies which type
// of access the repository will use, can be RepositoryAccess or AcidRepositoryAccess
Contract => Implementor, AccessType;
// Naming the bounds through which the repository methods can be called
User => UserRepository<C>,
/* ... */
// Function implementations for the trait
fn get_user_by_id(&self, some_param: &str) -> {
let mut conn = self.connect()?;
User::get_paginated(&mut conn, page, per_page, sort).map_err(Error::new)
}
/* ... */
}
The first ident => ident parameter specifies the contract to implement (left) and the struct on which
to implement it (right).
The second parameter is the repository access type, specifying whether the adapter will support transactions. This can be either RepositoryAccess or AcidRepositoryAccess.
The third pair of parameters are any number of ident => path pairs representing how the repositories will be named in the impl block.
From the example above, a U generic will be created in place of a UserRepository, therefore accessing its methods
is done via U::method(/* .. */).
The last pair of parameters are any number of function items for the trait implementation.
The first three pairs of arguments are used for the bounds in the contract implementation, while the fourth (the function items) are used to generate the impl block.