macro_rules! delegate_atomic_operation {
([$($generics:tt)*] $ty:ty, { $($pat:pat => $target:expr),+ $(,)? }) => { ... };
($ty:ty, { $($pat:pat => $target:expr),+ $(,)? }) => { ... };
}Expand description
Implements AtomicOperation for a type by
delegating every method to an operation it holds.
A type that wraps or dispatches to another operation — a newtype over
&mut DbOp that seals off commit(), a restricted view handed to a
callback, an enum choosing between several ops — needs all of
AtomicOperation forwarded. Written by hand that is eight near-identical
bodies per type, and a method left out silently inherits a trait default:
maybe_now starts reporting None, supports_hooks false, or
savepoint_parts reports no hook
buffer while the wrapped op has one. The behaviour changes and nothing fails
to compile.
This macro generates the whole impl, so those cannot drift apart, and it adds
no public accessor — the wrapped operation stays as private as it was.
That matters for types that withhold &mut access on purpose: exposing it
would let a caller swap the operation out or commit it directly.
§Newtype
struct FlushOp<'a>(&'a mut es_entity::DbOp<'static>);
es_entity::delegate_atomic_operation!(FlushOp<'_>, { s => s.0 });§Enum
Each arm names a pattern and the operation to delegate to. Arms may hold
different types — DbOp, &mut DbOp, &mut SavepointOp — because the
generated code calls the method inside each arm rather than unifying the
arms into one value.
es_entity::delegate_atomic_operation!(UseCaseOp<'_, '_>, {
Self::Owned(op) => op,
Self::Db(op) => op,
Self::Savepoint(op) => op,
});§Generic types
Pass the impl generics in brackets first:
es_entity::delegate_atomic_operation!([<'a, T: es_entity::AtomicOperation>] MyOp<'a, T>, {
s => s.inner
});§When not to use it
Only for pure delegation. A wrapper that changes behaviour — reporting its own cached time, refusing hooks — must hand-write the impl, since this macro forwards every method.