use super::{DeliveredMessage, Shutdown, SubscriptionStream};
use crate::SdkError;
use crate::remote::mailbox::{BlockingTake, ReaderEnd};
use alloc::format;
use alloc::sync::Arc;
impl SubscriptionStream {
pub fn recv(&self) -> Result<DeliveredMessage, SdkError> {
match self.mailbox.take_blocking(false)? {
BlockingTake::Item(message) => Ok(message),
BlockingTake::Ended(ReaderEnd::Failed(error) | ReaderEnd::PeerClosed(error)) => {
Err(error)
}
BlockingTake::Abandoned | BlockingTake::Ended(ReaderEnd::Stopped) => {
Err(SdkError::Connection {
description: "subscription receive failed: the subscription was closed".into(),
})
}
}
}
pub fn close_handle(
&self,
) -> Result<impl Fn() -> Result<(), SdkError> + Send + Sync + use<>, SdkError> {
let socket = self
.writer
.try_clone()
.map_err(|error| SdkError::Connection {
description: format!("failed to clone subscription close signal: {error}"),
})?;
let mailbox = Arc::clone(&self.mailbox);
Ok(move || {
let abandoned = mailbox.abandon();
let shutdown = socket
.shutdown(Shutdown::Both)
.or_else(|error| {
if error.kind() == std::io::ErrorKind::NotConnected {
Ok(())
} else {
Err(error)
}
})
.map_err(|error| SdkError::Connection {
description: format!("failed to close subscription socket: {error}"),
});
abandoned.and(shutdown)
})
}
}
impl From<crate::WebSocketDeliveredMessage> for DeliveredMessage {
fn from(message: crate::WebSocketDeliveredMessage) -> Self {
Self {
delivery_seq: message.delivery_seq(),
schema_id: message.schema_id(),
message: message.message(),
payload: message.into_payload(),
}
}
}