1use crate::account_address::AccountAddress;
9use hex::FromHex;
10#[cfg(any(test, feature = "fuzzing"))]
11use rand::{rngs::OsRng, RngCore};
12use serde::{de, ser, Deserialize, Serialize};
13use std::{
14 convert::{TryFrom, TryInto},
15 fmt,
16 str::FromStr,
17};
18
19#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
23pub struct EventKey([u8; EventKey::LENGTH]);
24
25#[cfg(any(test, feature = "fuzzing"))]
26use proptest::prelude::*;
27
28#[cfg(any(test, feature = "fuzzing"))]
29impl proptest::arbitrary::Arbitrary for EventKey {
30 type Parameters = ();
31 type Strategy = BoxedStrategy<Self>;
32
33 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
34 any::<u8>().prop_map(|_seed| EventKey::random()).boxed()
35 }
36}
37
38impl EventKey {
39 pub const LENGTH: usize = AccountAddress::LENGTH + 8;
41
42 pub fn new(key: [u8; Self::LENGTH]) -> Self { EventKey(key) }
44
45 pub fn as_bytes(&self) -> &[u8] { &self.0 }
47
48 pub fn to_vec(&self) -> Vec<u8> { self.0.to_vec() }
50
51 pub fn get_creator_address(&self) -> AccountAddress {
53 AccountAddress::try_from(
54 &self.0[EventKey::LENGTH - AccountAddress::LENGTH..],
55 )
56 .expect("get_creator_address failed")
57 }
58
59 pub fn get_creation_number(&self) -> u64 {
62 u64::from_le_bytes(self.0[0..8].try_into().unwrap())
63 }
64
65 #[cfg(any(test, feature = "fuzzing"))]
66 pub fn random() -> Self {
68 let mut rng = OsRng;
69 let salt = rng.next_u64();
70 EventKey::new_from_address(&AccountAddress::random(), salt)
71 }
72
73 pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
75 let mut output_bytes = [0; Self::LENGTH];
76 let (lhs, rhs) = output_bytes.split_at_mut(8);
77 lhs.copy_from_slice(&salt.to_le_bytes());
78 rhs.copy_from_slice(addr.as_ref());
79 EventKey(output_bytes)
80 }
81
82 pub fn from_hex<T: AsRef<[u8]>>(
83 hex: T,
84 ) -> Result<Self, EventKeyParseError> {
85 <[u8; Self::LENGTH]>::from_hex(hex)
86 .map_err(|_| EventKeyParseError)
87 .map(Self)
88 }
89
90 pub fn from_bytes<T: AsRef<[u8]>>(
91 bytes: T,
92 ) -> Result<Self, EventKeyParseError> {
93 <[u8; Self::LENGTH]>::try_from(bytes.as_ref())
94 .map_err(|_| EventKeyParseError)
95 .map(Self)
96 }
97}
98
99impl FromStr for EventKey {
100 type Err = EventKeyParseError;
101
102 fn from_str(s: &str) -> Result<Self, EventKeyParseError> {
103 EventKey::from_hex(s)
104 }
105}
106
107impl From<EventKey> for [u8; EventKey::LENGTH] {
108 fn from(event_key: EventKey) -> Self { event_key.0 }
109}
110
111impl From<&EventKey> for [u8; EventKey::LENGTH] {
112 fn from(event_key: &EventKey) -> Self { event_key.0 }
113}
114
115impl ser::Serialize for EventKey {
116 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
117 where S: ser::Serializer {
118 if serializer.is_human_readable() {
119 self.to_string().serialize(serializer)
120 } else {
121 serializer.serialize_newtype_struct(
125 "EventKey",
126 serde_bytes::Bytes::new(&self.0),
127 )
128 }
129 }
130}
131
132impl<'de> de::Deserialize<'de> for EventKey {
133 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
134 where D: de::Deserializer<'de> {
135 use serde::de::Error;
136
137 if deserializer.is_human_readable() {
138 let s = <String>::deserialize(deserializer)?;
139 EventKey::from_hex(s).map_err(D::Error::custom)
140 } else {
141 #[derive(::serde::Deserialize)]
143 #[serde(rename = "EventKey")]
144 struct Value<'a>(&'a [u8]);
145
146 let value = Value::deserialize(deserializer)?;
147 Self::try_from(value.0).map_err(D::Error::custom)
148 }
149 }
150}
151
152impl TryFrom<&[u8]> for EventKey {
153 type Error = EventKeyParseError;
154
155 fn try_from(bytes: &[u8]) -> Result<EventKey, EventKeyParseError> {
157 Self::from_bytes(bytes)
158 }
159}
160
161#[derive(Clone, Copy, Debug)]
162pub struct EventKeyParseError;
163
164impl fmt::Display for EventKeyParseError {
165 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
166 write!(f, "unable to parse EventKey")
167 }
168}
169
170impl std::error::Error for EventKeyParseError {}
171
172#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
174pub struct EventHandle {
175 count: u64,
177 key: EventKey,
180}
181
182impl EventHandle {
183 pub fn new(key: EventKey, count: u64) -> Self { EventHandle { key, count } }
185
186 pub fn key(&self) -> &EventKey { &self.key }
188
189 pub fn count(&self) -> u64 { self.count }
191
192 #[cfg(any(test, feature = "fuzzing"))]
193 pub fn count_mut(&mut self) -> &mut u64 { &mut self.count }
194
195 #[cfg(any(test, feature = "fuzzing"))]
196 pub fn random_handle(count: u64) -> Self {
198 Self {
199 key: EventKey::random(),
200 count,
201 }
202 }
203
204 #[cfg(any(test, feature = "fuzzing"))]
205 pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
207 Self {
208 key: EventKey::new_from_address(addr, salt),
209 count: 0,
210 }
211 }
212}
213
214impl fmt::LowerHex for EventKey {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 if f.alternate() {
217 write!(f, "0x")?;
218 }
219
220 for byte in &self.0 {
221 write!(f, "{:02x}", byte)?;
222 }
223
224 Ok(())
225 }
226}
227
228impl fmt::Display for EventKey {
229 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
230 write!(f, "{:x}", self)
231 }
232}
233
234#[cfg(test)]
235mod tests {
236 use super::EventKey;
237
238 #[test]
239 fn test_display_impls() {
240 let hex = "100000000000000000000000000000000000000000000000ca843279e3427144cead5e4d5999a3d0";
241
242 let key = EventKey::from_hex(hex).unwrap();
243
244 assert_eq!(format!("{}", key), hex);
245 assert_eq!(format!("{:x}", key), hex);
246
247 assert_eq!(format!("{:#x}", key), format!("0x{}", hex));
248 }
249
250 #[test]
251 fn test_invalid_length() {
252 let bytes = vec![1; 123];
253 EventKey::from_bytes(bytes).unwrap_err();
254 }
255
256 #[test]
257 fn test_deserialize_from_json_value() {
258 let key = EventKey::random();
259 let json_value = serde_json::to_value(key).unwrap();
260 let key2: EventKey = serde_json::from_value(json_value).unwrap();
261 assert_eq!(key, key2);
262 }
263
264 #[test]
265 fn test_serde_json() {
266 let hex = "100000000000000000000000000000000000000000000000ca843279e3427144cead5e4d5999a3d0";
267 let json_hex = "\"100000000000000000000000000000000000000000000000ca843279e3427144cead5e4d5999a3d0\"";
268
269 let key = EventKey::from_hex(hex).unwrap();
270
271 let json = serde_json::to_string(&key).unwrap();
272 let json_key: EventKey = serde_json::from_str(json_hex).unwrap();
273
274 assert_eq!(json, json_hex);
275 assert_eq!(key, json_key);
276 }
277}