Yet another Rust implementation of Google Protocol Buffer.
Generated structs
For an input .proto file like this:
syntax = "proto3";
message MyMessage {
int32 my_number = 1;
repeated string my_name = 2;
MyMessage my_child = 3;
}
A struct like this is output (detailed doc):
pub struct MyMessage {
pub my_number: i32,
pub my_name: Vec<String>,
pub my_child: Option<Box<MyMessage>>,
}
You can deserialize a struct from Iterator<std::io::Result<u8>>
(which is a return type of std::io::Read::bytes() method):
# #[derive(Default)]
# pub struct MyMessage {
# pub my_number: i32,
# }
# use ::puroro::*;
# impl Message<MyMessage> for MyMessage {}
# impl internal::DeserializableMessageFromBytesIterator for MyMessage {
# fn deser<I>(&mut self, iter: I) -> Result<()>
# where
# I: Iterator<Item = ::std::io::Result<u8>>
# {
# internal::de::from_iter::deser_from_iter(self, iter)
# }
# }
# impl internal::de::DeserFieldsFromBytesIter for MyMessage {
# fn deser_field<I>(
# &mut self,
# field_number: i32,
# data: internal::types::FieldData<&mut internal::de::from_iter::ScopedIter<I>>,
# ) -> Result<()>
# where
# I: Iterator<Item = ::std::io::Result<u8>>,
# {
# use internal::impls::simple::de::DeserFieldFromBytesIter;
# match field_number {
# 1 => DeserFieldFromBytesIter::<
# tags::Unlabeled, tags::Int32
# >::deser_field(&mut self.my_number, data),
# _ => panic!(),
# }
# }
# }
use puroro::Message; use std::io::Read; let input = vec![0x08, 0x0a];
let msg = MyMessage::from_bytes(input.bytes()).unwrap();
assert_eq!(10, msg.my_number);
And serialize it to std::io::Write:
# #[derive(Default)]
# pub struct MyMessage {
# pub my_number: i32,
# }
# use ::puroro::{internal, Result, tags};
# impl Message<MyMessage> for MyMessage {}
# impl ::puroro::internal::SerializableMessageToIoWrite for MyMessage {
# fn ser<W>(&self, out: &mut W) -> Result<()> where W: std::io::Write {
# internal::impls::simple::se::SerFieldToIoWrite::<tags::Unlabeled, tags::Int32>::ser_field(
# &self.my_number, 1, out
# )
# }
# }
use puroro::Message; let mut output = vec![];
let mut msg = MyMessage::default();
msg.my_number = 10;
msg.ser(&mut output).unwrap();
assert_eq!(vec![0x08, 0x0a], output);
Generated traits
(Detailed doc)
For the same input as above:
syntax = "proto3";
message MyMessage {
int32 my_number = 1;
repeated string my_name = 2;
MyMessage my_child = 3;
}
Trait like this is generated
(Omitting some bounds for explanation. Please check the traits page for detail):
# #![feature(generic_associated_types)]
# use ::std::ops::Deref;
pub trait MyMessageTrait {
fn my_number(&self) -> i32;
type Field2RepeatedType<'this>: IntoIterator<Item=&'this str>;
fn my_name(&self) -> Self::Field2RepeatedType<'_>;
type Field3MessageType<'this>: MyMessageTrait;
fn my_child(&self) -> Option<Self::Field3MessageType<'_>>;
}
The trait is implemented for the struct MyMessage and few other items:
# trait MyMessageTrait {}
impl MyMessageTrait for () { }
impl<'a, T: MyMessageTrait> MyMessageTrait for &'a T { }
impl<'a, T: MyMessageTrait> MyMessageTrait for &'a mut T { }
impl<T: MyMessageTrait> MyMessageTrait for Box<T> { }
impl<T: MyMessageTrait> MyMessageTrait for Option<T> { }
impl<T: MyMessageTrait, U: MyMessageTrait> MyMessageTrait for (T, U) { }
impl<T: MyMessageTrait, U: MyMessageTrait> MyMessageTrait for puroro::Either<T, U> { }
Builder struct
(Detailed doc)
puroro also generates a message builder.
A message generated by this builder has an advantage against
the normal message struct in memory size: It only consumes
the memory for the explicitly set fields.
# use ::std::ops::Deref;
# trait MyMessageTrait {}
pub struct MyMessageBuilder<T>(T);
impl MyMessageBuilder<()> {
pub fn new() -> Self {
# todo!()
}
}
impl<T: MyMessageTrait> MyMessageBuilder<T> {
pub fn append_my_number(self, value: i32)
-> MyMessageBuilder<(T, MyMessageSingleField1)> {
# todo!()
}
pub fn append_my_name<U, V>(self, value: U)
-> MyMessageBuilder<(T, MyMessageSingleField2<U, V>)>
where
for<'a> &'a U: IntoIterator<Item=&'a V>,
V: AsRef<str>,
{
# todo!()
}
pub fn append_my_child<U: MyMessageTrait>(self, value: U)
-> MyMessageBuilder<(T, MyMessageSingleField3<U>)> {
# todo!()
}
}
# pub struct MyMessageSingleField1();
# pub struct MyMessageSingleField2<T, U>(T, U);
# pub struct MyMessageSingleField3<T>(T);
Usage:
let my_message = MyMessageBuilder::new()
.append_my_number(10)
.append_my_name(vec!["foo", "bar"])
.build();
assert_eq!(10, my_message.my_number());