Skip to main content

systemprompt_identifiers/
client.rs

1//! OAuth client identifier with classifier helpers.
2
3crate::define_id!(ClientId);
4
5impl ClientId {
6    pub fn client_type(&self) -> ClientType {
7        if self.0.starts_with("https://") {
8            ClientType::Cimd
9        } else if self.0.starts_with("sp_") {
10            ClientType::FirstParty
11        } else if self.0.starts_with("client_") {
12            ClientType::ThirdParty
13        } else if self.0.starts_with("sys_") {
14            ClientType::System
15        } else {
16            ClientType::Unknown
17        }
18    }
19
20    pub fn is_dcr(&self) -> bool {
21        matches!(
22            self.client_type(),
23            ClientType::FirstParty | ClientType::ThirdParty
24        )
25    }
26
27    pub fn is_cimd(&self) -> bool {
28        self.0.starts_with("https://")
29    }
30
31    pub fn is_system(&self) -> bool {
32        self.0.starts_with("sys_")
33    }
34
35    pub fn web() -> Self {
36        Self("sp_web".to_string())
37    }
38
39    pub fn cli() -> Self {
40        Self("sp_cli".to_string())
41    }
42
43    pub fn mobile_ios() -> Self {
44        Self("sp_mobile_ios".to_string())
45    }
46
47    pub fn mobile_android() -> Self {
48        Self("sp_mobile_android".to_string())
49    }
50
51    pub fn desktop() -> Self {
52        Self("sp_desktop".to_string())
53    }
54
55    pub fn cowork() -> Self {
56        Self("sp_cowork".to_string())
57    }
58
59    pub fn system(service_name: &str) -> Self {
60        Self(format!("sys_{service_name}"))
61    }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
65#[serde(rename_all = "lowercase")]
66pub enum ClientType {
67    Cimd,
68    FirstParty,
69    ThirdParty,
70    System,
71    Unknown,
72}
73
74impl ClientType {
75    pub const fn as_str(self) -> &'static str {
76        match self {
77            Self::Cimd => "cimd",
78            Self::FirstParty => "firstparty",
79            Self::ThirdParty => "thirdparty",
80            Self::System => "system",
81            Self::Unknown => "unknown",
82        }
83    }
84}
85
86impl std::fmt::Display for ClientType {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        write!(f, "{}", self.as_str())
89    }
90}