1use crate::HasHash;
2use crate::HashableContent;
3use crate::HoloHashOf;
4#[cfg(feature = "serialization")]
5use holochain_serialized_bytes::prelude::*;
6
7#[cfg_attr(feature = "serialization", derive(Debug, Serialize, Deserialize))]
12pub struct HoloHashed<C: HashableContent> {
13 pub content: C,
15 pub hash: HoloHashOf<C>,
17}
18
19impl<C: HashableContent> HasHash for HoloHashed<C> {
20 type HashType = C::HashType;
21
22 fn as_hash(&self) -> &HoloHashOf<C> {
23 &self.hash
24 }
25
26 fn into_hash(self) -> HoloHashOf<C> {
27 self.hash
28 }
29}
30
31impl<C> HoloHashed<C>
32where
33 C: HashableContent,
34{
35 pub fn with_pre_hashed(content: C, hash: HoloHashOf<C>) -> Self {
37 Self { content, hash }
38 }
39
40 pub fn as_content(&self) -> &C {
44 &self.content
45 }
46
47 #[cfg(feature = "test_utils")]
51 pub fn as_content_mut(&mut self) -> &mut C {
52 &mut self.content
53 }
54
55 pub fn into_content(self) -> C {
57 self.content
58 }
59
60 pub fn into_inner(self) -> (C, HoloHashOf<C>) {
62 (self.content, self.hash)
63 }
64
65 #[cfg(feature = "test_utils")]
67 pub fn downcast<D>(&self) -> HoloHashed<D>
68 where
69 C: Clone,
70 C::HashType: crate::hash_type::HashTypeSync,
71 D: HashableContent<HashType = C::HashType> + From<C>,
72 {
73 let old_hash = &self.hash;
74 let content: D = self.content.clone().into();
75 let hashed = HoloHashed::from_content_sync_exact(content);
76 assert_eq!(&hashed.hash, old_hash);
77 hashed
78 }
79}
80
81impl<C> Clone for HoloHashed<C>
82where
83 C: HashableContent + Clone,
84{
85 fn clone(&self) -> Self {
86 Self {
87 content: self.content.clone(),
88 hash: self.hash.clone(),
89 }
90 }
91}
92
93impl<C> std::convert::From<HoloHashed<C>> for (C, HoloHashOf<C>)
94where
95 C: HashableContent,
96{
97 fn from(g: HoloHashed<C>) -> (C, HoloHashOf<C>) {
98 g.into_inner()
99 }
100}
101
102impl<C> std::ops::Deref for HoloHashed<C>
103where
104 C: HashableContent,
105{
106 type Target = C;
107
108 fn deref(&self) -> &Self::Target {
109 self.as_content()
110 }
111}
112
113impl<C> std::convert::AsRef<C> for HoloHashed<C>
114where
115 C: HashableContent,
116{
117 fn as_ref(&self) -> &C {
118 self.as_content()
119 }
120}
121
122impl<C> std::borrow::Borrow<C> for HoloHashed<C>
123where
124 C: HashableContent,
125{
126 fn borrow(&self) -> &C {
127 self.as_content()
128 }
129}
130
131impl<C> std::cmp::PartialEq for HoloHashed<C>
132where
133 C: HashableContent,
134{
135 fn eq(&self, other: &Self) -> bool {
136 self.hash == other.hash
137 }
138}
139
140impl<C> std::cmp::Eq for HoloHashed<C> where C: HashableContent {}
141
142impl<C> std::hash::Hash for HoloHashed<C>
143where
144 C: HashableContent,
145{
146 fn hash<StdH: std::hash::Hasher>(&self, state: &mut StdH) {
147 std::hash::Hash::hash(&self.hash, state)
148 }
149}
150
151impl<C> std::cmp::PartialOrd for HoloHashed<C>
152where
153 C: HashableContent + PartialOrd,
154{
155 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
156 self.content.partial_cmp(&other.content)
157 }
158}
159
160impl<C> std::cmp::Ord for HoloHashed<C>
161where
162 C: HashableContent + Ord,
163{
164 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
165 self.content.cmp(&other.content)
166 }
167}
168
169impl<C: HashableContent> HashableContent for HoloHashed<C> {
170 type HashType = C::HashType;
171
172 fn hash_type(&self) -> Self::HashType {
173 C::hash_type(self)
174 }
175
176 fn hashable_content(&self) -> crate::HashableContentBytes {
177 crate::HashableContentBytes::Prehashed39(self.as_hash().get_raw_39().to_vec())
178 }
179}