| .vscode | ||
| example | ||
| macros | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
rspc
Proof of concept RPC framework focused on ease of use.
It works by calling the macro #[rspc::service] on an impl block,
and code is generated for the resulting Server and Client objects.
The Server objects own the original struct data and implements listen functions.
The Client objects must be provided a connection, and replicates all the functions of the impl block where the macro was called.
The Server implements read-write locking, there can be many reads at once, but only one write. Requests are not errored upon write-lock, but instead waited for.
The Client object cannot be cloned. Instead all function calls are immutable, so a reference can be shared to all.
Currently only implements local thread messaging. Serialized TCP transport is unfinished.
Example:
use rspc::transport::{channel, ClientTransporter,ServerTransporter};
use rspc::service;
use serde::{Deserialize, Serialize};
#[derive(Serialize,Deserialize)]
pub struct MyStruct {
my_vec: Vec<String>,
}
#[service]
impl MyStruct
{
pub fn len(&self) -> usize {
self.my_vec.len()
}
pub fn push(&mut self, val: String) {
self.my_vec.push(val)
}
pub fn pop(&mut self) -> Option<String> {
self.my_vec.pop()
}
}
#[tokio::test]
async fn test() {
let my_data = MyStruct {
my_vec: Vec::new(),
};
let (c,s) = channel::new_async();
let srv_thread = tokio::spawn(async move {
let mut server = MyDataServer::from(my_data);
server.listen(s).await
} );
let client = MyStructClient::new(c);
assert_eq!(client.len().await.unwrap(), 0);
client.push("Hello world!".to_string()).await.unwrap();
assert_eq!(client.len().await.unwrap(), 1);
assert_eq!(client.pop().await.unwrap(), Some("Hello world!".to_string()));
client.stop().await.unwrap();
srv_thread.await.unwrap().unwrap();
}
See example for an more detailed example usage