From 8e5a53bc0df48894265199c488d25ba3ff7051da Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 12 Nov 2020 21:53:26 +0800 Subject: [PATCH] Implement Hash for Dynamic. --- src/ast.rs | 1 + src/dynamic.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index d99e6a74..1d5fbc70 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -836,6 +836,7 @@ pub struct FloatWrapper(pub FLOAT); impl Hash for FloatWrapper { #[inline(always)] fn hash(&self, state: &mut H) { + TypeId::of::().hash(state); state.write(&self.0.to_le_bytes()); } } diff --git a/src/dynamic.rs b/src/dynamic.rs index 6b3cc8b1..a66cc96b 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -21,6 +21,7 @@ use crate::stdlib::{ any::{type_name, Any, TypeId}, boxed::Box, fmt, + hash::{Hash, Hasher}, ops::{Deref, DerefMut}, string::{String, ToString}, }; @@ -361,6 +362,39 @@ impl Dynamic { } } +impl Hash for Dynamic { + fn hash(&self, state: &mut H) { + match &self.0 { + Union::Unit(_) => ().hash(state), + Union::Bool(value) => value.hash(state), + Union::Str(s) => s.hash(state), + Union::Char(ch) => ch.hash(state), + Union::Int(i) => i.hash(state), + #[cfg(not(feature = "no_float"))] + Union::Float(f) => { + TypeId::of::().hash(state); + state.write(&f.to_le_bytes()); + } + #[cfg(not(feature = "no_index"))] + Union::Array(a) => a.hash(state), + #[cfg(not(feature = "no_object"))] + Union::Map(m) => m.iter().for_each(|(key, item)| { + key.hash(state); + item.hash(state); + }), + + #[cfg(not(feature = "no_closure"))] + #[cfg(not(feature = "sync"))] + Union::Shared(cell) => (*cell.borrow()).hash(state), + #[cfg(not(feature = "no_closure"))] + #[cfg(feature = "sync")] + Union::Shared(cell) => (*cell.read().unwrap()).hash(hasher), + + _ => unimplemented!(), + } + } +} + /// Map the name of a standard type into a friendly form. #[inline] pub(crate) fn map_std_type_name(name: &str) -> &str {