codex_protocol/
conversation_id.rs1use std::fmt::Display;
2
3use std::borrow::Cow;
4use schemars::{JsonSchema, SchemaGenerator};
5use serde::Deserialize;
6use serde::Serialize;
7use ts_rs::TS;
8use uuid::Uuid;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, TS, Hash)]
11#[ts(type = "string")]
12pub struct ConversationId {
13 uuid: Uuid,
14}
15
16impl ConversationId {
17 pub fn new() -> Self {
18 Self {
19 uuid: Uuid::now_v7(),
20 }
21 }
22
23 pub fn from_string(s: &str) -> Result<Self, uuid::Error> {
24 Ok(Self {
25 uuid: Uuid::parse_str(s)?,
26 })
27 }
28}
29
30impl Default for ConversationId {
31 fn default() -> Self {
32 Self::new()
33 }
34}
35
36impl Display for ConversationId {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "{}", self.uuid)
39 }
40}
41
42impl Serialize for ConversationId {
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: serde::Serializer,
46 {
47 serializer.collect_str(&self.uuid)
48 }
49}
50
51impl<'de> Deserialize<'de> for ConversationId {
52 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53 where
54 D: serde::Deserializer<'de>,
55 {
56 let value = String::deserialize(deserializer)?;
57 let uuid = Uuid::parse_str(&value).map_err(serde::de::Error::custom)?;
58 Ok(Self { uuid })
59 }
60}
61
62impl JsonSchema for ConversationId {
63 fn schema_name() -> Cow<'static, str> {
64 "ConversationId".into()
65 }
66
67 fn json_schema(generator: &mut SchemaGenerator) -> schemars::Schema {
68 <String>::json_schema(generator)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 #[test]
76 fn test_conversation_id_default_is_not_zeroes() {
77 let id = ConversationId::default();
78 assert_ne!(id.uuid, Uuid::nil());
79 }
80}