Skip to main content

systemprompt_identifiers/macros/
token.rs

1//! `define_token!` macro for secret-bearing identifiers with redacted `Debug`.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6#[macro_export]
7macro_rules! define_token {
8    ($name:ident) => {
9        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)]
10        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
11        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
12        #[serde(transparent)]
13        pub struct $name(String);
14
15        impl $name {
16            pub fn new(token: impl Into<String>) -> Self {
17                Self(token.into())
18            }
19
20            pub fn as_str(&self) -> &str {
21                &self.0
22            }
23
24            #[must_use]
25            pub fn redacted(&self) -> String {
26                let len = self.0.len();
27                if len <= 16 {
28                    "*".repeat(len.min(8))
29                } else {
30                    format!("{}...{}", &self.0[..8], &self.0[len - 4..])
31                }
32            }
33        }
34
35        impl std::fmt::Display for $name {
36            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37                write!(f, "{}", self.redacted())
38            }
39        }
40
41        impl From<String> for $name {
42            fn from(s: String) -> Self {
43                Self(s)
44            }
45        }
46
47        impl From<&str> for $name {
48            fn from(s: &str) -> Self {
49                Self(s.to_string())
50            }
51        }
52
53        impl AsRef<str> for $name {
54            fn as_ref(&self) -> &str {
55                &self.0
56            }
57        }
58
59        impl $crate::ToDbValue for $name {
60            fn to_db_value(&self) -> $crate::DbValue {
61                $crate::DbValue::String(self.0.clone())
62            }
63        }
64
65        impl $crate::ToDbValue for &$name {
66            fn to_db_value(&self) -> $crate::DbValue {
67                $crate::DbValue::String(self.0.clone())
68            }
69        }
70    };
71}