util.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #![allow(clippy::type_complexity)]
  2. use crate::event_map::{FolderCouldServiceV1, WorkspaceUser};
  3. use lib_infra::retry::Action;
  4. use pin_project::pin_project;
  5. use std::{
  6. future::Future,
  7. marker::PhantomData,
  8. pin::Pin,
  9. sync::Arc,
  10. task::{Context, Poll},
  11. };
  12. pub(crate) type Builder<Fut> =
  13. Box<dyn Fn(String, Arc<dyn FolderCouldServiceV1>) -> Fut + Send + Sync>;
  14. #[allow(dead_code)]
  15. pub(crate) struct RetryAction<Fut, T, E> {
  16. token: String,
  17. cloud_service: Arc<dyn FolderCouldServiceV1>,
  18. user: Arc<dyn WorkspaceUser>,
  19. builder: Builder<Fut>,
  20. phantom: PhantomData<(T, E)>,
  21. }
  22. impl<Fut, T, E> RetryAction<Fut, T, E> {
  23. #[allow(dead_code)]
  24. pub(crate) fn new<F>(
  25. cloud_service: Arc<dyn FolderCouldServiceV1>,
  26. user: Arc<dyn WorkspaceUser>,
  27. builder: F,
  28. ) -> Self
  29. where
  30. Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
  31. F: Fn(String, Arc<dyn FolderCouldServiceV1>) -> Fut + Send + Sync + 'static,
  32. {
  33. let token = user.token().unwrap_or_else(|_| "".to_owned());
  34. Self {
  35. token,
  36. cloud_service,
  37. user,
  38. builder: Box::new(builder),
  39. phantom: PhantomData,
  40. }
  41. }
  42. }
  43. impl<Fut, T, E> Action for RetryAction<Fut, T, E>
  44. where
  45. Fut: Future<Output = Result<T, E>> + Send + Sync + 'static,
  46. T: Send + Sync + 'static,
  47. E: Send + Sync + 'static,
  48. {
  49. type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send + Sync>>;
  50. type Item = T;
  51. type Error = E;
  52. fn run(&mut self) -> Self::Future {
  53. let fut = (self.builder)(self.token.clone(), self.cloud_service.clone());
  54. Box::pin(RetryActionFut { fut: Box::pin(fut) })
  55. }
  56. }
  57. #[pin_project]
  58. struct RetryActionFut<T, E> {
  59. #[pin]
  60. fut: Pin<Box<dyn Future<Output = Result<T, E>> + Send + Sync>>,
  61. }
  62. impl<T, E> Future for RetryActionFut<T, E>
  63. where
  64. T: Send + Sync + 'static,
  65. E: Send + Sync + 'static,
  66. {
  67. type Output = Result<T, E>;
  68. fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  69. let mut this = self.project();
  70. this.fut.as_mut().poll(cx)
  71. }
  72. }