diff --git a/protobuf-codegen/src/field.rs b/protobuf-codegen/src/field.rs index 5bae17500..ed391e942 100644 --- a/protobuf-codegen/src/field.rs +++ b/protobuf-codegen/src/field.rs @@ -1192,6 +1192,8 @@ impl<'a> FieldGen<'a> { .value )); } else { + // Note it is different from C++ protobuf, where field is initialized + // with default value match self.full_storage_type() { RustType::SingularField(..) | RustType::SingularPtrField(..) => { @@ -1199,7 +1201,11 @@ impl<'a> FieldGen<'a> { w.write_line(&format!("{}.set_default();", self_field)); } _ => { - self.write_self_field_assign_some(w, &self.element_default_value_rust().value); + self.write_self_field_assign_some( + w, + &self.elem().rust_storage_type().default_value_typed() + .into_type(self.elem().rust_storage_type()).value, + ); } } } diff --git a/protobuf-codegen/src/rust_types_values.rs b/protobuf-codegen/src/rust_types_values.rs index 51ee9dbac..d74f4999f 100644 --- a/protobuf-codegen/src/rust_types_values.rs +++ b/protobuf-codegen/src/rust_types_values.rs @@ -96,6 +96,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 @@ -120,10 +127,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, } } @@ -141,13 +155,6 @@ impl RustType { } } - pub fn is_u8(&self) -> bool { - match *self { - RustType::Int(false, 8) => true, - _ => false, - } - } - pub fn is_ref(&self) -> bool { match *self { RustType::Ref(..) => true, @@ -159,7 +166,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(), @@ -252,11 +259,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, diff --git a/protobuf-test/src/v2/test_carllerche_bytes_default_value.rs b/protobuf-test/src/v2/test_carllerche_bytes_default_value.rs new file mode 100644 index 000000000..fc7da00aa --- /dev/null +++ b/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()); +} diff --git a/protobuf-test/src/v2/test_carllerche_bytes_default_value_pb.proto b/protobuf-test/src/v2/test_carllerche_bytes_default_value_pb.proto new file mode 100644 index 000000000..3b96b16b6 --- /dev/null +++ b/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"]; +}