Skip to content

Commit

Permalink
Fix proto2 string field with bytes option and default value
Browse files Browse the repository at this point in the history
Issue #395
  • Loading branch information
stepancheg committed Mar 5, 2019
1 parent 491f6bb commit 9c9a3c8
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
5 changes: 4 additions & 1 deletion protobuf-codegen/src/field.rs
Expand Up @@ -1452,6 +1452,8 @@ impl<'a> FieldGen<'a> {
));
} else {
let s = self.singular();
// Note it is different from C++ protobuf, where field is initialized
// with default value
match option_kind {
OptionKind::SingularField | OptionKind::SingularPtrField => {
let self_field = self.self_field();
Expand All @@ -1461,7 +1463,8 @@ impl<'a> FieldGen<'a> {
self.write_self_field_assign_some(
w,
s,
&self.element_default_value_rust().value,
&self.elem().rust_storage_elem_type().default_value_typed()
.into_type(s.elem.rust_storage_elem_type()).value,
);
}
}
Expand Down
31 changes: 27 additions & 4 deletions protobuf-codegen/src/rust_types_values.rs
Expand Up @@ -93,6 +93,13 @@ impl RustType {
}
}

pub fn is_u8(&self) -> bool {
match *self {
RustType::Int(false, 8) => true,
_ => false,
}
}

pub fn is_copy(&self) -> bool {
if self.is_primitive() {
true
Expand All @@ -117,10 +124,17 @@ impl RustType {
}
}

fn is_slice(&self) -> bool {
fn is_slice(&self) -> Option<&RustType> {
match *self {
RustType::Slice(..) => true,
_ => false,
RustType::Slice(ref v) => Some(&**v),
_ => None,
}
}

fn is_slice_u8(&self) -> bool {
match self.is_slice() {
Some(t) => t.is_u8(),
None => false,
}
}

Expand Down Expand Up @@ -156,7 +170,7 @@ impl RustType {
pub fn default_value(&self) -> String {
match *self {
RustType::Ref(ref t) if t.is_str() => "\"\"".to_string(),
RustType::Ref(ref t) if t.is_slice() => "&[]".to_string(),
RustType::Ref(ref t) if t.is_slice().is_some() => "&[]".to_string(),
RustType::Int(..) => "0".to_string(),
RustType::Float(..) => "0.".to_string(),
RustType::Bool => "false".to_string(),
Expand Down Expand Up @@ -248,11 +262,20 @@ impl RustType {
RustType::Str => true,
_ => false,
} => return Ok(format!("{}.to_owned()", v)),
(&RustType::Ref(ref t1), &RustType::Chars)
if match **t1 {
RustType::Str => true,
_ => false,
// TODO: from_static
} => return Ok(format!("<::protobuf::Chars as ::std::convert::From<_>>::from({}.to_owned())", v)),
(&RustType::Ref(ref t1), &RustType::Vec(ref t2))
if match (&**t1, &**t2) {
(&RustType::Slice(ref x), ref y) => **x == **y,
_ => false,
} => return Ok(format!("{}.to_vec()", v)),
(&RustType::Ref(ref t1), &RustType::Bytes)
if t1.is_slice_u8() =>
return Ok(format!("<::bytes::Bytes as ::std::convert::From<_>>::from({}.to_vec())", v)),
(&RustType::Vec(ref x), &RustType::Ref(ref t))
if match **t {
RustType::Slice(ref y) => x == y,
Expand Down
11 changes: 11 additions & 0 deletions protobuf-test/src/v2/test_carllerche_bytes_default_value.rs
@@ -0,0 +1,11 @@
use protobuf::*;

use super::test_carllerche_bytes_default_value_pb::*;

#[test]
fn test_default_values() {
assert_eq!("sss", TestCarllercheBytesDefaultValues::default_instance().get_s());
assert_eq!(b"bbb", TestCarllercheBytesDefaultValues::default_instance().get_b());
assert_eq!(&""[..], &**TestCarllercheBytesDefaultValues::new().mut_s());
assert_eq!(&b""[..], &**TestCarllercheBytesDefaultValues::new().mut_b());
}
14 changes: 14 additions & 0 deletions protobuf-test/src/v2/test_carllerche_bytes_default_value_pb.proto
@@ -0,0 +1,14 @@
syntax = "proto2";

package test_carllerche_bytes_default_value;

import "rustproto.proto";

option (rustproto.carllerche_bytes_for_bytes_all) = true;
option (rustproto.carllerche_bytes_for_string_all) = true;
option (rustproto.generate_accessors_all) = true;

message TestCarllercheBytesDefaultValues {
optional string s = 1 [default = "sss"];
optional bytes b = 2 [default = "bbb"];
}

0 comments on commit 9c9a3c8

Please sign in to comment.