use std::marker::PhantomData;
use serde::{de::DeserializeOwned, Serialize};
use crate::{codec::CodecType, error::Result};
use super::stream::{Stream, StreamBuilder};
#[derive(Clone)]
pub struct JetStreamContext<C: CodecType> {
inner: async_nats::jetstream::Context,
_codec: PhantomData<C>,
}
impl<C: CodecType> JetStreamContext<C> {
pub(crate) fn new(inner: async_nats::jetstream::Context) -> Self {
Self {
inner,
_codec: PhantomData,
}
}
pub fn inner(&self) -> &async_nats::jetstream::Context {
&self.inner
}
pub fn stream_builder(&self, name: &str) -> StreamBuilder<C> {
StreamBuilder::new(self.inner.clone(), name.to_string())
}
pub async fn get_stream(&self, name: &str) -> Result<Stream<C>> {
let inner = self
.inner
.get_stream(name)
.await
.map_err(|e| crate::error::Error::JetStreamStream(e.to_string()))?;
Ok(Stream::new(inner))
}
pub async fn delete_stream(&self, name: &str) -> Result<()> {
self.inner
.delete_stream(name)
.await
.map_err(|e| crate::error::Error::JetStreamStream(e.to_string()))?;
Ok(())
}
pub async fn publish<T: Serialize>(&self, subject: &str, message: &T) -> Result<PublishAck> {
let data = C::encode(message)?;
let ack = self
.inner
.publish(subject.to_string(), data.into())
.await
.map_err(|e| crate::error::Error::JetStream(e.to_string()))?
.await
.map_err(|e| crate::error::Error::JetStream(e.to_string()))?;
Ok(PublishAck {
stream: ack.stream.to_string(),
sequence: ack.sequence,
duplicate: ack.duplicate,
})
}
pub async fn publish_async<T: Serialize>(
&self,
subject: &str,
message: &T,
) -> Result<PublishAckFuture> {
let data = C::encode(message)?;
let future = self
.inner
.publish(subject.to_string(), data.into())
.await
.map_err(|e| crate::error::Error::JetStream(e.to_string()))?;
Ok(PublishAckFuture { inner: future })
}
pub async fn request<T: Serialize, R: DeserializeOwned>(
&self,
subject: &str,
message: &T,
) -> Result<R> {
let data = C::encode(message)?;
let response: async_nats::Message = self
.inner
.request(subject.to_string(), &bytes::Bytes::from(data))
.await
.map_err(|e| crate::error::Error::JetStream(e.to_string()))?;
C::decode(&response.payload)
}
}
#[derive(Debug, Clone)]
pub struct PublishAck {
pub stream: String,
pub sequence: u64,
pub duplicate: bool,
}
pub struct PublishAckFuture {
inner: async_nats::jetstream::context::PublishAckFuture,
}
impl PublishAckFuture {
pub async fn await_ack(self) -> Result<PublishAck> {
let ack = self
.inner
.await
.map_err(|e| crate::error::Error::JetStream(e.to_string()))?;
Ok(PublishAck {
stream: ack.stream.to_string(),
sequence: ack.sequence,
duplicate: ack.duplicate,
})
}
}
impl std::future::IntoFuture for PublishAckFuture {
type Output = Result<PublishAck>;
type IntoFuture = std::pin::Pin<Box<dyn std::future::Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(self.await_ack())
}
}