macro_rules! impl_hook {
(
// this empty generic helps with rustfmt
impl <$(__)?> $($rest:tt)*
) => { ... };
(
impl < $($generics_and_rest:tt)*
) => { ... };
(
impl $($rest:tt)*
) => { ... };
}
Expand description
Easily impl traits.
For example:
struct OutputOnce<T>(pub Option<T>);
impl_hook!(
impl<T: Unpin> OutputOnce<T> {
/// HookUnmount is implemented with default `fn unmount()`
fn unmount() {}
/// HookPollNextUpdate is implemented
fn poll_next_update(self, _cx: _) {
std::task::Poll::Ready(self.get_mut().0.is_some())
}
/// HookValue and Hook is implemented
/// HookValue::Value is `&'hook mut Option<T>`
#[inline]
fn use_hook(self) -> &'hook mut Option<T> {
&mut self.get_mut().0
}
}
);
§Just write the methods of the traits you want to impl in one impl block
impl_hook!(
impl<__> MyType { // <__> helps rustfmt to format this macro.
// write methods here
}
);
Generics and where clause are supported.
impl_hook!(
impl<'a, T: Clone + Default, F: FnMut(&T) -> T> MyType<'a, T, F>
where
T: Sized,
{
// write methods here
}
);
§Supported traits
impl HookUnmount
with unmount
HookUnmount
with unmount
With default implementation:
impl_hook!(
impl<__> MyType {
fn unmount() {}
}
);
With custom implementation:
impl_hook!(
impl<__> MyType {
fn unmount(self) {
self.do_something();
}
}
);
impl HookPollNextUpdate
with poll_next_update
HookPollNextUpdate
with poll_next_update
Argument cx
is of type &mut std::task::Context<'_>
.
The return type is std::task::Poll<bool>
impl_hook!(
impl<__> MyType {
fn poll_next_update(self, cx: _) {
self.project().inner.poll(cx)
}
}
);
Note that Hook
requires HookUnmount
+ HookPollNextUpdate
impl_hook!(
impl<__> MyType {
fn unmount() {}
fn poll_next_update(self, cx: _) { todo!() }
fn use_hook(self) -> MyValueType {
self.0
}
}
);
impl_hook!(
impl<__> UseMyHook {
fn into_hook(self) -> MyHook {
MyHook(self.0)
}
}
);
impl UpdateHook
with update_hook
UpdateHook
with update_hook
Note that UpdateHook
requires IntoHook
.
impl_hook!(
impl<__> UseMyHook {
fn into_hook(self) -> MyHook {
MyHook(self.0)
}
fn update_hook(self, mut hook: _) {
hook.0 = self.0
}
}
);
impl UpdateHookUninitialized
with h
UpdateHookUninitialized
with h
Note that UpdateHookUninitialized
requires UpdateHook
+ IntoHook
.
impl_hook!(
impl<__> UseMyHook {
fn into_hook(self) -> MyHook {
MyHook(self.0)
}
fn update_hook(self, mut hook: _) {
hook.0 = self.0
}
fn h(self, mut hook: MyHookUninitialized) {
hook.0.get_or_insert(self.0);
}
}
);