use futures::{channel::mpsc, executor, Future, SinkExt};
use thiserror::Error;
use std::fmt;
use crate::messages::{AnyTx, Verified};
pub struct ApiSender<T = Verified<AnyTx>>(mpsc::Sender<T>);
impl<T> Clone for ApiSender<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: Send + 'static> ApiSender<T> {
pub fn new(inner: mpsc::Sender<T>) -> Self {
Self(inner)
}
pub fn closed() -> Self {
Self(mpsc::channel(0).0)
}
pub async fn send_message(&mut self, message: T) -> Result<(), SendError> {
self.0.send(message).await.map_err(|_| SendError(()))
}
pub fn send_message_blocking(&self, message: T) -> Result<(), SendError> {
let mut this = self.clone();
executor::block_on(async move { this.send_message(message).await })
}
}
impl ApiSender {
pub fn broadcast_transaction(
&self,
tx: Verified<AnyTx>,
) -> impl Future<Output = Result<(), SendError>> {
let mut this = self.clone();
async move { this.send_message(tx).await }
}
pub fn broadcast_transaction_blocking(&self, tx: Verified<AnyTx>) -> Result<(), SendError> {
self.send_message_blocking(tx)
}
}
impl<T> fmt::Debug for ApiSender<T> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.debug_tuple("ApiSender").field(&"..").finish()
}
}
#[derive(Debug, Error)]
#[error("Failed to send API request to the node: the node is being shut down")]
pub struct SendError(());