Skip to main content

systemprompt_identifiers/
client.rs

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