read_write_store/
id.rs

1//! An opaque handle used to read, modify or remove an element from an [RwStore](crate::RwStore)
2//! once it has been inserted.
3//!
4//! When debug assertions are enabled, IDs will consume more memory to track the store that created
5//! them.
6//!
7//! # Example
8//!
9//! ```
10//! # use read_write_store::RwStore;
11//! let store = RwStore::new();
12//! let id_a = store.insert(42);
13//! let id_b = store.insert(42);
14//! ```
15
16use std::fmt;
17use std::fmt::{Debug, Formatter};
18use std::ptr::NonNull;
19
20use crate::rwstore_id::RwStoreId;
21
22/// An opaque handle used to read, modify or remove an element from an [RwStore](crate::RwStore)
23/// once it has been inserted. See the [module-level documentation](crate::id) for more.
24#[derive(Copy, Clone)]
25pub struct Id {
26    ordinal: u32,
27    slot_address: NonNull<()>,
28    store_id: RwStoreId,
29}
30
31impl Id {
32    pub(crate) fn new<T>(ordinal: u32, slot: &T, store_id: RwStoreId) -> Self {
33        Self {
34            ordinal,
35            slot_address: NonNull::from(slot).cast(),
36            store_id,
37        }
38    }
39
40    pub(crate) fn ordinal(&self) -> u32 {
41        self.ordinal
42    }
43
44    pub(crate) fn slot<T>(&self) -> NonNull<T> {
45        self.slot_address.cast()
46    }
47
48    pub(crate) fn store_id(&self) -> RwStoreId {
49        self.store_id
50    }
51}
52
53impl Debug for Id {
54    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
55        f.debug_struct("Id")
56            .field("id", &self.ordinal)
57            .field("address", &self.slot_address)
58            .finish()
59    }
60}
61
62unsafe impl Send for Id {}
63
64unsafe impl Sync for Id {}
65
66#[cfg(test)]
67mod test {
68    use std::panic::{RefUnwindSafe, UnwindSafe};
69
70    use crate::RwStore;
71
72    #[test]
73    fn implements_sync() {
74        let store = RwStore::new();
75        let id = store.insert(0);
76        &id as &dyn Sync;
77    }
78
79    #[test]
80    fn implements_send() {
81        let store = RwStore::new();
82        let id = store.insert(0);
83        &id as &dyn Send;
84    }
85
86    #[test]
87    fn implements_unwind_safe() {
88        let store = RwStore::new();
89        let id = store.insert(0);
90        &id as &dyn UnwindSafe;
91    }
92
93    #[test]
94    fn implements_ref_unwind_safe() {
95        let store = RwStore::new();
96        let id = store.insert(0);
97        &id as &dyn RefUnwindSafe;
98    }
99}