Skip to main content

systemprompt_identifiers/
macros.rs

1#[macro_export]
2macro_rules! define_id {
3    ($name:ident) => {
4        #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
5        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
6        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
7        #[serde(transparent)]
8        pub struct $name(String);
9
10        impl $name {
11            pub fn new(id: impl Into<String>) -> Self {
12                Self(id.into())
13            }
14
15            pub fn as_str(&self) -> &str {
16                &self.0
17            }
18        }
19
20        impl std::fmt::Display for $name {
21            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22                write!(f, "{}", self.0)
23            }
24        }
25
26        impl From<String> for $name {
27            fn from(s: String) -> Self {
28                Self(s)
29            }
30        }
31
32        impl From<&str> for $name {
33            fn from(s: &str) -> Self {
34                Self(s.to_string())
35            }
36        }
37
38        impl AsRef<str> for $name {
39            fn as_ref(&self) -> &str {
40                &self.0
41            }
42        }
43
44        impl $crate::ToDbValue for $name {
45            fn to_db_value(&self) -> $crate::DbValue {
46                $crate::DbValue::String(self.0.clone())
47            }
48        }
49
50        impl $crate::ToDbValue for &$name {
51            fn to_db_value(&self) -> $crate::DbValue {
52                $crate::DbValue::String(self.0.clone())
53            }
54        }
55
56        impl From<$name> for String {
57            fn from(id: $name) -> Self {
58                id.0
59            }
60        }
61
62        impl From<&$name> for String {
63            fn from(id: &$name) -> Self {
64                id.0.clone()
65            }
66        }
67
68        impl PartialEq<&str> for $name {
69            fn eq(&self, other: &&str) -> bool {
70                self.0 == *other
71            }
72        }
73
74        impl PartialEq<str> for $name {
75            fn eq(&self, other: &str) -> bool {
76                self.0 == other
77            }
78        }
79
80        impl PartialEq<$name> for &str {
81            fn eq(&self, other: &$name) -> bool {
82                *self == other.0
83            }
84        }
85
86        impl PartialEq<$name> for str {
87            fn eq(&self, other: &$name) -> bool {
88                self == other.0
89            }
90        }
91
92        impl std::borrow::Borrow<str> for $name {
93            fn borrow(&self) -> &str {
94                &self.0
95            }
96        }
97    };
98
99    ($name:ident, non_empty) => {
100        #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize)]
101        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
102        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
103        #[serde(transparent)]
104        pub struct $name(String);
105
106        impl $name {
107            pub fn try_new(value: impl Into<String>) -> Result<Self, $crate::error::IdValidationError> {
108                let value = value.into();
109                if value.is_empty() {
110                    return Err($crate::error::IdValidationError::empty(stringify!($name)));
111                }
112                Ok(Self(value))
113            }
114
115            #[allow(clippy::expect_used)]
116            pub fn new(value: impl Into<String>) -> Self {
117                Self::try_new(value).expect(concat!(stringify!($name), " cannot be empty"))
118            }
119
120            pub fn as_str(&self) -> &str {
121                &self.0
122            }
123        }
124
125        impl std::fmt::Display for $name {
126            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127                write!(f, "{}", self.0)
128            }
129        }
130
131        impl TryFrom<String> for $name {
132            type Error = $crate::error::IdValidationError;
133
134            fn try_from(s: String) -> Result<Self, Self::Error> {
135                Self::try_new(s)
136            }
137        }
138
139        impl TryFrom<&str> for $name {
140            type Error = $crate::error::IdValidationError;
141
142            fn try_from(s: &str) -> Result<Self, Self::Error> {
143                Self::try_new(s)
144            }
145        }
146
147        impl std::str::FromStr for $name {
148            type Err = $crate::error::IdValidationError;
149
150            fn from_str(s: &str) -> Result<Self, Self::Err> {
151                Self::try_new(s)
152            }
153        }
154
155        impl AsRef<str> for $name {
156            fn as_ref(&self) -> &str {
157                &self.0
158            }
159        }
160
161        impl<'de> serde::Deserialize<'de> for $name {
162            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
163            where
164                D: serde::Deserializer<'de>,
165            {
166                let s = String::deserialize(deserializer)?;
167                Self::try_new(s).map_err(serde::de::Error::custom)
168            }
169        }
170
171        impl $crate::ToDbValue for $name {
172            fn to_db_value(&self) -> $crate::DbValue {
173                $crate::DbValue::String(self.0.clone())
174            }
175        }
176
177        impl $crate::ToDbValue for &$name {
178            fn to_db_value(&self) -> $crate::DbValue {
179                $crate::DbValue::String(self.0.clone())
180            }
181        }
182
183        impl From<$name> for String {
184            fn from(id: $name) -> Self {
185                id.0
186            }
187        }
188
189        impl From<&$name> for String {
190            fn from(id: &$name) -> Self {
191                id.0.clone()
192            }
193        }
194
195        impl PartialEq<&str> for $name {
196            fn eq(&self, other: &&str) -> bool {
197                self.0 == *other
198            }
199        }
200
201        impl PartialEq<str> for $name {
202            fn eq(&self, other: &str) -> bool {
203                self.0 == other
204            }
205        }
206
207        impl PartialEq<$name> for &str {
208            fn eq(&self, other: &$name) -> bool {
209                *self == other.0
210            }
211        }
212
213        impl PartialEq<$name> for str {
214            fn eq(&self, other: &$name) -> bool {
215                self == other.0
216            }
217        }
218
219        impl std::borrow::Borrow<str> for $name {
220            fn borrow(&self) -> &str {
221                &self.0
222            }
223        }
224    };
225
226    ($name:ident, validated, $validator:expr) => {
227        #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize)]
228        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
229        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
230        #[serde(transparent)]
231        pub struct $name(String);
232
233        impl $name {
234            pub fn try_new(value: impl Into<String>) -> Result<Self, $crate::error::IdValidationError> {
235                let value = value.into();
236                let validator: fn(&str) -> Result<(), $crate::error::IdValidationError> = $validator;
237                validator(&value)?;
238                Ok(Self(value))
239            }
240
241            #[allow(clippy::expect_used)]
242            pub fn new(value: impl Into<String>) -> Self {
243                Self::try_new(value).expect(concat!(stringify!($name), " validation failed"))
244            }
245
246            pub fn as_str(&self) -> &str {
247                &self.0
248            }
249        }
250
251        impl std::fmt::Display for $name {
252            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253                write!(f, "{}", self.0)
254            }
255        }
256
257        impl TryFrom<String> for $name {
258            type Error = $crate::error::IdValidationError;
259
260            fn try_from(s: String) -> Result<Self, Self::Error> {
261                Self::try_new(s)
262            }
263        }
264
265        impl TryFrom<&str> for $name {
266            type Error = $crate::error::IdValidationError;
267
268            fn try_from(s: &str) -> Result<Self, Self::Error> {
269                Self::try_new(s)
270            }
271        }
272
273        impl std::str::FromStr for $name {
274            type Err = $crate::error::IdValidationError;
275
276            fn from_str(s: &str) -> Result<Self, Self::Err> {
277                Self::try_new(s)
278            }
279        }
280
281        impl AsRef<str> for $name {
282            fn as_ref(&self) -> &str {
283                &self.0
284            }
285        }
286
287        impl<'de> serde::Deserialize<'de> for $name {
288            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
289            where
290                D: serde::Deserializer<'de>,
291            {
292                let s = String::deserialize(deserializer)?;
293                Self::try_new(s).map_err(serde::de::Error::custom)
294            }
295        }
296
297        impl $crate::ToDbValue for $name {
298            fn to_db_value(&self) -> $crate::DbValue {
299                $crate::DbValue::String(self.0.clone())
300            }
301        }
302
303        impl $crate::ToDbValue for &$name {
304            fn to_db_value(&self) -> $crate::DbValue {
305                $crate::DbValue::String(self.0.clone())
306            }
307        }
308
309        impl From<$name> for String {
310            fn from(id: $name) -> Self {
311                id.0
312            }
313        }
314
315        impl From<&$name> for String {
316            fn from(id: &$name) -> Self {
317                id.0.clone()
318            }
319        }
320
321        impl PartialEq<&str> for $name {
322            fn eq(&self, other: &&str) -> bool {
323                self.0 == *other
324            }
325        }
326
327        impl PartialEq<str> for $name {
328            fn eq(&self, other: &str) -> bool {
329                self.0 == other
330            }
331        }
332
333        impl PartialEq<$name> for &str {
334            fn eq(&self, other: &$name) -> bool {
335                *self == other.0
336            }
337        }
338
339        impl PartialEq<$name> for str {
340            fn eq(&self, other: &$name) -> bool {
341                self == other.0
342            }
343        }
344
345        impl std::borrow::Borrow<str> for $name {
346            fn borrow(&self) -> &str {
347                &self.0
348            }
349        }
350    };
351
352    ($name:ident, generate) => {
353        $crate::define_id!($name);
354
355        impl $name {
356            pub fn generate() -> Self {
357                Self(uuid::Uuid::new_v4().to_string())
358            }
359        }
360    };
361
362    ($name:ident, system) => {
363        $crate::define_id!($name);
364
365        impl $name {
366            pub fn system() -> Self {
367                Self("system".to_string())
368            }
369        }
370    };
371
372    ($name:ident, generate, system) => {
373        $crate::define_id!($name);
374
375        impl $name {
376            pub fn generate() -> Self {
377                Self(uuid::Uuid::new_v4().to_string())
378            }
379
380            pub fn system() -> Self {
381                Self("system".to_string())
382            }
383        }
384    };
385
386    ($name:ident, schema) => {
387        #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
388        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
389        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
390        #[serde(transparent)]
391        pub struct $name(String);
392
393        impl $name {
394            pub fn new(id: impl Into<String>) -> Self {
395                Self(id.into())
396            }
397
398            pub fn as_str(&self) -> &str {
399                &self.0
400            }
401        }
402
403        impl std::fmt::Display for $name {
404            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
405                write!(f, "{}", self.0)
406            }
407        }
408
409        impl From<String> for $name {
410            fn from(s: String) -> Self {
411                Self(s)
412            }
413        }
414
415        impl From<&str> for $name {
416            fn from(s: &str) -> Self {
417                Self(s.to_string())
418            }
419        }
420
421        impl AsRef<str> for $name {
422            fn as_ref(&self) -> &str {
423                &self.0
424            }
425        }
426
427        impl $crate::ToDbValue for $name {
428            fn to_db_value(&self) -> $crate::DbValue {
429                $crate::DbValue::String(self.0.clone())
430            }
431        }
432
433        impl $crate::ToDbValue for &$name {
434            fn to_db_value(&self) -> $crate::DbValue {
435                $crate::DbValue::String(self.0.clone())
436            }
437        }
438
439        impl From<$name> for String {
440            fn from(id: $name) -> Self {
441                id.0
442            }
443        }
444
445        impl From<&$name> for String {
446            fn from(id: &$name) -> Self {
447                id.0.clone()
448            }
449        }
450
451        impl PartialEq<&str> for $name {
452            fn eq(&self, other: &&str) -> bool {
453                self.0 == *other
454            }
455        }
456
457        impl PartialEq<str> for $name {
458            fn eq(&self, other: &str) -> bool {
459                self.0 == other
460            }
461        }
462
463        impl PartialEq<$name> for &str {
464            fn eq(&self, other: &$name) -> bool {
465                *self == other.0
466            }
467        }
468
469        impl PartialEq<$name> for str {
470            fn eq(&self, other: &$name) -> bool {
471                self == other.0
472            }
473        }
474
475        impl std::borrow::Borrow<str> for $name {
476            fn borrow(&self) -> &str {
477                &self.0
478            }
479        }
480    };
481
482    ($name:ident, generate, schema) => {
483        $crate::define_id!(@ $name, schema);
484
485        impl $name {
486            pub fn generate() -> Self {
487                Self(uuid::Uuid::new_v4().to_string())
488            }
489        }
490    };
491
492    (@ $name:ident, schema) => {
493        #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
494        #[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
495        #[cfg_attr(feature = "sqlx", sqlx(transparent))]
496        #[serde(transparent)]
497        pub struct $name(String);
498
499        impl $name {
500            pub fn new(id: impl Into<String>) -> Self {
501                Self(id.into())
502            }
503
504            pub fn as_str(&self) -> &str {
505                &self.0
506            }
507        }
508
509        impl std::fmt::Display for $name {
510            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
511                write!(f, "{}", self.0)
512            }
513        }
514
515        impl From<String> for $name {
516            fn from(s: String) -> Self {
517                Self(s)
518            }
519        }
520
521        impl From<&str> for $name {
522            fn from(s: &str) -> Self {
523                Self(s.to_string())
524            }
525        }
526
527        impl AsRef<str> for $name {
528            fn as_ref(&self) -> &str {
529                &self.0
530            }
531        }
532
533        impl $crate::ToDbValue for $name {
534            fn to_db_value(&self) -> $crate::DbValue {
535                $crate::DbValue::String(self.0.clone())
536            }
537        }
538
539        impl $crate::ToDbValue for &$name {
540            fn to_db_value(&self) -> $crate::DbValue {
541                $crate::DbValue::String(self.0.clone())
542            }
543        }
544
545        impl From<$name> for String {
546            fn from(id: $name) -> Self {
547                id.0
548            }
549        }
550
551        impl From<&$name> for String {
552            fn from(id: &$name) -> Self {
553                id.0.clone()
554            }
555        }
556
557        impl PartialEq<&str> for $name {
558            fn eq(&self, other: &&str) -> bool {
559                self.0 == *other
560            }
561        }
562
563        impl PartialEq<str> for $name {
564            fn eq(&self, other: &str) -> bool {
565                self.0 == other
566            }
567        }
568
569        impl PartialEq<$name> for &str {
570            fn eq(&self, other: &$name) -> bool {
571                *self == other.0
572            }
573        }
574
575        impl PartialEq<$name> for str {
576            fn eq(&self, other: &$name) -> bool {
577                self == other.0
578            }
579        }
580
581        impl std::borrow::Borrow<str> for $name {
582            fn borrow(&self) -> &str {
583                &self.0
584            }
585        }
586    };
587}
588
589pub use define_id;