haste_jwt/
lib.rs

1use haste_fhir_model::r4::generated::terminology::UserRole as FHIRUserRole;
2use serde::{Deserialize, Serialize};
3use std::fmt::Display;
4
5#[cfg(feature = "reflect")]
6pub mod reflect;
7
8#[cfg(feature = "sqlx")]
9pub mod sqlx;
10
11pub mod claims;
12pub mod scopes;
13
14// Reserved keyword for system tenant, author and project.
15static SYSTEM: &str = "system";
16
17#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
18#[serde(rename_all = "lowercase")]
19pub enum UserRole {
20    Owner,
21    Admin,
22    Member,
23}
24
25impl From<FHIRUserRole> for UserRole {
26    fn from(role: FHIRUserRole) -> Self {
27        match role {
28            FHIRUserRole::Owner(_) => UserRole::Owner,
29            FHIRUserRole::Admin(_) => UserRole::Admin,
30            FHIRUserRole::Member(_) => UserRole::Member,
31            FHIRUserRole::Null(_) => UserRole::Member,
32        }
33    }
34}
35
36#[derive(Clone, Debug)]
37pub enum AuthorId {
38    // System is used for system level actions such as tenant creation etc..
39    System,
40    User(ResourceId),
41}
42
43impl AuthorId {
44    pub fn new(id: String) -> Self {
45        // Should never be able to create a system author from user.
46        if id == SYSTEM {
47            AuthorId::System
48        } else {
49            AuthorId::User(ResourceId::new(id))
50        }
51    }
52}
53
54impl AsRef<str> for AuthorId {
55    fn as_ref(&self) -> &str {
56        match self {
57            AuthorId::System => SYSTEM,
58            AuthorId::User(id) => id.as_ref(),
59        }
60    }
61}
62
63impl<'de> Deserialize<'de> for AuthorId {
64    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
65    where
66        D: serde::Deserializer<'de>,
67    {
68        Ok(AuthorId::new(String::deserialize(deserializer)?))
69    }
70}
71
72impl Serialize for AuthorId {
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: serde::Serializer,
76    {
77        serializer.serialize_str(self.as_ref())
78    }
79}
80
81impl Display for AuthorId {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        match self {
84            AuthorId::System => write!(f, "{}", SYSTEM),
85            AuthorId::User(id) => write!(f, "{}", id.as_ref()),
86        }
87    }
88}
89
90#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
91pub enum AuthorKind {
92    System,
93    Membership,
94    ClientApplication,
95    OperationDefinition,
96}
97
98impl AsRef<str> for AuthorKind {
99    fn as_ref(&self) -> &str {
100        match self {
101            AuthorKind::System => "System",
102            AuthorKind::Membership => "Membership",
103            AuthorKind::ClientApplication => "ClientApplication",
104            AuthorKind::OperationDefinition => "OperationDefinition",
105        }
106    }
107}
108
109impl Display for AuthorKind {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(f, "{}", self.as_ref())
112    }
113}
114
115#[derive(Debug, Clone, PartialEq)]
116pub enum TenantId {
117    System,
118    Custom(String),
119}
120
121impl TenantId {
122    pub fn new(id: String) -> Self {
123        // Should never be able to create a system tenant from user.
124        if id == SYSTEM {
125            TenantId::System
126        } else {
127            TenantId::Custom(id)
128        }
129    }
130}
131
132impl From<String> for TenantId {
133    fn from(id: String) -> Self {
134        TenantId::new(id)
135    }
136}
137
138impl AsRef<str> for TenantId {
139    fn as_ref(&self) -> &str {
140        match self {
141            TenantId::System => SYSTEM,
142            TenantId::Custom(id) => id,
143        }
144    }
145}
146
147impl<'de> Deserialize<'de> for TenantId {
148    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
149    where
150        D: serde::Deserializer<'de>,
151    {
152        Ok(TenantId::new(String::deserialize(deserializer)?))
153    }
154}
155
156impl Serialize for TenantId {
157    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
158    where
159        S: serde::Serializer,
160    {
161        serializer.serialize_str(self.as_ref())
162    }
163}
164
165impl Display for TenantId {
166    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167        match self {
168            TenantId::System => write!(f, "{}", SYSTEM),
169            TenantId::Custom(id) => write!(f, "{}", id),
170        }
171    }
172}
173
174#[derive(Debug, Clone, PartialEq)]
175pub enum ProjectId {
176    System,
177    Custom(String),
178}
179impl ProjectId {
180    pub fn new(id: String) -> Self {
181        // Should never be able to create a system project from user.
182        if id == SYSTEM {
183            ProjectId::System
184        } else {
185            ProjectId::Custom(id)
186        }
187    }
188}
189
190impl AsRef<str> for ProjectId {
191    fn as_ref(&self) -> &str {
192        match self {
193            ProjectId::System => SYSTEM,
194            ProjectId::Custom(id) => id,
195        }
196    }
197}
198
199impl<'de> Deserialize<'de> for ProjectId {
200    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
201    where
202        D: serde::Deserializer<'de>,
203    {
204        Ok(ProjectId::new(String::deserialize(deserializer)?))
205    }
206}
207
208impl Serialize for ProjectId {
209    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
210    where
211        S: serde::Serializer,
212    {
213        serializer.serialize_str(self.as_ref())
214    }
215}
216
217impl Display for ProjectId {
218    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219        match self {
220            ProjectId::System => write!(f, "{}", SYSTEM),
221            ProjectId::Custom(id) => write!(f, "{}", id),
222        }
223    }
224}
225
226pub struct VersionIdRef<'a>(&'a str);
227impl<'a> VersionIdRef<'a> {
228    pub fn new(id: &'a str) -> Self {
229        VersionIdRef(id)
230    }
231}
232impl<'a> AsRef<str> for VersionIdRef<'a> {
233    fn as_ref(&self) -> &'a str {
234        &self.0
235    }
236}
237impl<'a> From<&'a VersionId> for VersionIdRef<'a> {
238    fn from(version_id: &'a VersionId) -> Self {
239        VersionIdRef::new(&version_id.0)
240    }
241}
242
243#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq, Hash)]
244pub struct VersionId(String);
245impl VersionId {
246    pub fn new(id: String) -> Self {
247        VersionId(id)
248    }
249}
250impl From<String> for VersionId {
251    fn from(id: String) -> Self {
252        VersionId(id)
253    }
254}
255impl AsRef<str> for VersionId {
256    fn as_ref(&self) -> &str {
257        &self.0
258    }
259}
260
261#[derive(Clone, Deserialize, Serialize, Debug)]
262pub struct ResourceId(String);
263impl ResourceId {
264    pub fn new(id: String) -> Self {
265        ResourceId(id)
266    }
267}
268impl AsRef<str> for ResourceId {
269    fn as_ref(&self) -> &str {
270        &self.0
271    }
272}