Skip to main content

flow_lib/utils/
tower_client.rs

1use actix::MailboxError;
2use serde::{Deserialize, Serialize};
3use serde_with::serde_as;
4use std::{
5    error::Error as StdError,
6    fmt::{Debug, Display},
7    future::ready,
8    sync::Arc,
9};
10use thiserror::Error as ThisError;
11use tower::{service_fn, util::BoxCloneSyncService};
12
13pub type TowerClient<T, U, E> = BoxCloneSyncService<T, U, E>;
14
15#[serde_as]
16#[derive(Clone, Debug, ThisError, Serialize, Deserialize)]
17pub enum CommonError {
18    #[error("unimplemented")]
19    Unimplemented,
20    #[error(transparent)]
21    MailBox(
22        #[from]
23        #[serde_as(as = "crate::errors::AsMailboxError")]
24        MailboxError,
25    ),
26    #[error(transparent)]
27    Other(#[serde_as(as = "Arc<crate::errors::AsAnyhow>")] Arc<anyhow::Error>),
28}
29
30pub trait FromAnyhow: Sized {
31    fn from_anyhow(e: anyhow::Error) -> Self;
32}
33
34pub fn unimplemented_svc<T, U, E>() -> TowerClient<T, U, E>
35where
36    E: From<CommonError> + Send + 'static,
37    U: Send + 'static,
38{
39    TowerClient::new(service_fn(|_| {
40        ready(Err(CommonError::Unimplemented.into()))
41    }))
42}
43
44pub trait CommonErrorExt {
45    fn msg<M: Display + Debug + Send + Sync + 'static>(msg: M) -> Self;
46    fn other<E: StdError + Send + Sync + 'static>(error: E) -> Self;
47    fn from_anyhow(e: anyhow::Error) -> Self;
48    fn from_boxed(error: Box<dyn StdError + Send + Sync + 'static>) -> Self;
49}
50
51impl<S> CommonErrorExt for S
52where
53    S: From<CommonError> + Display + Debug + Send + Sync + 'static,
54{
55    fn msg<M: Display + Debug + Send + Sync + 'static>(msg: M) -> Self {
56        CommonError::Other(Arc::new(anyhow::Error::msg(msg))).into()
57    }
58
59    fn other<E: StdError + Send + Sync + 'static>(error: E) -> Self {
60        CommonError::Other(Arc::new(anyhow::Error::new(error))).into()
61    }
62
63    fn from_boxed(error: Box<dyn StdError + Send + Sync + 'static>) -> Self {
64        CommonError::Other(Arc::new(anyhow::Error::from_boxed(error))).into()
65    }
66
67    fn from_anyhow(e: anyhow::Error) -> Self {
68        e.downcast::<Self>()
69            .unwrap_or_else(|error| CommonError::Other(Arc::new(error)).into())
70    }
71}