1use std::hash::{Hash, Hasher};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{Equality, MaybeEq};
6
7#[derive(Clone, Debug, Deserialize, Serialize, Eq)]
9pub enum Tracked<T> {
10 None,
12 Unknown,
14 Known(T),
16}
17
18impl<T> PartialEq for Tracked<T>
19where
20 T: PartialEq,
21{
22 fn eq(&self, other: &Self) -> bool {
23 match (self, other) {
24 (Self::None, Self::None) => true,
26
27 (Self::Known(t_self), Self::Known(t_other)) => t_self.eq(t_other),
29
30 (Self::Known(_), Self::None)
33 | (Self::None, Self::Known(_))
34 | (_, Self::Unknown)
35 | (Self::Unknown, _) => false,
36 }
37 }
38}
39
40impl<T> Hash for Tracked<T>
41where
42 T: Hash,
43{
44 fn hash<H: Hasher>(&self, state: &mut H) {
45 match self {
46 Self::None => 0.hash(state),
47 Self::Known(t) => t.hash(state),
48 Self::Unknown => 2.hash(state),
49 }
50 }
51}
52
53impl<T> MaybeEq for Tracked<T>
54where
55 T: MaybeEq,
56{
57 fn maybe_eq(&self, other: &Self) -> Equality {
58 match (self, other) {
59 (Self::None, Self::None) => Equality::Equal,
61
62 (Self::Known(t_self), Self::Known(t_other)) => t_self.maybe_eq(t_other),
64
65 (Self::Known(_), Self::None) | (Self::None, Self::Known(_)) => Equality::NotEqual,
67
68 (_, Self::Unknown) | (Self::Unknown, _) => Equality::Unknown,
70 }
71 }
72}