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 71 72
//! Helper traits for Id.
use super::{Id, Owned, Ownership};
use crate::Message;
/// Helper trait for functionality on slices containing [`Id`]s.
pub trait SliceId {
/// The type of the items in the slice.
type Item: ?Sized;
/// Convert a slice of [`Id`]s into a slice of references.
fn as_slice_ref(&self) -> &[&Self::Item];
/// Convert a mutable slice of [`Id`]s into a mutable slice of references.
fn as_slice_mut(&mut self) -> &mut [&Self::Item];
}
/// Helper trait for functionality on slices containing owned [`Id`]s.
pub trait SliceIdMut: SliceId {
/// Convert a mutable slice of mutable [`Id`]s into a mutable slice of
/// mutable references.
fn as_mut_slice_mut(&mut self) -> &mut [&mut Self::Item];
}
impl<T: Message + ?Sized, O: Ownership> SliceId for [Id<T, O>] {
type Item = T;
fn as_slice_ref(&self) -> &[&T] {
let ptr = self as *const Self as *const [&T];
// SAFETY: Id<T, O> and &T have the same memory layout. Further safety
// follows from `Deref` impl.
unsafe { ptr.as_ref().unwrap_unchecked() }
}
fn as_slice_mut(&mut self) -> &mut [&T] {
let ptr = self as *mut Self as *mut [&T];
// SAFETY: Id<T, O> and &T have the same memory layout. Further safety
// follows from `Deref` impl.
unsafe { ptr.as_mut().unwrap_unchecked() }
}
}
impl<T: Message + ?Sized> SliceIdMut for [Id<T, Owned>] {
fn as_mut_slice_mut(&mut self) -> &mut [&mut T] {
let ptr = self as *mut Self as *mut [&mut T];
// SAFETY: Id<T, O> and &mut T have the same memory layout, and the
// `Id` is `Owned` so we're allowed to hand out mutable references.
// Further safety follows from `DerefMut` impl.
unsafe { ptr.as_mut().unwrap_unchecked() }
}
}
/// Helper trait to implement [`Default`] on types whoose default value is an
/// [`Id`].
// TODO: Maybe make this `unsafe` and provide a default implementation?
pub trait DefaultId {
/// Indicates whether the default value is mutable or immutable.
type Ownership: Ownership;
/// The default [`Id`] for a type.
///
/// On most objects the implementation would just be sending a message to
/// the `new` selector.
fn default_id() -> Id<Self, Self::Ownership>;
}
impl<T: DefaultId + ?Sized> Default for Id<T, T::Ownership> {
#[inline]
fn default() -> Self {
T::default_id()
}
}