Expand description
Forwarding by construction for Source and
Sink wrappers (RFC 0013, #877).
A wrapper (a decorator that holds an inner source or sink) must forward
every defaulted hook, or the hook silently reverts to its trait default for
everything behind the wrapper — exactly-once, upsert, the columnar fast
path, multi-table routing. forward_source! and
forward_sink! generate the forwarding body for
every hook, so a wrapper writes only the methods it changes and a hook
added to the trait later reaches the inner connector without touching the
wrapper.
Both macros are invoked inside the wrapper’s impl block (with or without
#[async_trait]):
forward_sink!(inner); // forward everything
forward_sink!(inner; except write_batch, flush); // the wrapper defines theseinner names the field holding the wrapped connector: any type whose
methods resolve to a Source/Sink (a Box<dyn Sink>, an Arc<S>, a
&'a S, a concrete connector), or a tuple index such as 0.
Every hook listed after except is left out: the wrapper either defines it
itself or deliberately takes the trait default. A name that is not a hook
of the trait is a compile error, and defining a hook without listing it is
a duplicate-definition error, so the list stays exact.
Forwarding is verbatim, including the convenience hooks whose default
delegates to another hook (fetch_all, stream_pages, check,
write_batch_partial, write_batch_idempotent, …). A wrapper that changes
a hook must also list the hooks that should go through its change rather
than straight to the inner connector — a sink that rewrites records in
write_batch lists write_batch_partial, write_batch_idempotent,
write_batch_columnar and load_native too. faucet-conformance’s
assert_source_forwards_every_hook / assert_sink_forwards_every_hook
check the result.