Skip to main content

weavatrix_memory/
id.rs

1use crate::{MemoryError, Result};
2use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _};
3use std::{fmt, str::FromStr, sync::Arc};
4
5macro_rules! text_id {
6    ($name:ident, $kind:literal) => {
7        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8        pub struct $name(Arc<str>);
9
10        impl $name {
11            /// Creates a stable, non-empty identifier.
12            ///
13            /// # Errors
14            ///
15            /// Rejects empty identifiers and surrounding whitespace.
16            pub fn new(value: impl Into<String>) -> Result<Self> {
17                let value = value.into();
18                if value.is_empty() || value.trim() != value {
19                    return Err(MemoryError::InvalidId { kind: $kind, value });
20                }
21                Ok(Self(value.into()))
22            }
23
24            #[must_use]
25            pub fn as_str(&self) -> &str {
26                &self.0
27            }
28
29            #[must_use]
30            pub fn into_inner(self) -> String {
31                self.0.to_string()
32            }
33        }
34
35        impl fmt::Display for $name {
36            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37                formatter.write_str(&self.0)
38            }
39        }
40
41        impl FromStr for $name {
42            type Err = MemoryError;
43
44            fn from_str(value: &str) -> Result<Self> {
45                Self::new(value)
46            }
47        }
48
49        impl Serialize for $name {
50            fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
51            where
52                S: Serializer,
53            {
54                serializer.serialize_str(&self.0)
55            }
56        }
57
58        impl<'de> Deserialize<'de> for $name {
59            fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
60            where
61                D: Deserializer<'de>,
62            {
63                let value = String::deserialize(deserializer)?;
64                Self::new(value).map_err(D::Error::custom)
65            }
66        }
67    };
68}
69
70text_id!(EventId, "event");
71text_id!(StreamId, "stream");
72text_id!(EntityId, "entity");
73text_id!(FactId, "fact");
74text_id!(AgentId, "agent");
75text_id!(SessionId, "session");