1use crate::{Session, StratumRequest};
2use async_trait::async_trait;
3use futures::Future;
4use tracing::error;
5
6pub(crate) type DynEndpoint<State, CState> = dyn Endpoint<State, CState>;
7
8#[async_trait]
9pub trait Endpoint<State: Clone, CState: Clone>: Send + Sync + 'static {
10 async fn call(
11 &self,
12 req: StratumRequest<State>,
13 connection: Session<CState>,
14 ) -> serde_json::Value;
15}
16
17#[async_trait]
18impl<State, CState, F, Fut, Res, E> Endpoint<State, CState> for F
19where
20 State: Clone + Send + Sync + 'static,
21 CState: Clone + Send + Sync + 'static,
22 F: Send + Sync + 'static + Fn(StratumRequest<State>, Session<CState>) -> Fut,
23 Fut: Future<Output = std::result::Result<Res, E>> + Send + 'static,
24 E: std::error::Error + 'static + std::marker::Send,
25 Res: Into<serde_json::Value> + 'static + std::marker::Send,
26{
27 async fn call(
28 &self,
29 req: StratumRequest<State>,
30 connection: Session<CState>,
31 ) -> serde_json::Value {
32 let fut = (self)(req, connection.clone());
33
34 match fut.await {
35 Ok(response) => response.into(),
36 Err(e) => {
37 error!(
38 connection_id = connection.id().to_string(),
39 error.cause_chain = ?e,
40 error.message = %e,
41 "Request failed disconnecting miner"
42 );
43
44 connection.disconnect();
46 serde_json::Value::Null
47 }
48 }
49 }
50}