eventuary_core/
event_key.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::{Error, Result};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(try_from = "String", into = "String")]
9pub struct EventKey(String);
10
11impl EventKey {
12 pub fn new(s: impl Into<String>) -> Result<Self> {
13 let s = s.into();
14 if s.is_empty() {
15 return Err(Error::InvalidEventKey("must not be empty".into()));
16 }
17 if s.len() > 1024 {
18 return Err(Error::InvalidEventKey(
19 "event key must not exceed 1024 characters".into(),
20 ));
21 }
22 Ok(Self(s))
23 }
24
25 pub fn as_str(&self) -> &str {
26 &self.0
27 }
28}
29
30impl fmt::Display for EventKey {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(f, "{}", self.0)
33 }
34}
35
36impl TryFrom<String> for EventKey {
37 type Error = Error;
38 fn try_from(s: String) -> Result<Self> {
39 Self::new(s)
40 }
41}
42
43impl From<EventKey> for String {
44 fn from(k: EventKey) -> Self {
45 k.0
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn valid_key() {
55 assert!(EventKey::new("task-123").is_ok());
56 assert!(EventKey::new("agent-abc").is_ok());
57 assert!(EventKey::new("org/project/name").is_ok());
58 }
59
60 #[test]
61 fn empty_key_fails() {
62 assert!(EventKey::new("").is_err());
63 }
64
65 #[test]
66 fn too_long_key_fails() {
67 let s = "a".repeat(1025);
68 assert!(EventKey::new(s).is_err());
69 }
70}