systemprompt_identifiers/
client.rs

1//! Client identifier types.
2
3use crate::{DbValue, ToDbValue};
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
9#[cfg_attr(feature = "sqlx", sqlx(transparent))]
10#[serde(transparent)]
11pub struct ClientId(String);
12
13impl ClientId {
14    pub fn new(id: impl Into<String>) -> Self {
15        Self(id.into())
16    }
17
18    pub fn as_str(&self) -> &str {
19        &self.0
20    }
21
22    pub fn client_type(&self) -> ClientType {
23        if self.0.starts_with("https://") {
24            ClientType::Cimd
25        } else if self.0.starts_with("sp_") {
26            ClientType::FirstParty
27        } else if self.0.starts_with("client_") {
28            ClientType::ThirdParty
29        } else if self.0.starts_with("sys_") {
30            ClientType::System
31        } else {
32            ClientType::Unknown
33        }
34    }
35
36    pub fn is_dcr(&self) -> bool {
37        matches!(
38            self.client_type(),
39            ClientType::FirstParty | ClientType::ThirdParty
40        )
41    }
42
43    pub fn is_cimd(&self) -> bool {
44        self.0.starts_with("https://")
45    }
46
47    pub fn is_system(&self) -> bool {
48        self.0.starts_with("sys_")
49    }
50
51    pub fn web() -> Self {
52        Self("sp_web".to_string())
53    }
54
55    pub fn cli() -> Self {
56        Self("sp_cli".to_string())
57    }
58
59    pub fn mobile_ios() -> Self {
60        Self("sp_mobile_ios".to_string())
61    }
62
63    pub fn mobile_android() -> Self {
64        Self("sp_mobile_android".to_string())
65    }
66
67    pub fn desktop() -> Self {
68        Self("sp_desktop".to_string())
69    }
70
71    pub fn system(service_name: &str) -> Self {
72        Self(format!("sys_{service_name}"))
73    }
74}
75
76impl fmt::Display for ClientId {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        write!(f, "{}", self.0)
79    }
80}
81
82impl From<String> for ClientId {
83    fn from(s: String) -> Self {
84        Self(s)
85    }
86}
87
88impl From<&str> for ClientId {
89    fn from(s: &str) -> Self {
90        Self(s.to_string())
91    }
92}
93
94impl AsRef<str> for ClientId {
95    fn as_ref(&self) -> &str {
96        &self.0
97    }
98}
99
100impl ToDbValue for ClientId {
101    fn to_db_value(&self) -> DbValue {
102        DbValue::String(self.0.clone())
103    }
104}
105
106impl ToDbValue for &ClientId {
107    fn to_db_value(&self) -> DbValue {
108        DbValue::String(self.0.clone())
109    }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
113#[serde(rename_all = "lowercase")]
114pub enum ClientType {
115    Cimd,
116    FirstParty,
117    ThirdParty,
118    System,
119    Unknown,
120}
121
122impl ClientType {
123    pub const fn as_str(self) -> &'static str {
124        match self {
125            Self::Cimd => "cimd",
126            Self::FirstParty => "firstparty",
127            Self::ThirdParty => "thirdparty",
128            Self::System => "system",
129            Self::Unknown => "unknown",
130        }
131    }
132}
133
134impl fmt::Display for ClientType {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        write!(f, "{}", self.as_str())
137    }
138}