Skip to main content

ferroui_controls/pull_to_refresh/
refresh_completion_deferral.rs

1use std::cell::Cell;
2use std::rc::Rc;
3
4/// Deferral class for notify that a work done in RefreshRequested event is
5/// done.
6pub struct RefreshCompletionDeferral {
7    deferred_action: Option<Rc<dyn Fn()>>,
8    defer_count: Cell<i32>,
9}
10
11impl RefreshCompletionDeferral {
12    /// Creates a deferral that runs `deferred_action` when every deferral
13    /// taken with [`get`](Self::get) has been completed.
14    pub fn new(deferred_action: impl Fn() + 'static) -> Rc<Self> {
15        Self::from_action(Some(Rc::new(deferred_action)))
16    }
17
18    /// Creates a deferral for an action that may be absent.
19    pub fn from_action(deferred_action: Option<Rc<dyn Fn()>>) -> Rc<Self> {
20        Rc::new(Self { deferred_action, defer_count: Cell::new(0) })
21    }
22
23    pub fn complete(&self) {
24        self.defer_count.set(self.defer_count.get() - 1);
25
26        if self.defer_count.get() == 0 {
27            if let Some(deferred_action) = &self.deferred_action {
28                deferred_action();
29            }
30        }
31    }
32
33    pub fn get(self: &Rc<Self>) -> Rc<Self> {
34        self.defer_count.set(self.defer_count.get() + 1);
35
36        self.clone()
37    }
38}
39
40/// A deferral is a reference object: it compares by identity.
41impl PartialEq for RefreshCompletionDeferral {
42    fn eq(&self, other: &Self) -> bool {
43        std::ptr::eq(self, other)
44    }
45}