Skip to content

Commit

Permalink
Smallen codegen (#158)
Browse files Browse the repository at this point in the history
* deserialize helpers

* use into_known to impl OpenProtoEnum

* add serialize special case

* Special case for compute_size as well

* Use if let instead of for for optional fields

* Only generate compute_grpc_slices_size for types that use grpc_slices
  • Loading branch information
goffrie authored Dec 14, 2023
1 parent 3997f8b commit 5c81968
Show file tree
Hide file tree
Showing 14 changed files with 1,103 additions and 4,002 deletions.
280 changes: 148 additions & 132 deletions pb-jelly-gen/codegen/codegen.py

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions pb-jelly/src/base_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,17 @@ pub trait ClosedProtoEnum: ProtoEnum + Debug {
///
/// Note that this is *not* a closed enum.
pub trait OpenProtoEnum: ProtoEnum {
type Closed: ClosedProtoEnum;
/// If this is a known variant, returns the corresponding closed enum value.
fn into_known(self) -> Option<Self::Closed>;
/// Get the name of this variant, if it is known.
fn name(self) -> Option<&'static str>;
/// Whether or not this enum variant is "known" (i.e. there is an associate constant with it).
fn is_known(self) -> bool;
fn name(self) -> Option<&'static str> {
self.into_known().map(<Self::Closed as ClosedProtoEnum>::name)
}
/// Whether or not this enum variant is "known" (i.e. there is an associated constant with it).
fn is_known(self) -> bool {
self.into_known().is_some()
}
}

/// Marker trait for proto enums.
Expand Down
96 changes: 96 additions & 0 deletions pb-jelly/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use std::io;

use crate::{
ensure_split,
ensure_wire_format,
varint,
wire_format,
Message,
PbBufferReader,
PbBufferWriter,
};

pub fn deserialize_packed<B: PbBufferReader, T: Message>(
buf: &mut B,
typ: wire_format::Type,
expected_wire_format: wire_format::Type,
msg_name: &'static str,
field_number: usize,
out: &mut Vec<T>,
) -> io::Result<()> {
match typ {
wire_format::Type::LengthDelimited => {
let len = varint::ensure_read(buf)?;
let mut vals = ensure_split(buf, len as usize)?;
while vals.has_remaining() {
let mut val: T = Default::default();
val.deserialize(&mut vals)?;
out.push(val);
}
},
_ => {
ensure_wire_format(typ, expected_wire_format, msg_name, field_number)?;
let mut val: T = Default::default();
val.deserialize(buf)?;
out.push(val);
},
}
Ok(())
}

pub fn deserialize_length_delimited<B: PbBufferReader, T: Message>(
buf: &mut B,
typ: wire_format::Type,
msg_name: &'static str,
field_number: usize,
) -> io::Result<T> {
ensure_wire_format(typ, wire_format::Type::LengthDelimited, msg_name, field_number)?;
let len = varint::ensure_read(buf)?;
let mut next = ensure_split(buf, len as usize)?;
let mut val: T = Default::default();
val.deserialize(&mut next)?;
Ok(val)
}

pub fn deserialize_known_length<B: PbBufferReader, T: Message>(
buf: &mut B,
typ: wire_format::Type,
expected_wire_format: wire_format::Type,
msg_name: &'static str,
field_number: usize,
) -> io::Result<T> {
ensure_wire_format(typ, expected_wire_format, msg_name, field_number)?;
let mut val: T = Default::default();
val.deserialize(buf)?;
Ok(val)
}

pub fn serialize_scalar<W: PbBufferWriter, T: Message>(
w: &mut W,
val: &T,
field_number: u32,
wire_format: wire_format::Type,
) -> io::Result<()> {
if *val != T::default() {
wire_format::write(field_number, wire_format, w)?;
if let wire_format::Type::LengthDelimited = wire_format {
let l = val.compute_size();
varint::write(l as u64, w)?;
}
val.serialize(w)?;
}
Ok(())
}

pub fn compute_size_scalar<T: Message>(val: &T, field_number: u32, wire_format: wire_format::Type) -> usize {
let mut size = 0;
if *val != T::default() {
size += wire_format::serialized_length(field_number);
let l = val.compute_size();
if let wire_format::Type::LengthDelimited = wire_format {
size += varint::serialized_length(l as u64);
}
size += l;
}
size
}
1 change: 1 addition & 0 deletions pb-jelly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use bytes::buf::{
};

pub mod erased;
pub mod helpers;
pub mod varint;
pub mod wire_format;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ impl ::pb_jelly::Message for Empty {
fn compute_size(&self) -> usize {
0
}
fn compute_grpc_slices_size(&self) -> usize {
0
}
fn serialize<W: ::pb_jelly::PbBufferWriter>(&self, w: &mut W) -> ::std::io::Result<()> {
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,18 @@ impl ::pb_jelly::Message for NoPackage {
}
fn compute_size(&self) -> usize {
let mut size = 0;
let mut field_size = 0;
if self.field != <::std::string::String as ::std::default::Default>::default() {
let val = &self.field;
let l = ::pb_jelly::Message::compute_size(val);
field_size += ::pb_jelly::wire_format::serialized_length(1);
field_size += ::pb_jelly::varint::serialized_length(l as u64);
field_size += l;
}
size += field_size;
size
}
fn compute_grpc_slices_size(&self) -> usize {
let mut size = 0;
if self.field != <::std::string::String as ::std::default::Default>::default() {
let val = &self.field;
size += ::pb_jelly::Message::compute_grpc_slices_size(val);
}
size += ::pb_jelly::helpers::compute_size_scalar::<::std::string::String>(&self.field, 1, ::pb_jelly::wire_format::Type::LengthDelimited);
size
}
fn serialize<W: ::pb_jelly::PbBufferWriter>(&self, w: &mut W) -> ::std::io::Result<()> {
if self.field != <::std::string::String as ::std::default::Default>::default() {
let val = &self.field;
::pb_jelly::wire_format::write(1, ::pb_jelly::wire_format::Type::LengthDelimited, w)?;
let l = ::pb_jelly::Message::compute_size(val);
::pb_jelly::varint::write(l as u64, w)?;
::pb_jelly::Message::serialize(val, w)?;
}
::pb_jelly::helpers::serialize_scalar::<W, ::std::string::String>(w, &self.field, 1, ::pb_jelly::wire_format::Type::LengthDelimited)?;
Ok(())
}
fn deserialize<B: ::pb_jelly::PbBufferReader>(&mut self, mut buf: &mut B) -> ::std::io::Result<()> {
while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? {
match field_number {
1 => {
::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::LengthDelimited, "NoPackage", 1)?;
let len = ::pb_jelly::varint::ensure_read(&mut buf)?;
let mut next = ::pb_jelly::ensure_split(buf, len as usize)?;
let mut val: ::std::string::String = ::std::default::Default::default();
::pb_jelly::Message::deserialize(&mut val, &mut next)?;
let val = ::pb_jelly::helpers::deserialize_length_delimited::<B, ::std::string::String>(buf, typ, "NoPackage", 1)?;
self.field = val;
}
_ => {
Expand Down
Loading

0 comments on commit 5c81968

Please sign in to comment.