Skip to main content

agent_rooms/
models.rs

1//! Parley data model — pure serde structs.
2//!
3//! Mirrors `parley/models/{room,message,participant,base}.py`. The Python
4//! version uses SQLAlchemy ORM types; this port carries only the in-memory
5//! / wire shapes since the Rust crate does not include the database layer.
6
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10/// Room status string per SPEC §5.1.
11pub const STATUS_OPEN: &str = "open";
12pub const STATUS_CLOSED: &str = "closed";
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub struct Room {
16    pub id: Uuid,
17    pub topic: String,
18    /// Bare hex of the creator's 32-byte Ed25519 pubkey.
19    pub creator_pubkey: String,
20    /// `"open"` or `"closed"`.
21    pub status: String,
22    pub turn_n: i64,
23    /// Bare hex; `None` once the room is closed.
24    pub turn_owner_pubkey: Option<String>,
25    pub max_turns: i64,
26    pub ttl_until: DateTime<Utc>,
27    pub closed_at: Option<DateTime<Utc>>,
28    pub closed_by_pubkey: Option<String>,
29    pub summary: Option<String>,
30    pub created_at: DateTime<Utc>,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub struct Participant {
35    pub room_id: Uuid,
36    pub agent_pubkey: String,
37    pub owner_pubkey: String,
38    pub invited_by_pubkey: String,
39    pub invited_at: DateTime<Utc>,
40    pub accepted_at: Option<DateTime<Utc>>,
41    /// Bare hex of the accept signature (128 chars); `None` until accepted.
42    pub accept_sig: Option<String>,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46pub struct Message {
47    pub id: Uuid,
48    pub room_id: Uuid,
49    pub author_pubkey: String,
50    pub turn_n: i64,
51    pub body: String,
52    /// Bare hex of the 64-byte Ed25519 signature (128 chars).
53    pub sig: String,
54    pub created_at: DateTime<Utc>,
55}
56
57/// Minimal UUID v4 string newtype so this module does not pull in the `uuid`
58/// crate. The protocol treats room/message IDs as opaque UUID-formatted
59/// strings (lowercase, hyphenated, 36 chars).
60mod uuid_compat {
61    use serde::{Deserialize, Serialize};
62
63    #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
64    #[serde(transparent)]
65    pub struct Uuid(pub String);
66
67    impl Uuid {
68        pub fn new(s: impl Into<String>) -> Self {
69            Self(s.into())
70        }
71
72        pub fn as_str(&self) -> &str {
73            &self.0
74        }
75    }
76
77    impl std::fmt::Display for Uuid {
78        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79            f.write_str(&self.0)
80        }
81    }
82
83    impl From<String> for Uuid {
84        fn from(s: String) -> Self {
85            Self(s)
86        }
87    }
88
89    impl From<&str> for Uuid {
90        fn from(s: &str) -> Self {
91            Self(s.to_string())
92        }
93    }
94}
95
96pub use uuid_compat::Uuid;