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