use std::hash::{Hash, Hasher};
use serde::{Deserialize, Serialize};
use crate::{Equality, MaybeEq};
#[derive(Clone, Debug, Deserialize, Serialize, Eq)]
pub enum Tracked<T> {
None,
Unknown,
Known(T),
}
impl<T> PartialEq for Tracked<T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::None, Self::None) => true,
(Self::Known(t_self), Self::Known(t_other)) => t_self.eq(t_other),
(Self::Known(_), Self::None)
| (Self::None, Self::Known(_))
| (_, Self::Unknown)
| (Self::Unknown, _) => false,
}
}
}
impl<T> Hash for Tracked<T>
where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Self::None => 0.hash(state),
Self::Known(t) => t.hash(state),
Self::Unknown => 2.hash(state),
}
}
}
impl<T> MaybeEq for Tracked<T>
where
T: MaybeEq,
{
fn maybe_eq(&self, other: &Self) -> Equality {
match (self, other) {
(Self::None, Self::None) => Equality::Equal,
(Self::Known(t_self), Self::Known(t_other)) => t_self.maybe_eq(t_other),
(Self::Known(_), Self::None) | (Self::None, Self::Known(_)) => Equality::NotEqual,
(_, Self::Unknown) | (Self::Unknown, _) => Equality::Unknown,
}
}
}