1use serde::{Deserialize, Serialize};
8use std::fmt;
9use std::ops::Deref;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
16#[serde(transparent)]
17pub struct PrincipalId(pub String);
18
19impl PrincipalId {
20 pub fn new(s: impl Into<String>) -> Self {
21 Self(s.into())
22 }
23}
24
25impl Deref for PrincipalId {
26 type Target = str;
27 fn deref(&self) -> &str {
28 &self.0
29 }
30}
31
32impl AsRef<str> for PrincipalId {
33 fn as_ref(&self) -> &str {
34 &self.0
35 }
36}
37
38impl fmt::Display for PrincipalId {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.write_str(&self.0)
41 }
42}
43
44impl<T: Into<String>> From<T> for PrincipalId {
45 fn from(value: T) -> Self {
46 Self(value.into())
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
52#[serde(transparent)]
53pub struct ActionId(pub String);
54
55impl ActionId {
56 pub fn new(s: impl Into<String>) -> Self {
57 Self(s.into())
58 }
59}
60
61impl Deref for ActionId {
62 type Target = str;
63 fn deref(&self) -> &str {
64 &self.0
65 }
66}
67
68impl AsRef<str> for ActionId {
69 fn as_ref(&self) -> &str {
70 &self.0
71 }
72}
73
74impl fmt::Display for ActionId {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 f.write_str(&self.0)
77 }
78}
79
80impl<T: Into<String>> From<T> for ActionId {
81 fn from(value: T) -> Self {
82 Self(value.into())
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
88#[serde(transparent)]
89pub struct ResourceId(pub String);
90
91impl ResourceId {
92 pub fn new(s: impl Into<String>) -> Self {
93 Self(s.into())
94 }
95}
96
97impl Deref for ResourceId {
98 type Target = str;
99 fn deref(&self) -> &str {
100 &self.0
101 }
102}
103
104impl AsRef<str> for ResourceId {
105 fn as_ref(&self) -> &str {
106 &self.0
107 }
108}
109
110impl fmt::Display for ResourceId {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 f.write_str(&self.0)
113 }
114}
115
116impl<T: Into<String>> From<T> for ResourceId {
117 fn from(value: T) -> Self {
118 Self(value.into())
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn principal_id_derefs_to_str() {
128 let id: PrincipalId = "alice".into();
129 assert_eq!(&*id, "alice");
130 assert_eq!(format!("{}", id), "alice");
131 }
132
133 #[test]
134 fn distinct_types_are_distinct() {
135 let p: PrincipalId = "alice".into();
136 let a: ActionId = "alice".into();
137 let r: ResourceId = "alice".into();
138 assert_eq!(p.0, a.0);
141 assert_eq!(a.0, r.0);
142 }
143}