systemprompt_identifiers/
agent.rs

1//! Agent identifier types.
2
3use crate::error::IdValidationError;
4use crate::{DbValue, ToDbValue};
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
10#[cfg_attr(feature = "sqlx", sqlx(transparent))]
11#[serde(transparent)]
12pub struct AgentId(String);
13
14impl AgentId {
15    pub fn new(id: impl Into<String>) -> Self {
16        Self(id.into())
17    }
18
19    pub fn generate() -> Self {
20        Self(uuid::Uuid::new_v4().to_string())
21    }
22
23    pub fn as_str(&self) -> &str {
24        &self.0
25    }
26}
27
28impl fmt::Display for AgentId {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        write!(f, "{}", self.0)
31    }
32}
33
34impl From<String> for AgentId {
35    fn from(s: String) -> Self {
36        Self(s)
37    }
38}
39
40impl From<&str> for AgentId {
41    fn from(s: &str) -> Self {
42        Self(s.to_string())
43    }
44}
45
46impl AsRef<str> for AgentId {
47    fn as_ref(&self) -> &str {
48        &self.0
49    }
50}
51
52impl ToDbValue for AgentId {
53    fn to_db_value(&self) -> DbValue {
54        DbValue::String(self.0.clone())
55    }
56}
57
58impl ToDbValue for &AgentId {
59    fn to_db_value(&self) -> DbValue {
60        DbValue::String(self.0.clone())
61    }
62}
63
64impl From<AgentId> for String {
65    fn from(id: AgentId) -> Self {
66        id.0
67    }
68}
69
70impl From<&AgentId> for String {
71    fn from(id: &AgentId) -> Self {
72        id.0.clone()
73    }
74}
75
76impl PartialEq<&str> for AgentId {
77    fn eq(&self, other: &&str) -> bool {
78        self.0 == *other
79    }
80}
81
82impl PartialEq<str> for AgentId {
83    fn eq(&self, other: &str) -> bool {
84        self.0 == other
85    }
86}
87
88impl std::borrow::Borrow<str> for AgentId {
89    fn borrow(&self) -> &str {
90        &self.0
91    }
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
95#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
96#[cfg_attr(feature = "sqlx", sqlx(transparent))]
97#[serde(transparent)]
98pub struct AgentName(String);
99
100impl AgentName {
101    pub fn try_new(name: impl Into<String>) -> Result<Self, IdValidationError> {
102        let name = name.into();
103        if name.is_empty() {
104            return Err(IdValidationError::empty("AgentName"));
105        }
106        if name.eq_ignore_ascii_case("unknown") {
107            return Err(IdValidationError::invalid(
108                "AgentName",
109                "'unknown' is reserved for error detection",
110            ));
111        }
112        Ok(Self(name))
113    }
114
115    #[allow(clippy::expect_used)]
116    pub fn new(name: impl Into<String>) -> Self {
117        Self::try_new(name).expect("AgentName validation failed")
118    }
119
120    pub fn as_str(&self) -> &str {
121        &self.0
122    }
123
124    pub fn system() -> Self {
125        Self("system".to_string())
126    }
127}
128
129impl AsRef<str> for AgentName {
130    fn as_ref(&self) -> &str {
131        &self.0
132    }
133}
134
135impl fmt::Display for AgentName {
136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137        write!(f, "{}", self.0)
138    }
139}
140
141impl TryFrom<String> for AgentName {
142    type Error = IdValidationError;
143
144    fn try_from(s: String) -> Result<Self, Self::Error> {
145        Self::try_new(s)
146    }
147}
148
149impl TryFrom<&str> for AgentName {
150    type Error = IdValidationError;
151
152    fn try_from(s: &str) -> Result<Self, Self::Error> {
153        Self::try_new(s)
154    }
155}
156
157impl std::str::FromStr for AgentName {
158    type Err = IdValidationError;
159
160    fn from_str(s: &str) -> Result<Self, Self::Err> {
161        Self::try_new(s)
162    }
163}
164
165impl<'de> Deserialize<'de> for AgentName {
166    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
167    where
168        D: serde::Deserializer<'de>,
169    {
170        let s = String::deserialize(deserializer)?;
171        Self::try_new(s).map_err(serde::de::Error::custom)
172    }
173}
174
175impl ToDbValue for AgentName {
176    fn to_db_value(&self) -> DbValue {
177        DbValue::String(self.0.clone())
178    }
179}
180
181impl ToDbValue for &AgentName {
182    fn to_db_value(&self) -> DbValue {
183        DbValue::String(self.0.clone())
184    }
185}
186
187impl From<AgentName> for String {
188    fn from(id: AgentName) -> Self {
189        id.0
190    }
191}
192
193impl From<&AgentName> for String {
194    fn from(id: &AgentName) -> Self {
195        id.0.clone()
196    }
197}
198
199impl PartialEq<&str> for AgentName {
200    fn eq(&self, other: &&str) -> bool {
201        self.0 == *other
202    }
203}
204
205impl PartialEq<str> for AgentName {
206    fn eq(&self, other: &str) -> bool {
207        self.0 == other
208    }
209}
210
211impl std::borrow::Borrow<str> for AgentName {
212    fn borrow(&self) -> &str {
213        &self.0
214    }
215}