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
use std::fmt;
use std::hash::Hash;
use std::sync::atomic::{self, AtomicU64};

/// The id of the window.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Id(u64);

static COUNT: AtomicU64 = AtomicU64::new(1);

impl Id {
    /// No window will match this Id
    pub const NONE: Id = Id(0);
    pub const RESERVED: Id = Id(1);

    /// Creates a new unique window [`Id`].
    pub fn unique() -> Id {
        let id = Id(COUNT.fetch_add(1, atomic::Ordering::Relaxed));
        if id.0 == 0 {
            Id(COUNT.fetch_add(2, atomic::Ordering::Relaxed))
        } else if id.0 == 1 {
            Id(COUNT.fetch_add(1, atomic::Ordering::Relaxed))
        } else {
            id
        }
    }
}

impl fmt::Display for Id {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(f)
    }
}