Protobuf
Shizuku provides Protocol Buffers serialization support through the protobuf
feature flag. This integration uses prost
for serialization and deserialization.
Installation
-
Add the
protobuf
feature to your Shizuku dependency inCargo.toml
:Cargo.toml [dependencies]shizuku = { version = "0.0.2-alpha.2", features = ["protobuf"] } -
Add
prost-build
to your build dependencies:Cargo.toml [build-dependencies]prost-build = "0.13" -
Create a
build.rs
file in your project root to compile.proto
files:/build.rs fn main() {prost_build::compile_protos(&["src/proto/user.proto"], &["src/proto"]).unwrap();} -
Create your
.proto
files in the specified directory (e.g.,src/proto/user.proto
):src/proto/user.proto syntax = "proto3";package user;message User {string id = 1;string name = 2;string email = 3;} -
Create a module file to include the generated code (e.g.,
src/user.rs
):src/user.rs // Include the generated protobuf codepub mod proto {include!(concat!(env!("OUT_DIR"), "/user.rs"));}// Re-export the types you want to use directlypub use proto::User;pub use proto::CreateUserRequest;pub use proto::CreateUserResponse;// Implement serialization and deserialization for the typesuse shizuku::{protobuf_ser, protobuf_des};protobuf_ser!(User);protobuf_des!(User);protobuf_ser!(CreateUserRequest);protobuf_des!(CreateUserResponse);
Usage
The Protobuf integration provides two macros for implementing serialization traits:
protobuf_ser
: ImplementsByteSerialize
for Protobuf serializationprotobuf_des
: ImplementsByteDeserialize
for Protobuf deserialization
Using in Services
The Protobuf serialization works seamlessly with NATS services:
use shizuku::{protobuf_ser, protobuf_des, NatsRpcCallTrait};include!(concat!(env!("OUT_DIR"), "/user.rs"));
impl NatsRpcCallTrait<CreateUserResponse> for CreateUserRequest { fn subject() -> (NatsSubjectPath, PhantomData<CreateUserResponse>) { (subject_path!["user", "create"], PhantomData) }}
protobuf_ser!(CreateUserRequest);protobuf_des!(CreateUserResponse);
Using with JetStream
You can use Protobuf serialization for JetStream events and consumers:
use shizuku::{protobuf_ser, protobuf_des, DynamicSubjectMessage, JetStreamMessageSendTrait};include!(concat!(env!("OUT_DIR"), "/order.rs"));
// Implement serializationprotobuf_ser!(OrderCreatedEvent);protobuf_des!(OrderData);
use shizuku::{DynamicSubjectMessage, JetStreamMessageSendTrait};use shizuku::jetstream::FinalJetStreamProcessor;use crate::order::{OrderCreatedEvent, OrderData};
// Implement dynamic subject for the eventimpl DynamicSubjectMessage for OrderCreatedEvent { fn subject(&self) -> NatsSubjectPath { subject_path!["order", "created", &self.order_id] }}
// The trait is automatically implementedimpl JetStreamMessageSendTrait for OrderCreatedEvent {}
// Define a consumer that processes Protobuf messages
struct OrderProcessor;
impl Processor<Message, Result<(), Error>> for OrderProcessor { async fn process(&self, msg: Message) -> Result<(), Error> { // Parse Protobuf message let order = OrderData::parse_from_bytes(msg.payload)?;
// Process the order println!("Processing order: {}", order.order_id); Ok(()) }}