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