Skip to main content

iced_core/widget/
id.rs

1use std::borrow;
2use std::sync::atomic::{self, AtomicUsize};
3
4static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
5
6/// The identifier of a generic widget.
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub struct Id(Internal);
9
10impl Id {
11    /// Creates a new [`Id`] from a static `str`.
12    pub const fn new(id: &'static str) -> Self {
13        Self(Internal::Custom(borrow::Cow::Borrowed(id)))
14    }
15
16    /// Creates a unique [`Id`].
17    ///
18    /// This function produces a different [`Id`] every time it is called.
19    pub fn unique() -> Self {
20        let id = NEXT_ID.fetch_add(1, atomic::Ordering::Relaxed);
21
22        Self(Internal::Unique(id))
23    }
24}
25
26impl std::fmt::Display for Id {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match &self.0 {
29            Internal::Unique(n) => write!(f, "__unique_{n}"),
30            Internal::Custom(name) => f.write_str(name),
31        }
32    }
33}
34
35impl From<&'static str> for Id {
36    fn from(value: &'static str) -> Self {
37        Self::new(value)
38    }
39}
40
41impl From<String> for Id {
42    fn from(value: String) -> Self {
43        Self(Internal::Custom(borrow::Cow::Owned(value)))
44    }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash)]
48enum Internal {
49    Unique(usize),
50    Custom(borrow::Cow<'static, str>),
51}
52
53#[cfg(test)]
54mod tests {
55    use super::Id;
56
57    #[test]
58    fn unique_generates_different_ids() {
59        let a = Id::unique();
60        let b = Id::unique();
61
62        assert_ne!(a, b);
63    }
64}