use std::sync::Arc;
use rapace::prelude::*;
use rapace_core::RpcSession;
#[allow(async_fn_in_trait)]
#[rapace::service]
pub trait Calculator {
async fn add(&self, a: i32, b: i32) -> i32;
async fn multiply(&self, a: i32, b: i32) -> i32;
async fn range(&self, n: u32) -> Streaming<u32>;
}
struct CalculatorImpl;
impl Calculator for CalculatorImpl {
async fn add(&self, a: i32, b: i32) -> i32 {
a + b
}
async fn multiply(&self, a: i32, b: i32) -> i32 {
a * b
}
async fn range(&self, n: u32) -> Streaming<u32> {
let (tx, rx) = tokio::sync::mpsc::channel(16);
tokio::spawn(async move {
for i in 0..n {
if tx.send(Ok(i)).await.is_err() {
break; }
}
});
Box::pin(tokio_stream::wrappers::ReceiverStream::new(rx))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (client_transport, server_transport) = rapace::Transport::mem_pair();
let client_transport = client_transport;
let server_transport = server_transport;
let server = CalculatorServer::new(CalculatorImpl);
let server_handle = tokio::spawn(server.serve(server_transport));
let session = RpcSession::new(client_transport.clone());
let client = CalculatorClient::new(Arc::new(session));
println!("Calling add(2, 3)...");
let sum = client.add(2, 3).await?;
println!(" Result: {}", sum);
println!("\nCalling multiply(4, 5)...");
let product = client.multiply(4, 5).await?;
println!(" Result: {}", product);
println!("\nCalling range(5)...");
let mut stream = client.range(5).await?;
use tokio_stream::StreamExt;
print!(" Stream items: ");
while let Some(item) = stream.next().await {
match item {
Ok(n) => print!("{} ", n),
Err(e) => eprintln!("Stream error: {}", e),
}
}
println!();
client_transport.close();
server_handle.abort();
println!("\nDone!");
Ok(())
}