1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::Hook;
pub trait GetArgsForHook<R: ?Sized, H: Hook<Args> + ?Sized, Args> {
fn get_args_for_hook(&mut self, runner: &mut R, hook: &mut H) -> Args;
}
impl<F, R: ?Sized, H: Hook<Args> + ?Sized, Args> GetArgsForHook<R, H, Args> for F
where
F: ?Sized + FnMut(&mut R, &mut H) -> Args,
{
#[inline]
fn get_args_for_hook(&mut self, runner: &mut R, hook: &mut H) -> Args {
self(runner, hook)
}
}
pub struct CloneArgsForHook<Args: Clone>(pub Args);
impl<R: ?Sized, H: Hook<Args> + ?Sized, Args: Clone> GetArgsForHook<R, H, Args>
for CloneArgsForHook<Args>
{
#[inline]
fn get_args_for_hook(&mut self, _runner: &mut R, _hook: &mut H) -> Args {
self.0.clone()
}
}
pub struct DefaultArgsForHook;
impl<R: ?Sized, H: Hook<Args> + ?Sized, Args: Default> GetArgsForHook<R, H, Args>
for DefaultArgsForHook
{
#[inline]
fn get_args_for_hook(&mut self, _runner: &mut R, _hook: &mut H) -> Args {
Args::default()
}
}
pub trait RunHook<H: Hook<Args>, G: GetArgsForHook<Self, H, Args>, Args> {
type RunningHook;
fn run_hook(self, hook: H, get_args: G) -> Self::RunningHook;
}
pub mod default_runner {
use std::{
future::Future,
marker::PhantomData,
pin::Pin,
task::{Context, Poll},
};
use super::GetArgsForHook;
use crate::{Hook, HookExt, HookLifetime, HookPollNextUpdateExt};
#[derive(Debug, Default, Clone, Copy)]
pub struct Runner;
pub struct RunningHook<H, G, Args> {
hook: H,
get_args: G,
args: PhantomData<Args>,
}
pub struct RunningHookNextValue<'hook, H, G, Args> {
running_hook: Option<&'hook mut RunningHook<H, G, Args>>,
}
impl<'hook, H, G, Args> Future for RunningHookNextValue<'hook, H, G, Args>
where
H: Hook<Args> + Unpin,
G: GetArgsForHook<Runner, H, Args>,
{
type Output = Option<<H as HookLifetime<'hook, Args>>::Value>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let running_hook = this.running_hook.as_mut().unwrap();
match HookPollNextUpdateExt::poll_next_update(&mut running_hook.hook, cx) {
Poll::Ready(dynamic) => {
if dynamic {
let running_hook = this.running_hook.take().unwrap();
let args = running_hook
.get_args
.get_args_for_hook(&mut Runner, &mut running_hook.hook);
let v = running_hook.hook.use_hook(args);
Poll::Ready(Some(v))
} else {
Poll::Ready(None)
}
}
Poll::Pending => Poll::Pending,
}
}
}
impl<H: Hook<Args>, G, Args> RunningHook<H, G, Args> {
pub fn next_value(&mut self) -> RunningHookNextValue<'_, H, G, Args> {
RunningHookNextValue {
running_hook: Some(self),
}
}
}
impl<H: Hook<Args>, G: GetArgsForHook<Self, H, Args>, Args> super::RunHook<H, G, Args> for Runner {
type RunningHook = RunningHook<H, G, Args>;
fn run_hook(self, hook: H, get_args: G) -> Self::RunningHook {
RunningHook {
hook,
get_args,
args: PhantomData,
}
}
}
}