hooks_core/ext/
next_value.rs

1use std::{future::Future, pin::Pin};
2
3use crate::{Hook, HookPollNextUpdate, HookValue};
4
5/// A future which outputs the next value of the hook.
6/// See [`HookExt::next_value`](crate::HookExt::next_value).
7#[must_use = "futures do nothing unless you `.await` or poll them"]
8pub struct NextValue<'hook, H: ?Sized> {
9    hook: Option<Pin<&'hook mut H>>,
10}
11
12impl<'hook, H: ?Sized> Unpin for NextValue<'hook, H> {}
13
14impl<'hook, H: ?Sized> NextValue<'hook, H> {
15    #[inline]
16    pub fn new(hook: Pin<&'hook mut H>) -> Self {
17        Self { hook: Some(hook) }
18    }
19}
20
21impl<'hook, H: ?Sized> Future for NextValue<'hook, H>
22where
23    H: Hook,
24{
25    type Output = Option<<H as HookValue<'hook>>::Value>;
26
27    #[inline]
28    fn poll(
29        self: Pin<&mut Self>,
30        cx: &mut std::task::Context<'_>,
31    ) -> std::task::Poll<Self::Output> {
32        let this = &mut self.get_mut().hook;
33        let hook = this
34            .as_mut()
35            .expect("NextValue should not be polled again after ready");
36        let hook = hook.as_mut();
37
38        <H as HookPollNextUpdate>::poll_next_update(hook, cx).map(|dynamic| {
39            let hook = this.take().unwrap();
40            if dynamic {
41                let value = <H as Hook>::use_hook(hook);
42                Some(value)
43            } else {
44                None
45            }
46        })
47    }
48}