Skip to main content

haste_jwt/
lib.rs

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