| Crates.io | libzrpc |
| lib.rs | libzrpc |
| version | 0.1.1 |
| created_at | 2025-03-08 09:44:28.942624+00 |
| updated_at | 2025-03-20 14:59:21.370094+00 |
| description | A RPC library for Rust |
| homepage | |
| repository | https://github.com/BIERTONSTAFF/libzrpc |
| max_upload_size | |
| id | 1584262 |
| size | 30,797 |
ZRPC is a library for creating Remote Procedure Calls (RPC) in Rust, which allows you to easily set up a server and client for data exchange. Below is a quick guide to the main aspects of using ZRPC with code examples.
ZRpcDt is an enumeration that represents various data types used in RPC calls. It includes:Int32(i32) — an interger.Float32(f32) — a floating-point number.String(String) — a string.Serialized(Vec<u8>) — serialized data as byte vector.Error(ErrorKind) — an error that may occur during call processing.Code Example:
fn add(p: &Vec<ZRpcDt>) -> Result<ZRpcDt, ProcedureError> {
match (&p[1], &p[2]) {
(ZRpcDt::Int32(a), ZRpcDt::Int32(b)) => proc_ok!(a + b),
_ => proc_err!(InvalidParameters),
}
}
User {..}.to_zdt() => ZRpcDt::Serialized([..])
fn user_info(p: &Vec<ZRpcDt>) -> Result<ZRpcDt, ProcedureError> {
match &p[0] {
ZRpcDt::Serialized(_) => {
let user = p[0]
.deserialize::<User>()
.expect("Failed to deserialize User");
proc_ok!(format!("Name: {}, age: {}", user.name, user.age))
}
_ => proc_err!(InvalidParameters),
}
}
ErrorKind is used to define various errors that may occur during RPC execution:ProcedureNotFound — the called procedure was not found.InvalidParameters — invalid parameters were passed.InternalError — an internal server error.Code Example:
fn mul(p: &Vec<ZRpcDt>) -> Result<ZRpcDt, ProcedureError> {
match (&p[0], &p[1]) {
(ZRpcDt::Float(a), ZRpcDt::Float(b)) => proc_ok!(a * b),
_ => proc_err!(InvalidParameters),
}
}
ZRpcServer, which listens for incoming connections.Code Example:
#[tokio::main]
async fn main() {
let mut server = ZRpcServer::new((Ipv4Addr::LOCALHOST, 3000)).await.unwrap();
/* Adding middleware */
server
.add_middleware(AuthMiddleware {
api_key: "SECRET_KEY".to_string(),
})
.await;
/* Adding procedures */
add_procs!(server, add, mul, user_info);
server.start().await.unwrap()
}
ZRpcClient, which establishes a connection to the server.Code Example:
let mut client = ZRpcClient::new((Ipv4Addr::LOCALHOST, 3000)).await.unwrap();
call method is used. Requests are serialized and sent to the server, after which the client waits for a response.Code Example:
match client.call("add", params!("SECRET_KEY", 2, 2)).await {
Ok(ZRpcDt::Int32(res)) => println!("Sum: {}", res),
Err(e) => eprintln!("{}", e),
_ => {}
}
pub struct AuthMiddleware {
api_key: String,
}
impl Middleware for AuthMiddleware {
fn before_call(&self, req: &libzrpc::types::req::ZRpcReq) -> Result<(), MiddlewareError> {
if let Some(ZRpcDt::String(key)) = req.1.first() {
if key == &self.api_key {
Ok(())
} else {
middleware_err!("Unauthorized")
}
} else {
middleware_err!("Missing apiKey")
}
}
}
To initialize a request parameters, you can also use params!() macro:
let _ = client.call("procedure_name", params!(..)));
params!("Hello, World", 1, 3.14) => vec![ZRpcDt::String("Hello, World".to_string()), ZRpcDt::Int8(1), ZRpcDt::Float(3.14)]
Example:
1.to_zdt() => ZRpcDt::Int8(1)
3.14.to_zdt() => ZRpcDt::Float32(3.14)