Skip to main content

codex_protocol/
response_item_id.rs

1use std::fmt;
2use std::ops::Deref;
3
4use schemars::JsonSchema;
5use serde::Deserialize;
6use serde::Serialize;
7use ts_rs::TS;
8
9/// A Responses API item ID. New IDs require an explicit prefix; deserialization
10/// remains permissive so legacy rollouts can still be read.
11#[derive(
12    Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema, TS,
13)]
14#[serde(transparent)]
15#[schemars(with = "String")]
16#[ts(type = "string")]
17pub struct ResponseItemId(String);
18
19impl ResponseItemId {
20    pub fn new(prefix: &str) -> Self {
21        Self::with_suffix(prefix, uuid::Uuid::now_v7())
22    }
23
24    pub fn with_suffix(prefix: &str, suffix: impl fmt::Display) -> Self {
25        Self(format!("{prefix}_{suffix}"))
26    }
27
28    pub fn from_server(value: String) -> Self {
29        Self(value)
30    }
31
32    pub fn as_str(&self) -> &str {
33        &self.0
34    }
35
36    pub fn is_prefixed(&self) -> bool {
37        self.split_once('_')
38            .is_some_and(|(prefix, suffix)| !prefix.is_empty() && !suffix.is_empty())
39    }
40}
41
42impl Deref for ResponseItemId {
43    type Target = str;
44
45    fn deref(&self) -> &Self::Target {
46        self.as_str()
47    }
48}
49
50impl AsRef<str> for ResponseItemId {
51    fn as_ref(&self) -> &str {
52        self.as_str()
53    }
54}
55
56impl fmt::Display for ResponseItemId {
57    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58        formatter.write_str(self.as_str())
59    }
60}
61
62impl From<ResponseItemId> for String {
63    fn from(value: ResponseItemId) -> Self {
64        value.0
65    }
66}
67
68#[cfg(test)]
69#[path = "response_item_id_tests.rs"]
70mod tests;