rig_core/completion/message/
identity.rs1use std::borrow::Cow;
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
19#[serde(try_from = "String", into = "String")]
20pub struct ToolName(String);
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
24#[error("a tool name cannot be empty")]
25pub struct EmptyToolName;
26
27impl ToolName {
28 pub fn new(name: impl Into<String>) -> Result<Self, EmptyToolName> {
30 let name = name.into();
31 if name.is_empty() {
32 Err(EmptyToolName)
33 } else {
34 Ok(Self(name))
35 }
36 }
37
38 pub fn as_str(&self) -> &str {
40 &self.0
41 }
42}
43
44impl TryFrom<String> for ToolName {
45 type Error = EmptyToolName;
46
47 fn try_from(name: String) -> Result<Self, EmptyToolName> {
48 Self::new(name)
49 }
50}
51
52impl TryFrom<&str> for ToolName {
53 type Error = EmptyToolName;
54
55 fn try_from(name: &str) -> Result<Self, EmptyToolName> {
56 Self::new(name)
57 }
58}
59
60impl From<ToolName> for String {
61 fn from(name: ToolName) -> Self {
62 name.0
63 }
64}
65
66impl std::ops::Deref for ToolName {
67 type Target = str;
68
69 fn deref(&self) -> &str {
70 &self.0
71 }
72}
73
74impl AsRef<str> for ToolName {
75 fn as_ref(&self) -> &str {
76 &self.0
77 }
78}
79
80impl std::borrow::Borrow<str> for ToolName {
81 fn borrow(&self) -> &str {
82 &self.0
83 }
84}
85
86impl std::fmt::Display for ToolName {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 f.write_str(&self.0)
89 }
90}
91
92impl PartialEq<str> for ToolName {
93 fn eq(&self, other: &str) -> bool {
94 self.0 == other
95 }
96}
97
98impl PartialEq<&str> for ToolName {
99 fn eq(&self, other: &&str) -> bool {
100 self.0 == *other
101 }
102}
103
104impl PartialEq<String> for ToolName {
105 fn eq(&self, other: &String) -> bool {
106 &self.0 == other
107 }
108}
109
110impl PartialEq<ToolName> for String {
111 fn eq(&self, other: &ToolName) -> bool {
112 *self == other.0
113 }
114}
115
116impl PartialEq<ToolName> for str {
117 fn eq(&self, other: &ToolName) -> bool {
118 self == other.0
119 }
120}
121
122#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
139#[serde(rename_all = "snake_case")]
140pub enum CallId {
141 Provider(ProviderCallId),
143 Local(LocalCallId),
145}
146
147impl CallId {
148 pub fn from_wire(call_id: impl Into<String>) -> Self {
150 ProviderCallId::new(call_id).map_or_else(|| Self::Local(LocalCallId::new()), Self::Provider)
151 }
152
153 pub fn from_dual_wire(item_id: impl Into<String>, call_id: impl Into<String>) -> Self {
157 match ProviderCallId::new(call_id) {
158 Some(provider) => Self::Provider(provider.with_item_id(item_id)),
159 None => Self::Local(LocalCallId::new()),
160 }
161 }
162
163 pub fn provider(&self) -> Option<&ProviderCallId> {
165 match self {
166 Self::Provider(provider) => Some(provider),
167 Self::Local(_) => None,
168 }
169 }
170
171 pub fn is_local(&self) -> bool {
173 matches!(self, Self::Local(_))
174 }
175
176 pub fn wire(&self) -> Cow<'_, str> {
179 match self {
180 Self::Provider(provider) => Cow::Borrowed(provider.call_id.as_str()),
181 Self::Local(local) => Cow::Owned(local.to_string()),
182 }
183 }
184}
185
186impl From<ProviderCallId> for CallId {
187 fn from(provider: ProviderCallId) -> Self {
188 Self::Provider(provider)
189 }
190}
191
192impl From<LocalCallId> for CallId {
193 fn from(local: LocalCallId) -> Self {
194 Self::Local(local)
195 }
196}
197
198impl std::fmt::Display for CallId {
199 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200 f.write_str(&self.wire())
201 }
202}
203
204#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
206#[serde(transparent)]
207pub struct LocalCallId(uuid::Uuid);
208
209impl LocalCallId {
210 pub fn new() -> Self {
212 Self(uuid::Uuid::new_v4())
213 }
214}
215
216impl Default for LocalCallId {
217 fn default() -> Self {
218 Self::new()
219 }
220}
221
222impl std::fmt::Display for LocalCallId {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 self.0.fmt(f)
225 }
226}
227
228#[derive(Deserialize)]
231struct ProviderCallIdWire {
232 call_id: String,
233 #[serde(default)]
234 item_id: Option<String>,
235}
236
237#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
241#[serde(try_from = "ProviderCallIdWire")]
242pub struct ProviderCallId {
243 pub call_id: String,
245 #[serde(default, skip_serializing_if = "Option::is_none")]
248 pub item_id: Option<String>,
249}
250
251#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
253#[error("a provider call id cannot be empty")]
254pub struct EmptyCallId;
255
256impl ProviderCallId {
257 pub fn new(call_id: impl Into<String>) -> Option<Self> {
260 let call_id = call_id.into();
261 (!call_id.is_empty()).then_some(Self {
262 call_id,
263 item_id: None,
264 })
265 }
266
267 pub fn with_item_id(mut self, item_id: impl Into<String>) -> Self {
269 let item_id = item_id.into();
270 self.item_id = (!item_id.is_empty()).then_some(item_id);
271 self
272 }
273}
274
275impl TryFrom<ProviderCallIdWire> for ProviderCallId {
276 type Error = EmptyCallId;
277
278 fn try_from(wire: ProviderCallIdWire) -> Result<Self, EmptyCallId> {
279 let provider = Self::new(wire.call_id).ok_or(EmptyCallId)?;
280 Ok(match wire.item_id {
281 Some(item_id) => provider.with_item_id(item_id),
282 None => provider,
283 })
284 }
285}
286
287#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
294#[serde(transparent)]
295pub struct Issuer(Cow<'static, str>);
296
297impl Issuer {
298 pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
300 Self(name.into())
301 }
302
303 pub const fn from_static(name: &'static str) -> Self {
305 Self(Cow::Borrowed(name))
306 }
307
308 pub fn as_str(&self) -> &str {
310 &self.0
311 }
312
313 pub fn accepts(&self, issued: &Issuer) -> bool {
316 self.0 == issued.0 || (self.0.ends_with('/') && issued.0.starts_with(self.as_str()))
317 }
318}
319
320impl std::fmt::Display for Issuer {
321 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
322 f.write_str(&self.0)
323 }
324}
325
326impl From<&'static str> for Issuer {
327 fn from(name: &'static str) -> Self {
328 Self(Cow::Borrowed(name))
329 }
330}
331
332impl From<String> for Issuer {
333 fn from(name: String) -> Self {
334 Self(Cow::Owned(name))
335 }
336}
337
338#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
353pub struct Sealed<T> {
354 issuer: Issuer,
355 #[serde(flatten)]
356 value: T,
357}
358
359impl<T> Sealed<T> {
360 pub fn new(issuer: impl Into<Issuer>, value: T) -> Self {
362 Self {
363 issuer: issuer.into(),
364 value,
365 }
366 }
367
368 pub fn issuer(&self) -> &Issuer {
370 &self.issuer
371 }
372
373 pub fn open(&self, to: &Issuer) -> Option<&T> {
375 to.accepts(&self.issuer).then_some(&self.value)
376 }
377
378 pub fn open_for(&self, issuers: &[Issuer]) -> Option<&T> {
380 issuers
381 .iter()
382 .any(|to| to.accepts(&self.issuer))
383 .then_some(&self.value)
384 }
385
386 pub(crate) fn reseal(self, issuer: impl Into<Issuer>) -> Self {
388 Self::new(issuer, self.value)
389 }
390
391 pub(crate) fn value(&self) -> &T {
393 &self.value
394 }
395}