Skip to main content

rx_rust/utils/
id_generator.rs

1//! Ids handed out under a lock, to tell one thing apart from another that replaced it.
2//!
3//! Two shapes use this, and the difference lives in the caller, not in the id:
4//!
5//! - a *generation*, compared against [`IdGenerator::latest`] to tell whether something built with
6//!   the lock released is still the current one — see
7//!   [`SharedDisposal`](crate::disposable::shared_disposal::SharedDisposal) and
8//!   [`Switch`](crate::operators::combining::switch::Switch);
9//! - a *key*, identifying an entry of a collection — see
10//!   [`MergeAll`](crate::operators::combining::merge_all::MergeAll) and
11//!   [`PublishSubject`](crate::subject::publish_subject::PublishSubject).
12//!
13//! An [`Id`] can only come from an [`IdGenerator`], which never hands the same one out twice, so a
14//! holder of an id cannot forge one that collides with a later value.
15
16/// Hands out an [`Id`] that is never equal to any it handed out before.
17///
18/// It carries no lock of its own: it lives inside state that is already guarded, and
19/// [`next_id`](Self::next_id) takes `&mut self`.
20#[derive(Debug, Default)]
21pub struct IdGenerator(u64);
22
23/// An id handed out by an [`IdGenerator`].
24///
25/// There is deliberately no `Default`: an id can only be obtained from a generator, so it can
26/// never accidentally equal the value a generator starts from.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub struct Id(u64);
29
30impl IdGenerator {
31    /// The next id, greater than every id handed out before.
32    ///
33    /// `u64` is big enough that this never wraps on any platform.
34    #[must_use = "the id identifies what is being handed out, and is the only way to recognize it later"]
35    pub fn next_id(&mut self) -> Id {
36        self.0 += 1;
37        Id(self.0)
38    }
39
40    /// The id handed out last, or `None` before the first one.
41    pub fn latest(&self) -> Option<Id> {
42        (self.0 != 0).then_some(Id(self.0))
43    }
44}