krpc 0.2.0

A asynchronous RPC library(include client and server) which can use easly and communicate by tokio unix/tcp socket
Documentation
use krpc::*;
use tokio::time;

struct MySub;
impl SubcribeCallback<(String, i32)> for MySub {
	fn callback(&mut self, data: (String, i32)) -> bool {
		assert_eq!(&data.0, "hello");
		assert_eq!(data.1, 100i32);
		false
	}
}

async fn start_server(addr: &str) -> std::io::Result<()> {
	let mut service = Server::new();
	service.bind(
		"test_notargs_and_notret",
		callback!(|| {
			println!("test_notargs_and_notret called");
		}),
	);
	service.bind(
		"test_notret",
		callback!(|s: String| {
			println!("str is {}", s);
		}),
	);
	service.bind("test_notargs", callback!(|| -> String { String::from("test_notargs called!") }));
	service.bind(
		"test_has_args_and_ret",
		callback!(|a0: i32, a1: i16, a2: i8, a3: bool| -> String { format!("{} {} {} {}", a0, a1, a2, a3) }),
	);
	let publisher = service.publisher();
	tokio::spawn(async move {
		let mut interval = time::interval(time::Duration::from_secs(1));
		loop {
			publisher.push("sub", ("hello", 100));
			interval.tick().await;
		}
	});
	service.run(addr).await
}

#[tokio::test]
async fn test_call_macro() -> Result<(), Error> {
	let task = tokio::spawn(async move {
		let _ = start_server("/tmp/local/unix").await;
	});
	time::sleep(time::Duration::new(1, 0)).await;
	let _ = call!(unix, "/tmp/local/unix", test_notargs_and_notret()).await?;
	let _ = call!(unix, "/tmp/local/unix", test_notret("hello client")).await?;
	let ret = call!(unix, "/tmp/local/unix", test_notargs() -> String).await?;
	assert_eq!(&ret, "test_notargs called!");
	let ret = call!(unix, "/tmp/local/unix", test_has_args_and_ret(10000, 1000, 10, true) -> String).await?;
	assert_eq!(&ret, "10000 1000 10 true");
	task.abort();
	Ok(())
}

#[tokio::test]
async fn test_subcribe_macro() -> Result<(), Error> {
	let task = tokio::spawn(async move {
		let _ = start_server("/tmp/local/unix").await;
	});
	time::sleep(time::Duration::new(1, 0)).await;
	let mut sub = MySub;
	//test subcribe with trait
	subcribe!(unix, "/tmp/local/unix", "sub", &mut sub).await?;
	let task2 = tokio::spawn(async move {
		//test subcribe with lambda
		subcribe!(unix, "/tmp/local/unix", "sub", |s: String, v: i32| {
			assert_eq!(&s, "hello");
			assert_eq!(v, 100i32);
		})
		.await
	});
	time::sleep(time::Duration::new(2, 0)).await;
	task2.abort();
	task.abort();
	Ok(())
}

define!(unix, RPC1,
	fn test_notargs_and_notret(),
	fn test_notret(s:&'static str),
	fn test_notargs()->String,
	fn test_has_args_and_ret(a:i32,b:i16,c:i8,d:bool)->String,
	sub sub(topic:&'static str, v:&mut MySub)
);

define!(unix, RPC2,
	sub sub1(topic:&'static str, f:impl FnMut((String,i32))),
	sub sub2(topic:&'static str, v:&mut MySub)
);

#[tokio::test]
async fn test_client_server() -> Result<(), Error> {
	let task = tokio::spawn(async move {
		let _ = start_server("/tmp/local/unix").await;
	});
	time::sleep(time::Duration::new(1, 0)).await;
	let rpc = RPC1::new("/tmp/local/unix").await?;
	let _ = rpc.test_notargs_and_notret().await?;
	let _ = rpc.test_notret("hello client").await?;
	let ret = rpc.test_notargs().await?;
	assert_eq!(&ret, "test_notargs called!");
	let ret = rpc.test_has_args_and_ret(10000, 1000, 10, true).await?;
	assert_eq!(&ret, "10000 1000 10 true");

	let mut v = MySub;
	rpc.sub("sub", &mut v).await?;
	task.abort();
	Ok(())
}

#[tokio::test]
async fn test_multi_subcribe() -> Result<(), Error> {
	let task = tokio::spawn(async move {
		let _ = start_server("/tmp/local/unix").await;
	});
	time::sleep(time::Duration::new(1, 0)).await;
	let rpc = RPC2::new("/tmp/local/unix").await?;
	let mut v = MySub;
	let _ = rpc.sub2("sub", &mut v).await?;
	let task2 = tokio::spawn(async move {
		rpc.sub1("sub", |(s, id)| {
			assert_eq!(&s, "hello");
			assert_eq!(id, 100i32);
		})
		.await
	});
	time::sleep(time::Duration::new(3, 0)).await;
	task2.abort();
	task.abort();
	Ok(())
}