use alloy_json_rpc::{Response, ResponsePayload, SerializedRequest, SubId};
use alloy_transport::{TransportError, TransportResult};
use std::fmt;
use tokio::sync::oneshot;
pub struct InFlight {
pub request: SerializedRequest,
pub channel_size: usize,
pub tx: oneshot::Sender<TransportResult<Response>>,
}
impl fmt::Debug for InFlight {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InFlight")
.field("request", &self.request)
.field("channel_size", &self.channel_size)
.field("tx_is_closed", &self.tx.is_closed())
.finish()
}
}
impl InFlight {
pub fn new(
request: SerializedRequest,
channel_size: usize,
) -> (Self, oneshot::Receiver<TransportResult<Response>>) {
let (tx, rx) = oneshot::channel();
(Self { request, channel_size, tx }, rx)
}
pub fn is_subscription(&self) -> bool {
self.request.is_subscription()
}
pub const fn request(&self) -> &SerializedRequest {
&self.request
}
pub fn fulfill(self, resp: Response) -> Option<(SubId, Self)> {
if self.is_subscription() {
if let ResponsePayload::Success(val) = resp.payload {
let sub_id: serde_json::Result<SubId> = serde_json::from_str(val.get());
return match sub_id {
Ok(alias) => Some((alias, self)),
Err(e) => {
let _ = self.tx.send(Err(TransportError::deser_err(e, val.get())));
None
}
};
}
}
let _ = self.tx.send(Ok(resp));
None
}
}