codewhale_protocol/
ids.rs1use std::fmt;
14use std::str::FromStr;
15
16use serde::{Deserialize, Serialize};
17use uuid::Uuid;
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[serde(transparent)]
23pub struct ThreadId(pub String);
24
25impl ThreadId {
26 #[must_use]
27 pub fn new() -> Self {
28 Self(format!("thread-{}", Uuid::new_v4()))
29 }
30
31 #[must_use]
32 pub fn from_string(s: impl Into<String>) -> Self {
33 Self(s.into())
34 }
35
36 #[must_use]
37 pub fn as_str(&self) -> &str {
38 &self.0
39 }
40
41 #[must_use]
42 pub fn into_string(self) -> String {
43 self.0
44 }
45}
46
47impl Default for ThreadId {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl fmt::Display for ThreadId {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.write_str(&self.0)
56 }
57}
58
59impl From<String> for ThreadId {
60 fn from(s: String) -> Self {
61 Self(s)
62 }
63}
64
65impl From<ThreadId> for String {
66 fn from(id: ThreadId) -> Self {
67 id.0
68 }
69}
70
71impl FromStr for ThreadId {
72 type Err = std::convert::Infallible;
73 fn from_str(s: &str) -> Result<Self, Self::Err> {
74 Ok(Self(s.to_string()))
75 }
76}
77
78#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
83#[serde(transparent)]
84pub struct SessionId(pub String);
85
86impl SessionId {
87 #[must_use]
88 pub fn new() -> Self {
89 Self(format!("session-{}", Uuid::new_v4()))
90 }
91
92 #[must_use]
93 pub fn from_string(s: impl Into<String>) -> Self {
94 Self(s.into())
95 }
96
97 #[must_use]
98 pub fn as_str(&self) -> &str {
99 &self.0
100 }
101
102 #[must_use]
103 pub fn into_string(self) -> String {
104 self.0
105 }
106}
107
108impl Default for SessionId {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl fmt::Display for SessionId {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 f.write_str(&self.0)
117 }
118}
119
120impl From<String> for SessionId {
121 fn from(s: String) -> Self {
122 Self(s)
123 }
124}
125
126impl From<SessionId> for String {
127 fn from(id: SessionId) -> Self {
128 id.0
129 }
130}
131
132impl FromStr for SessionId {
133 type Err = std::convert::Infallible;
134 fn from_str(s: &str) -> Result<Self, Self::Err> {
135 Ok(Self(s.to_string()))
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn thread_id_roundtrip() {
145 let id = ThreadId::new();
146 let s = id.to_string();
147 assert!(s.starts_with("thread-"));
148 let parsed: ThreadId = s.parse().unwrap();
149 assert_eq!(parsed.as_str(), id.as_str());
150 }
151
152 #[test]
153 fn session_id_display() {
154 let id = SessionId::from_string("session-abc");
155 assert_eq!(format!("{id}"), "session-abc");
156 let json = serde_json::to_string(&id).unwrap();
157 assert_eq!(json, "\"session-abc\"");
158 let back: SessionId = serde_json::from_str(&json).unwrap();
159 assert_eq!(back, id);
160 }
161}