Skip to content

Commit 5c81968

Browse files
authored
Smallen codegen (#158)
* 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
1 parent 3997f8b commit 5c81968

14 files changed

Lines changed: 1103 additions & 4002 deletions

File tree

pb-jelly-gen/codegen/codegen.py

Lines changed: 148 additions & 132 deletions
Large diffs are not rendered by default.

pb-jelly/src/base_types.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,17 @@ pub trait ClosedProtoEnum: ProtoEnum + Debug {
4949
///
5050
/// Note that this is *not* a closed enum.
5151
pub trait OpenProtoEnum: ProtoEnum {
52+
type Closed: ClosedProtoEnum;
53+
/// If this is a known variant, returns the corresponding closed enum value.
54+
fn into_known(self) -> Option<Self::Closed>;
5255
/// Get the name of this variant, if it is known.
53-
fn name(self) -> Option<&'static str>;
54-
/// Whether or not this enum variant is "known" (i.e. there is an associate constant with it).
55-
fn is_known(self) -> bool;
56+
fn name(self) -> Option<&'static str> {
57+
self.into_known().map(<Self::Closed as ClosedProtoEnum>::name)
58+
}
59+
/// Whether or not this enum variant is "known" (i.e. there is an associated constant with it).
60+
fn is_known(self) -> bool {
61+
self.into_known().is_some()
62+
}
5663
}
5764

5865
/// Marker trait for proto enums.

pb-jelly/src/helpers.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use std::io;
2+
3+
use crate::{
4+
ensure_split,
5+
ensure_wire_format,
6+
varint,
7+
wire_format,
8+
Message,
9+
PbBufferReader,
10+
PbBufferWriter,
11+
};
12+
13+
pub fn deserialize_packed<B: PbBufferReader, T: Message>(
14+
buf: &mut B,
15+
typ: wire_format::Type,
16+
expected_wire_format: wire_format::Type,
17+
msg_name: &'static str,
18+
field_number: usize,
19+
out: &mut Vec<T>,
20+
) -> io::Result<()> {
21+
match typ {
22+
wire_format::Type::LengthDelimited => {
23+
let len = varint::ensure_read(buf)?;
24+
let mut vals = ensure_split(buf, len as usize)?;
25+
while vals.has_remaining() {
26+
let mut val: T = Default::default();
27+
val.deserialize(&mut vals)?;
28+
out.push(val);
29+
}
30+
},
31+
_ => {
32+
ensure_wire_format(typ, expected_wire_format, msg_name, field_number)?;
33+
let mut val: T = Default::default();
34+
val.deserialize(buf)?;
35+
out.push(val);
36+
},
37+
}
38+
Ok(())
39+
}
40+
41+
pub fn deserialize_length_delimited<B: PbBufferReader, T: Message>(
42+
buf: &mut B,
43+
typ: wire_format::Type,
44+
msg_name: &'static str,
45+
field_number: usize,
46+
) -> io::Result<T> {
47+
ensure_wire_format(typ, wire_format::Type::LengthDelimited, msg_name, field_number)?;
48+
let len = varint::ensure_read(buf)?;
49+
let mut next = ensure_split(buf, len as usize)?;
50+
let mut val: T = Default::default();
51+
val.deserialize(&mut next)?;
52+
Ok(val)
53+
}
54+
55+
pub fn deserialize_known_length<B: PbBufferReader, T: Message>(
56+
buf: &mut B,
57+
typ: wire_format::Type,
58+
expected_wire_format: wire_format::Type,
59+
msg_name: &'static str,
60+
field_number: usize,
61+
) -> io::Result<T> {
62+
ensure_wire_format(typ, expected_wire_format, msg_name, field_number)?;
63+
let mut val: T = Default::default();
64+
val.deserialize(buf)?;
65+
Ok(val)
66+
}
67+
68+
pub fn serialize_scalar<W: PbBufferWriter, T: Message>(
69+
w: &mut W,
70+
val: &T,
71+
field_number: u32,
72+
wire_format: wire_format::Type,
73+
) -> io::Result<()> {
74+
if *val != T::default() {
75+
wire_format::write(field_number, wire_format, w)?;
76+
if let wire_format::Type::LengthDelimited = wire_format {
77+
let l = val.compute_size();
78+
varint::write(l as u64, w)?;
79+
}
80+
val.serialize(w)?;
81+
}
82+
Ok(())
83+
}
84+
85+
pub fn compute_size_scalar<T: Message>(val: &T, field_number: u32, wire_format: wire_format::Type) -> usize {
86+
let mut size = 0;
87+
if *val != T::default() {
88+
size += wire_format::serialized_length(field_number);
89+
let l = val.compute_size();
90+
if let wire_format::Type::LengthDelimited = wire_format {
91+
size += varint::serialized_length(l as u64);
92+
}
93+
size += l;
94+
}
95+
size
96+
}

pb-jelly/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use bytes::buf::{
2424
};
2525

2626
pub mod erased;
27+
pub mod helpers;
2728
pub mod varint;
2829
pub mod wire_format;
2930

pb-test/gen/pb-jelly/proto_google/src/protobuf/empty.rs.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ impl ::pb_jelly::Message for Empty {
3434
fn compute_size(&self) -> usize {
3535
0
3636
}
37-
fn compute_grpc_slices_size(&self) -> usize {
38-
0
39-
}
4037
fn serialize<W: ::pb_jelly::PbBufferWriter>(&self, w: &mut W) -> ::std::io::Result<()> {
4138
Ok(())
4239
}

pb-test/gen/pb-jelly/proto_nopackage/src/proto_nopackage.rs.expected

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,44 +35,18 @@ impl ::pb_jelly::Message for NoPackage {
3535
}
3636
fn compute_size(&self) -> usize {
3737
let mut size = 0;
38-
let mut field_size = 0;
39-
if self.field != <::std::string::String as ::std::default::Default>::default() {
40-
let val = &self.field;
41-
let l = ::pb_jelly::Message::compute_size(val);
42-
field_size += ::pb_jelly::wire_format::serialized_length(1);
43-
field_size += ::pb_jelly::varint::serialized_length(l as u64);
44-
field_size += l;
45-
}
46-
size += field_size;
47-
size
48-
}
49-
fn compute_grpc_slices_size(&self) -> usize {
50-
let mut size = 0;
51-
if self.field != <::std::string::String as ::std::default::Default>::default() {
52-
let val = &self.field;
53-
size += ::pb_jelly::Message::compute_grpc_slices_size(val);
54-
}
38+
size += ::pb_jelly::helpers::compute_size_scalar::<::std::string::String>(&self.field, 1, ::pb_jelly::wire_format::Type::LengthDelimited);
5539
size
5640
}
5741
fn serialize<W: ::pb_jelly::PbBufferWriter>(&self, w: &mut W) -> ::std::io::Result<()> {
58-
if self.field != <::std::string::String as ::std::default::Default>::default() {
59-
let val = &self.field;
60-
::pb_jelly::wire_format::write(1, ::pb_jelly::wire_format::Type::LengthDelimited, w)?;
61-
let l = ::pb_jelly::Message::compute_size(val);
62-
::pb_jelly::varint::write(l as u64, w)?;
63-
::pb_jelly::Message::serialize(val, w)?;
64-
}
42+
::pb_jelly::helpers::serialize_scalar::<W, ::std::string::String>(w, &self.field, 1, ::pb_jelly::wire_format::Type::LengthDelimited)?;
6543
Ok(())
6644
}
6745
fn deserialize<B: ::pb_jelly::PbBufferReader>(&mut self, mut buf: &mut B) -> ::std::io::Result<()> {
6846
while let Some((field_number, typ)) = ::pb_jelly::wire_format::read(&mut buf)? {
6947
match field_number {
7048
1 => {
71-
::pb_jelly::ensure_wire_format(typ, ::pb_jelly::wire_format::Type::LengthDelimited, "NoPackage", 1)?;
72-
let len = ::pb_jelly::varint::ensure_read(&mut buf)?;
73-
let mut next = ::pb_jelly::ensure_split(buf, len as usize)?;
74-
let mut val: ::std::string::String = ::std::default::Default::default();
75-
::pb_jelly::Message::deserialize(&mut val, &mut next)?;
49+
let val = ::pb_jelly::helpers::deserialize_length_delimited::<B, ::std::string::String>(buf, typ, "NoPackage", 1)?;
7650
self.field = val;
7751
}
7852
_ => {

0 commit comments

Comments
 (0)