Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2020-02-12T21:45:56-08:00

====== FunStuff ======

===== Dynamic Hash Map Keys =====
{{{code: lang="rust" linenumbers="True"
pub mod dynhash {
	use std::any::Any;
	use std::hash::{Hash, Hasher};

	pub trait DynEq: Any {
		fn dyn_eq(&self, other: &dyn DynEq) -> bool;

		fn as_any(&self) -> &dyn Any;
	}

	pub trait DynHash: DynEq {
		fn dyn_hash(&self, hasher: &mut dyn Hasher);

		fn as_dyn_eq(&self) -> &dyn DynEq;
	}

	impl<H: Eq + Any> DynEq for H {
		fn dyn_eq(&self, other: &dyn DynEq) -> bool {
			if let Some(other) = other.as_any().downcast_ref::<H>() {
				self == other
			} else {
				false
			}
		}

		fn as_any(&self) -> &dyn Any {
			self
		}
	}

	impl<H: Hash + DynEq> DynHash for H {
		fn dyn_hash(&self, mut hasher: &mut dyn Hasher) {
			H::hash(self, &mut hasher)
		}

		fn as_dyn_eq(&self) -> &dyn DynEq {
			self
		}
	}

	impl PartialEq for dyn DynHash {
		fn eq(&self, other: &dyn DynHash) -> bool {
			self.dyn_eq(other.as_dyn_eq())
		}
	}

	impl Eq for dyn DynHash {}

	impl Hash for dyn DynHash {
		fn hash<H: Hasher>(&self, hasher: &mut H) {
			self.dyn_hash(hasher)
		}
	}
}
}}}
