use std::io;
use std::time::Duration;
use ruststream::codec::{Codec, JsonCodec};
use ruststream::runtime::{
App, AppInfo, Outgoing, PublishContext, PublishTransform, RustStream, TypedPublisher,
};
use ruststream::{IncomingMessage, OutgoingMessage, RequestReply, subscriber};
use ruststream_zeromq::{ZmqEndpoint, ZmqRpc, ZmqRpcPublish};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
struct Greeting {
who: String,
}
#[derive(Debug, Deserialize, Serialize)]
struct Reply {
text: String,
}
struct ReplyToRequester;
impl<C> PublishTransform<C> for ReplyToRequester {
fn apply(&self, out: &mut Outgoing<'_>, cx: &PublishContext<'_, C>) {
if let Some(reply_to) = cx.headers().reply_to() {
out.set_name(reply_to.to_owned());
}
if let Some(correlation) = cx.headers().correlation_id() {
out.headers_mut()
.insert("correlation-id", correlation.to_owned());
}
}
}
#[subscriber("greeter", publish("reply"))]
async fn greet(request: &Greeting) -> Reply {
Reply {
text: format!("hello {}", request.who),
}
}
#[ruststream::app]
fn app() -> impl App {
RustStream::new(AppInfo::new("greeter", "0.1.0")).with_broker(
ZmqRpc::new(ZmqEndpoint::bind("tcp://127.0.0.1:0")),
|b| {
b.include(greet)
.publisher(TypedPublisher::new(ZmqRpcPublish).transform(ReplyToRequester));
b.after_startup(ZmqRpcPublish, async move |publisher| -> io::Result<()> {
let request = JsonCodec
.encode(&Greeting {
who: "world".to_owned(),
})
.map_err(io::Error::other)?;
let answer = publisher
.request(
OutgoingMessage::new("greeter", request.as_ref()),
Duration::from_secs(5),
)
.await
.map_err(io::Error::other)?;
let answer: Reply = JsonCodec
.decode(answer.payload())
.map_err(io::Error::other)?;
println!("reply: {}", answer.text);
Ok(())
});
},
)
}