automatons_github/
macros.rs1#[macro_export]
16macro_rules! id {
17 (
18 $(#[$meta:meta])*
19 $id:ident
20 ) => {
21 $(#[$meta])*
22 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
23 #[derive(serde::Deserialize, serde::Serialize)]
24 pub struct $id(u64);
25
26 #[allow(dead_code)]
27 impl $id {
28 #[cfg_attr(feature = "tracing", tracing::instrument)]
30 pub fn new(id: u64) -> Self {
31 Self(id)
32 }
33
34 #[cfg_attr(feature = "tracing", tracing::instrument)]
36 pub fn get(&self) -> u64 {
37 self.0
38 }
39 }
40
41 impl std::fmt::Display for $id {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "{}", self.0)
44 }
45 }
46
47 impl From<u64> for $id {
48 #[cfg_attr(feature = "tracing", tracing::instrument)]
49 fn from(id: u64) -> $id {
50 $id(id)
51 }
52 }
53 };
54}
55
56#[macro_export]
74macro_rules! name {
75 (
76 $(#[$meta:meta])*
77 $name:ident
78 ) => {
79 $(#[$meta])*
80 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
81 #[derive(serde::Deserialize, serde::Serialize)]
82 pub struct $name(String);
83
84 #[allow(dead_code)]
85 impl $name {
86 #[cfg_attr(feature = "tracing", tracing::instrument)]
88 pub fn new(name: &str) -> Self {
89 Self(name.into())
90 }
91
92 #[cfg_attr(feature = "tracing", tracing::instrument)]
94 pub fn get(&self) -> &str {
95 &self.0
96 }
97 }
98
99 impl std::fmt::Display for $name {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}", self.0)
102 }
103 }
104
105 impl From<&str> for $name {
106 #[cfg_attr(feature = "tracing", tracing::instrument)]
107 fn from(string: &str) -> $name {
108 $name(string.into())
109 }
110 }
111
112 impl From<String> for $name {
113 #[cfg_attr(feature = "tracing", tracing::instrument)]
114 fn from(string: String) -> $name {
115 $name(string)
116 }
117 }
118 };
119}
120
121#[macro_export]
136macro_rules! secret {
137 (
138 $(#[$meta:meta])*
139 $secret:ident
140 ) => {
141 $(#[$meta])*
142 #[derive(Clone, Debug)]
143 pub struct $secret(secrecy::SecretString);
144
145 #[allow(dead_code)]
146 impl $secret {
147 #[cfg_attr(feature = "tracing", tracing::instrument)]
149 pub fn new(secret: &str) -> Self {
150 Self(secrecy::SecretString::new(String::from(secret)))
151 }
152
153 #[cfg_attr(feature = "tracing", tracing::instrument)]
155 pub fn expose(&self) -> &str {
156 use secrecy::ExposeSecret;
157 self.0.expose_secret()
158 }
159 }
160
161 impl std::fmt::Display for $secret {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 write!(f, "[REDACTED]")
164 }
165 }
166
167 impl From<&str> for $secret {
168 #[cfg_attr(feature = "tracing", tracing::instrument)]
169 fn from(secret: &str) -> $secret {
170 $secret(secrecy::SecretString::new(String::from(secret)))
171 }
172 }
173
174 impl From<String> for $secret {
175 #[cfg_attr(feature = "tracing", tracing::instrument)]
176 fn from(secret: String) -> $secret {
177 $secret(secrecy::SecretString::new(secret))
178 }
179 }
180 };
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::{id, name};
186
187 id!(
188 TestId
190 );
191
192 #[test]
193 fn id() {
194 let id = TestId::new(42);
195
196 assert_eq!(42, id.get());
197 assert_eq!("42", id.to_string());
198 }
199
200 #[test]
201 fn id_from_u64() {
202 let _id: TestId = 42.into();
203 }
204
205 name!(
206 TestName
208 );
209
210 #[test]
211 fn name() {
212 let name = TestName::new("test");
213
214 assert_eq!("test", name.get());
215 assert_eq!("test", name.to_string());
216 }
217
218 #[test]
219 fn name_from_str() {
220 let _name: TestName = "test".into();
221 }
222
223 #[test]
224 fn name_from_string() {
225 let _name: TestName = String::from("test").into();
226 }
227
228 secret!(
229 TestSecret
231 );
232
233 #[test]
234 fn secret() {
235 let secret = TestSecret::new("test");
236
237 assert_eq!("test", secret.expose());
238 assert_eq!("[REDACTED]", secret.to_string());
239 }
240
241 #[test]
242 fn secret_from_str() {
243 let _secret: TestSecret = "test".into();
244 }
245
246 #[test]
247 fn secret_from_string() {
248 let _secret: TestSecret = String::from("test").into();
249 }
250}