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
use std::pin::Pin;

use hooks_core::HookPollNextUpdateExt;

use super::SharedStateEqData;

pub struct SharedStateEq<T: PartialEq>(Option<SharedStateEqData<T>>);

impl<T: PartialEq> SharedStateEq<T> {
    pub fn use_hook_with(
        self: Pin<&mut Self>,
        get_initial_state: impl FnOnce() -> T,
    ) -> &SharedStateEqData<T> {
        self.get_mut()
            .0
            .get_or_insert_with(|| SharedStateEqData::new(get_initial_state()))
    }
}

impl<T: PartialEq> Unpin for SharedStateEq<T> {}

pub struct SharedStateEqWith<T: PartialEq>(SharedStateEq<T>);

impl<T: PartialEq> Unpin for SharedStateEqWith<T> {}

crate::utils::impl_hook! {
    impl [T: PartialEq] for SharedStateEq<T> {
        #[inline]
        poll_next_update(self, cx) {
            self.get_mut().0.as_mut().map_or(
                ::core::task::Poll::Ready(true),
                |this| this.impl_poll_next_update(cx),
            )
        }

        #[inline]
        use_hook(self, initial_state: T) -> &'hook SharedStateEqData<T> {
            self.use_hook_with(move || initial_state)
        }
    }
}

crate::utils::impl_hook! {
    impl [T: PartialEq] for SharedStateEqWith<T> {
        #[inline]
        poll_next_update(self, cx) {
            self.get_mut().0.poll_next_update(cx)
        }

        #[inline]
        use_hook[F: FnOnce() -> T](self, get_initial_state: F) -> &'hook SharedStateEqData<T> {
            Pin::new(&mut self.get_mut().0).use_hook_with(get_initial_state)
        }
    }
}

#[inline]
pub fn use_shared_state_eq<T: PartialEq>() -> SharedStateEq<T> {
    SharedStateEq(None)
}

#[inline]
pub fn use_shared_state_eq_with<T: PartialEq>() -> SharedStateEqWith<T> {
    SharedStateEqWith(use_shared_state_eq())
}