| Crates.io | zenobuf-cli |
| lib.rs | zenobuf-cli |
| version | 0.3.3 |
| created_at | 2025-04-12 03:50:27.084566+00 |
| updated_at | 2025-07-29 04:12:56.079899+00 |
| description | Command-line tools for the Zenobuf framework - monitor topics, call services, manage parameters |
| homepage | https://github.com/varunkamath/zenobuf |
| repository | https://github.com/varunkamath/zenobuf |
| max_upload_size | |
| id | 1630602 |
| size | 139,474 |
A simple ROS-like framework in Rust, using Zenoh for transport and Protocol Buffers for serialization.
Zenobuf is a lightweight, ergonomic framework for building distributed systems in Rust. It provides a publish-subscribe messaging system, a service-based RPC system, and a parameter system, similar to ROS (Robot Operating System) but with a more Rust-idiomatic API.
protoc) 3.0 or laterAdd the following to your Cargo.toml:
[dependencies]
zenobuf-core = "0.1.0"
zenobuf-macros = "0.1.0"
Define your messages using Protocol Buffers:
syntax = "proto3";
package my_messages;
message Point {
float x = 1;
float y = 2;
float z = 3;
}
Step 1: Add dependencies to your Cargo.toml:
[dependencies]
zenobuf-core = "0.2"
zenobuf-macros = "0.2"
prost = "0.13"
tokio = { version = "1", features = ["full"] }
[build-dependencies]
prost-build = "0.13"
Step 2: Create a build.rs file that automatically adds the derive macro:
fn main() -> std::io::Result<()> {
prost_build::Config::new()
.type_attribute(".", "#[derive(zenobuf_macros::ZenobufMessage)]")
.compile_protos(&["protos/my_messages.proto"], &["protos"])?;
Ok(())
}
Step 3: Include the generated code in your lib.rs or main.rs:
pub mod proto {
include!(concat!(env!("OUT_DIR"), "/my_messages.rs"));
}
That's it! The ZenobufMessage derive macro is automatically added to all your protobuf types.
For the fastest way to get started, copy the starter template which includes:
Cargo.toml and build.rscp -r starter-template my-zenobuf-app
cd my-zenobuf-app
cargo run
use zenobuf_core::Node;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a node
let node = Node::new("my_node").await?;
// ...
Ok(())
}
use zenobuf_core::{Node, QosProfile};
use my_crate::proto::Point;
// Create a publisher
let publisher = node
.publisher::<Point>("point_topic")
.build()
.await?;
// Create a message
let point = Point {
x: 1.0,
y: 2.0,
z: 3.0,
};
// Publish the message
publisher.publish(&point)?;
use zenobuf_core::{Node, QosProfile};
use my_crate::proto::Point;
// Create a subscriber
let _subscriber = node
.subscriber::<Point>("point_topic")
.build(|point| {
println!("Received point: ({}, {}, {})", point.x, point.y, point.z);
})
.await?;
// Spin the node
node.spin().await?;
use zenobuf_core::{Node, Result};
use my_crate::proto::{AddRequest, AddResponse};
// Create a service
let _service = node
.service::<AddRequest, AddResponse>("add_service")
.build(|request| {
Ok(AddResponse {
sum: request.a + request.b,
})
})
.await?;
// Spin the node
node.spin().await?;
use zenobuf_core::{Node, Result};
use my_crate::proto::{AddRequest, AddResponse};
// Create a client
let client = node.create_client::<AddRequest, AddResponse>("add_service")?;
// Create a request
let request = AddRequest {
a: 2,
b: 3,
};
// Call the service
let response = client.call(&request)?;
println!("Sum: {}", response.sum);
use zenobuf_core::{Node, Result};
// Set a parameter
node.set_parameter("my_param", 42)?;
// Get a parameter
let value: i32 = node.get_parameter("my_param")?;
println!("Parameter value: {}", value);
See the zenobuf-examples crate for complete examples:
Install the CLI tools for development and debugging:
cargo install zenobuf-cli
# Monitor topics
zenobuf-cli monitor sensor_data
# List system components
zenobuf-cli list topics
zenobuf-cli list services
zenobuf-cli list nodes
# Call services
zenobuf-cli call add_service --data '{"a": 5, "b": 3}'
# Manage parameters
zenobuf-cli param get max_speed
zenobuf-cli param set max_speed 15.0
This project is licensed under either of
at your option.