1use async_trait::async_trait;
8use futures_util::future::BoxFuture;
9use thiserror::Error;
10
11use crate::{
12 app_session::AppSessionRepository,
13 compat::{
14 CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
15 CompatSsoLoginRepository,
16 },
17 oauth2::{
18 OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository, OAuth2ClientRepository,
19 OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository, OAuth2SessionRepository,
20 },
21 personal::{PersonalAccessTokenRepository, PersonalSessionRepository},
22 policy_data::PolicyDataRepository,
23 queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
24 upstream_oauth2::{
25 UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
26 UpstreamOAuthSessionRepository,
27 },
28 user::{
29 BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
30 UserRecoveryRepository, UserRegistrationRepository, UserRegistrationTokenRepository,
31 UserRepository, UserTermsRepository,
32 },
33};
34
35#[async_trait]
39pub trait RepositoryFactory {
40 async fn create(&self) -> Result<BoxRepository, RepositoryError>;
42}
43
44pub type BoxRepositoryFactory = Box<dyn RepositoryFactory + Send + Sync + 'static>;
46
47pub trait Repository<E>:
49 RepositoryAccess<Error = E> + RepositoryTransaction<Error = E> + Send
50where
51 E: std::error::Error + Send + Sync + 'static,
52{
53}
54
55#[derive(Debug, Error)]
57#[error(transparent)]
58pub struct RepositoryError {
59 source: Box<dyn std::error::Error + Send + Sync + 'static>,
60}
61
62impl RepositoryError {
63 pub fn from_error<E>(value: E) -> Self
65 where
66 E: std::error::Error + Send + Sync + 'static,
67 {
68 Self {
69 source: Box::new(value),
70 }
71 }
72}
73
74pub type BoxRepository = Box<dyn Repository<RepositoryError> + Send + Sync + 'static>;
76
77pub trait RepositoryTransaction {
80 type Error;
82
83 fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
90
91 fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
98}
99
100pub trait RepositoryAccess: Send {
116 type Error: std::error::Error + Send + Sync + 'static;
118
119 fn upstream_oauth_link<'c>(
121 &'c mut self,
122 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c>;
123
124 fn upstream_oauth_provider<'c>(
126 &'c mut self,
127 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c>;
128
129 fn upstream_oauth_session<'c>(
131 &'c mut self,
132 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c>;
133
134 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c>;
136
137 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c>;
139
140 fn user_password<'c>(&'c mut self)
142 -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c>;
143
144 fn user_recovery<'c>(&'c mut self)
146 -> Box<dyn UserRecoveryRepository<Error = Self::Error> + 'c>;
147
148 fn user_registration<'c>(
150 &'c mut self,
151 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c>;
152
153 fn user_registration_token<'c>(
155 &'c mut self,
156 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c>;
157
158 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c>;
160
161 fn browser_session<'c>(
163 &'c mut self,
164 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c>;
165
166 fn app_session<'c>(&'c mut self) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c>;
168
169 fn oauth2_client<'c>(&'c mut self)
171 -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c>;
172
173 fn oauth2_authorization_grant<'c>(
175 &'c mut self,
176 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c>;
177
178 fn oauth2_session<'c>(
180 &'c mut self,
181 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c>;
182
183 fn oauth2_access_token<'c>(
185 &'c mut self,
186 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c>;
187
188 fn oauth2_refresh_token<'c>(
190 &'c mut self,
191 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c>;
192
193 fn oauth2_device_code_grant<'c>(
195 &'c mut self,
196 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c>;
197
198 fn compat_session<'c>(
200 &'c mut self,
201 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c>;
202
203 fn compat_sso_login<'c>(
205 &'c mut self,
206 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c>;
207
208 fn compat_access_token<'c>(
210 &'c mut self,
211 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c>;
212
213 fn compat_refresh_token<'c>(
215 &'c mut self,
216 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c>;
217
218 fn personal_access_token<'c>(
220 &'c mut self,
221 ) -> Box<dyn PersonalAccessTokenRepository<Error = Self::Error> + 'c>;
222
223 fn personal_session<'c>(
225 &'c mut self,
226 ) -> Box<dyn PersonalSessionRepository<Error = Self::Error> + 'c>;
227
228 fn queue_worker<'c>(&'c mut self) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c>;
230
231 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c>;
233
234 fn queue_schedule<'c>(
236 &'c mut self,
237 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c>;
238
239 fn policy_data<'c>(&'c mut self) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c>;
241}
242
243mod impls {
246 use futures_util::{FutureExt, TryFutureExt, future::BoxFuture};
247
248 use super::RepositoryAccess;
249 use crate::{
250 MapErr, Repository, RepositoryTransaction,
251 app_session::AppSessionRepository,
252 compat::{
253 CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
254 CompatSsoLoginRepository,
255 },
256 oauth2::{
257 OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository,
258 OAuth2ClientRepository, OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository,
259 OAuth2SessionRepository,
260 },
261 personal::{PersonalAccessTokenRepository, PersonalSessionRepository},
262 policy_data::PolicyDataRepository,
263 queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
264 upstream_oauth2::{
265 UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
266 UpstreamOAuthSessionRepository,
267 },
268 user::{
269 BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
270 UserRegistrationRepository, UserRegistrationTokenRepository, UserRepository,
271 UserTermsRepository,
272 },
273 };
274
275 impl<R, F, E1, E2> Repository<E2> for MapErr<R, F>
277 where
278 R: Repository<E1> + RepositoryAccess<Error = E1> + RepositoryTransaction<Error = E1>,
279 F: FnMut(E1) -> E2 + Send + Sync + 'static,
280 E1: std::error::Error + Send + Sync + 'static,
281 E2: std::error::Error + Send + Sync + 'static,
282 {
283 }
284
285 impl<R, F, E> RepositoryTransaction for MapErr<R, F>
287 where
288 R: RepositoryTransaction,
289 R::Error: 'static,
290 F: FnMut(R::Error) -> E + Send + Sync + 'static,
291 E: std::error::Error,
292 {
293 type Error = E;
294
295 fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
296 Box::new(self.inner).save().map_err(self.mapper).boxed()
297 }
298
299 fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
300 Box::new(self.inner).cancel().map_err(self.mapper).boxed()
301 }
302 }
303
304 impl<R, F, E> RepositoryAccess for MapErr<R, F>
306 where
307 R: RepositoryAccess,
308 R::Error: 'static,
309 F: FnMut(R::Error) -> E + Send + Sync + 'static,
310 E: std::error::Error + Send + Sync + 'static,
311 {
312 type Error = E;
313
314 fn upstream_oauth_link<'c>(
315 &'c mut self,
316 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
317 Box::new(MapErr::new(
318 self.inner.upstream_oauth_link(),
319 &mut self.mapper,
320 ))
321 }
322
323 fn upstream_oauth_provider<'c>(
324 &'c mut self,
325 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
326 Box::new(MapErr::new(
327 self.inner.upstream_oauth_provider(),
328 &mut self.mapper,
329 ))
330 }
331
332 fn upstream_oauth_session<'c>(
333 &'c mut self,
334 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
335 Box::new(MapErr::new(
336 self.inner.upstream_oauth_session(),
337 &mut self.mapper,
338 ))
339 }
340
341 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
342 Box::new(MapErr::new(self.inner.user(), &mut self.mapper))
343 }
344
345 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
346 Box::new(MapErr::new(self.inner.user_email(), &mut self.mapper))
347 }
348
349 fn user_password<'c>(
350 &'c mut self,
351 ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
352 Box::new(MapErr::new(self.inner.user_password(), &mut self.mapper))
353 }
354
355 fn user_recovery<'c>(
356 &'c mut self,
357 ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
358 Box::new(MapErr::new(self.inner.user_recovery(), &mut self.mapper))
359 }
360
361 fn user_registration<'c>(
362 &'c mut self,
363 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
364 Box::new(MapErr::new(
365 self.inner.user_registration(),
366 &mut self.mapper,
367 ))
368 }
369
370 fn user_registration_token<'c>(
371 &'c mut self,
372 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
373 Box::new(MapErr::new(
374 self.inner.user_registration_token(),
375 &mut self.mapper,
376 ))
377 }
378
379 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
380 Box::new(MapErr::new(self.inner.user_terms(), &mut self.mapper))
381 }
382
383 fn browser_session<'c>(
384 &'c mut self,
385 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
386 Box::new(MapErr::new(self.inner.browser_session(), &mut self.mapper))
387 }
388
389 fn app_session<'c>(
390 &'c mut self,
391 ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
392 Box::new(MapErr::new(self.inner.app_session(), &mut self.mapper))
393 }
394
395 fn oauth2_client<'c>(
396 &'c mut self,
397 ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
398 Box::new(MapErr::new(self.inner.oauth2_client(), &mut self.mapper))
399 }
400
401 fn oauth2_authorization_grant<'c>(
402 &'c mut self,
403 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
404 Box::new(MapErr::new(
405 self.inner.oauth2_authorization_grant(),
406 &mut self.mapper,
407 ))
408 }
409
410 fn oauth2_session<'c>(
411 &'c mut self,
412 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
413 Box::new(MapErr::new(self.inner.oauth2_session(), &mut self.mapper))
414 }
415
416 fn oauth2_access_token<'c>(
417 &'c mut self,
418 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
419 Box::new(MapErr::new(
420 self.inner.oauth2_access_token(),
421 &mut self.mapper,
422 ))
423 }
424
425 fn oauth2_refresh_token<'c>(
426 &'c mut self,
427 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
428 Box::new(MapErr::new(
429 self.inner.oauth2_refresh_token(),
430 &mut self.mapper,
431 ))
432 }
433
434 fn oauth2_device_code_grant<'c>(
435 &'c mut self,
436 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
437 Box::new(MapErr::new(
438 self.inner.oauth2_device_code_grant(),
439 &mut self.mapper,
440 ))
441 }
442
443 fn compat_session<'c>(
444 &'c mut self,
445 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
446 Box::new(MapErr::new(self.inner.compat_session(), &mut self.mapper))
447 }
448
449 fn compat_sso_login<'c>(
450 &'c mut self,
451 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
452 Box::new(MapErr::new(self.inner.compat_sso_login(), &mut self.mapper))
453 }
454
455 fn compat_access_token<'c>(
456 &'c mut self,
457 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
458 Box::new(MapErr::new(
459 self.inner.compat_access_token(),
460 &mut self.mapper,
461 ))
462 }
463
464 fn compat_refresh_token<'c>(
465 &'c mut self,
466 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
467 Box::new(MapErr::new(
468 self.inner.compat_refresh_token(),
469 &mut self.mapper,
470 ))
471 }
472
473 fn personal_access_token<'c>(
474 &'c mut self,
475 ) -> Box<dyn PersonalAccessTokenRepository<Error = Self::Error> + 'c> {
476 Box::new(MapErr::new(
477 self.inner.personal_access_token(),
478 &mut self.mapper,
479 ))
480 }
481
482 fn personal_session<'c>(
483 &'c mut self,
484 ) -> Box<dyn PersonalSessionRepository<Error = Self::Error> + 'c> {
485 Box::new(MapErr::new(self.inner.personal_session(), &mut self.mapper))
486 }
487
488 fn queue_worker<'c>(
489 &'c mut self,
490 ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
491 Box::new(MapErr::new(self.inner.queue_worker(), &mut self.mapper))
492 }
493
494 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
495 Box::new(MapErr::new(self.inner.queue_job(), &mut self.mapper))
496 }
497
498 fn queue_schedule<'c>(
499 &'c mut self,
500 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
501 Box::new(MapErr::new(self.inner.queue_schedule(), &mut self.mapper))
502 }
503
504 fn policy_data<'c>(
505 &'c mut self,
506 ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
507 Box::new(MapErr::new(self.inner.policy_data(), &mut self.mapper))
508 }
509 }
510
511 impl<R: RepositoryAccess + ?Sized> RepositoryAccess for Box<R> {
512 type Error = R::Error;
513
514 fn upstream_oauth_link<'c>(
515 &'c mut self,
516 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
517 (**self).upstream_oauth_link()
518 }
519
520 fn upstream_oauth_provider<'c>(
521 &'c mut self,
522 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
523 (**self).upstream_oauth_provider()
524 }
525
526 fn upstream_oauth_session<'c>(
527 &'c mut self,
528 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
529 (**self).upstream_oauth_session()
530 }
531
532 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
533 (**self).user()
534 }
535
536 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
537 (**self).user_email()
538 }
539
540 fn user_password<'c>(
541 &'c mut self,
542 ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
543 (**self).user_password()
544 }
545
546 fn user_recovery<'c>(
547 &'c mut self,
548 ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
549 (**self).user_recovery()
550 }
551
552 fn user_registration<'c>(
553 &'c mut self,
554 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
555 (**self).user_registration()
556 }
557
558 fn user_registration_token<'c>(
559 &'c mut self,
560 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
561 (**self).user_registration_token()
562 }
563
564 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
565 (**self).user_terms()
566 }
567
568 fn browser_session<'c>(
569 &'c mut self,
570 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
571 (**self).browser_session()
572 }
573
574 fn app_session<'c>(
575 &'c mut self,
576 ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
577 (**self).app_session()
578 }
579
580 fn oauth2_client<'c>(
581 &'c mut self,
582 ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
583 (**self).oauth2_client()
584 }
585
586 fn oauth2_authorization_grant<'c>(
587 &'c mut self,
588 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
589 (**self).oauth2_authorization_grant()
590 }
591
592 fn oauth2_session<'c>(
593 &'c mut self,
594 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
595 (**self).oauth2_session()
596 }
597
598 fn oauth2_access_token<'c>(
599 &'c mut self,
600 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
601 (**self).oauth2_access_token()
602 }
603
604 fn oauth2_refresh_token<'c>(
605 &'c mut self,
606 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
607 (**self).oauth2_refresh_token()
608 }
609
610 fn oauth2_device_code_grant<'c>(
611 &'c mut self,
612 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
613 (**self).oauth2_device_code_grant()
614 }
615
616 fn compat_session<'c>(
617 &'c mut self,
618 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
619 (**self).compat_session()
620 }
621
622 fn compat_sso_login<'c>(
623 &'c mut self,
624 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
625 (**self).compat_sso_login()
626 }
627
628 fn compat_access_token<'c>(
629 &'c mut self,
630 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
631 (**self).compat_access_token()
632 }
633
634 fn compat_refresh_token<'c>(
635 &'c mut self,
636 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
637 (**self).compat_refresh_token()
638 }
639
640 fn personal_access_token<'c>(
641 &'c mut self,
642 ) -> Box<dyn PersonalAccessTokenRepository<Error = Self::Error> + 'c> {
643 (**self).personal_access_token()
644 }
645
646 fn personal_session<'c>(
647 &'c mut self,
648 ) -> Box<dyn PersonalSessionRepository<Error = Self::Error> + 'c> {
649 (**self).personal_session()
650 }
651
652 fn queue_worker<'c>(
653 &'c mut self,
654 ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
655 (**self).queue_worker()
656 }
657
658 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
659 (**self).queue_job()
660 }
661
662 fn queue_schedule<'c>(
663 &'c mut self,
664 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
665 (**self).queue_schedule()
666 }
667
668 fn policy_data<'c>(
669 &'c mut self,
670 ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
671 (**self).policy_data()
672 }
673 }
674}