use std::cmp::Eq;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::iter::FromIterator;
use super::Identity;
use super::Record;
use super::TemporaryIdAllocator;
pub enum Id<T>
where
T: ?Sized + Record,
{
New{
value: <T::Allocator as TemporaryIdAllocator>::Type,
},
Permanent {
value: <T::Allocator as TemporaryIdAllocator>::Type,
}
}
impl<T> Id<T>
where
T: ?Sized + Record,
{
pub fn is_new(&self) -> bool {
match self {
Id::New{..} => true,
Id::Permanent{..} => false
}
}
}
impl<T> Identity<T, <T::Allocator as TemporaryIdAllocator>::Type> for Id<T>
where
T: ?Sized + Record,
{
fn get_value(&self) -> <T::Allocator as TemporaryIdAllocator>::Type {
match self {
Id::New{value, ..} => *value,
Id::Permanent{value, ..} => *value,
}
}
}
impl<T> Clone for Id<T>
where
T: ?Sized + Record,
{
fn clone(&self) -> Self {
match self {
Id::New{value, ..} => Id::New{
value: *value,
},
Id::Permanent{value, ..} => Id::Permanent{
value: *value,
}
}
}
}
impl<T> Copy for Id<T>
where
T: ?Sized + Record,
{}
impl<T> fmt::Display for Id<T>
where
<T::Allocator as TemporaryIdAllocator>::Type: fmt::Display,
T: ?Sized + Record,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Id::New{value, ..} => value.fmt(f),
Id::Permanent{value, ..} => value.fmt(f),
}
}
}
impl<T> Id<T>
where
T: ?Sized + Record,
{
#[must_use]
pub fn new() -> Self {
Id::New {
value: T::Allocator::new_id(),
}
}
pub fn from(value: <T::Allocator as TemporaryIdAllocator>::Type) -> Self {
Id::Permanent {
value,
}
}
}
impl<T> Default for Id<T>
where
T: ?Sized + Record,
{
fn default() -> Self {
Id::new()
}
}
impl<T> PartialEq for Id<T>
where
T: ?Sized + Record,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Id::New{value: lhs, ..}, Id::New{value: rhs, ..}) => lhs.eq(rhs),
(Id::Permanent{value: lhs, ..}, Id::Permanent{value: rhs, ..}) => lhs.eq(rhs),
_ => false
}
}
}
impl<T> Eq for Id<T>
where
T: ?Sized + Record,
{}
impl<T>Hash for Id<T>
where
T: ?Sized + Record,
{
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Id::New{value, ..} => value.hash(state),
Id::Permanent{value, ..} => value.hash(state)
}
}
}
impl<T> fmt::Debug for Id<T>
where
<T::Allocator as TemporaryIdAllocator>::Type: fmt::Debug,
T: ?Sized + Record,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Id::New{value, ..} =>
f.debug_tuple("Id::New").field(value).finish(),
Id::Permanent{value, ..} =>
f.debug_tuple("Id::Permanent").field(value).finish(),
}
}
}
impl<T> FromIterator<&'static Id<T>> for HashSet<Id<T>>
where
T: 'static + ?Sized + Record,
{
fn from_iter<II: IntoIterator<Item = &'static Id<T>>>(iter: II) -> Self {
iter.into_iter().copied().collect()
}
}