devela/data/id/pin/mod.rs
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
// devela::data::id::pin
//
//!
//
#[cfg(feature = "alloc")]
mod r#box;
#[cfg(feature = "alloc")]
pub use r#box::IdPinBox;
use crate::{addr_of, Pin};
/// A unique identifier based on a pinned stack-allocated reference.
///
/// `IdPin` generates a unique ID by pinning a value on the stack,
/// ensuring that the ID is based on the stack memory address
/// for the lifetime of the reference.
///
/// It doesn't implement `Clone` or `Default`.
///
/// # Example
/// ```
/// # use devela::IdPin;
/// let mut data1: u8 = 0;
/// let id1 = IdPin::new(&mut data1);
/// ```
pub struct IdPin<'a> {
inner: Pin<&'a mut u8>,
}
impl<'a> IdPin<'a> {
/// Creates a new `IdPin` with a unique stack memory address.
///
/// Expects a mutable reference to a `u8` `data` that will be pinned.
pub fn new(data: &'a mut u8) -> Self {
let inner = Pin::new(data);
Self { inner }
}
/// Returns the unique ID as a `usize`, derived from the stack memory address.
pub fn as_usize(&self) -> usize {
addr_of!(*self.inner) as usize
}
}
mod impl_traits {
use crate::{impl_trait, IdPin, Ordering, Ptr};
impl_trait![fmt::Debug for IdPin<'a> |self, f| write!(f, "{}", self.as_usize())];
impl_trait![Hash for IdPin<'a> |self, s| self.as_usize().hash(s)];
impl PartialEq for IdPin<'_> {
fn eq(&self, other: &Self) -> bool {
Ptr::eq(&*self.inner, &*other.inner)
}
}
impl Eq for IdPin<'_> {}
impl PartialOrd for IdPin<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.as_usize().cmp(&other.as_usize()))
}
}
impl Ord for IdPin<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.as_usize().cmp(&other.as_usize())
}
}
}