flow_lib/utils/
tower_client.rs

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