Skip to main content

mempill_types/
identity.rs

1//! Identity types: opaque, stable identifiers used as primary keys and partition keys.
2
3/// Opaque stable identifier for a memory agent. Primary partition key everywhere.
4#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
5#[serde(transparent)]
6pub struct AgentId(pub String);
7
8/// Opaque, stable, immutable identity of a committed claim. Minted once at injection time.
9#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
10#[serde(transparent)]
11pub struct ClaimRef(pub uuid::Uuid);
12
13impl ClaimRef {
14    /// Mint a new random ClaimRef.
15    pub fn new_random() -> Self {
16        Self(uuid::Uuid::new_v4())
17    }
18}
19
20/// Compound key identifying the (agent_id, subject, predicate) subject-line.
21#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
22pub struct SubjectLineRef {
23    /// The agent that owns this subject-line.
24    pub agent_id: AgentId,
25    /// The entity being described.
26    pub subject: String,
27    /// The aspect being asserted.
28    pub predicate: String,
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn agent_id_equality() {
37        let a = AgentId("agent-1".into());
38        let b = AgentId("agent-1".into());
39        assert_eq!(a, b);
40    }
41
42    #[test]
43    fn claim_ref_new_random_is_unique() {
44        let r1 = ClaimRef::new_random();
45        let r2 = ClaimRef::new_random();
46        assert_ne!(r1, r2);
47    }
48
49    #[test]
50    fn claim_ref_round_trip_serde() {
51        let r = ClaimRef::new_random();
52        let json = serde_json::to_string(&r).unwrap();
53        let back: ClaimRef = serde_json::from_str(&json).unwrap();
54        assert_eq!(r, back);
55    }
56
57    #[test]
58    fn claim_ref_serializes_as_bare_uuid_string() {
59        let uuid = uuid::Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
60        let r = ClaimRef(uuid);
61        let json = serde_json::to_string(&r).unwrap();
62        assert_eq!(json, r#""550e8400-e29b-41d4-a716-446655440000""#);
63        let back: ClaimRef = serde_json::from_str(&json).unwrap();
64        assert_eq!(r, back);
65    }
66
67    #[test]
68    fn agent_id_serializes_as_bare_string() {
69        let id = AgentId("my-agent".into());
70        let json = serde_json::to_string(&id).unwrap();
71        assert_eq!(json, r#""my-agent""#);
72        let back: AgentId = serde_json::from_str(&json).unwrap();
73        assert_eq!(id, back);
74    }
75
76    #[test]
77    fn subject_line_ref_equality() {
78        let s1 = SubjectLineRef {
79            agent_id: AgentId("a".into()),
80            subject: "user".into(),
81            predicate: "name".into(),
82        };
83        let s2 = s1.clone();
84        assert_eq!(s1, s2);
85    }
86}