Implement flat setters for map and repeated fields.

This doesn't yet use the new IntoProxied trait, but is functionaly equivalent with MutProxy::set() and always copies.

PiperOrigin-RevId: 629358666
pull/16630/head
Jakob Buchgraber 11 months ago committed by Copybara-Service
parent 6d33efeefe
commit e181855abe
  1. 17
      rust/test/shared/accessors_map_test.rs
  2. 14
      rust/test/shared/accessors_repeated_test.rs
  3. 14
      src/google/protobuf/compiler/rust/accessors/map.cc
  4. 73
      src/google/protobuf/compiler/rust/accessors/repeated_field.cc

@ -157,6 +157,23 @@ fn test_bytes_and_string_copied() {
assert_that!(msg.map_int32_bytes_mut().get(1).unwrap(), eq(b"world"));
}
#[test]
fn test_map_setter() {
let mut msg = TestMap::new();
msg.map_string_string_mut().insert("hello", "world");
msg.map_string_string_mut().insert("fizz", "buzz");
let mut msg2 = TestMap::new();
msg2.set_map_string_string(msg.map_string_string());
assert_that!(
msg2.map_string_string().iter().collect::<Vec<_>>(),
unordered_elements_are![
eq(("hello".into(), "world".into())),
eq(("fizz".into(), "buzz".into()))
]
);
}
macro_rules! generate_map_with_msg_values_tests {
(
$(($k_field:ident, $k_nonzero:expr, $k_other:expr $(,)?)),*

@ -55,16 +55,17 @@ macro_rules! generate_repeated_numeric_test {
#[test]
fn [< test_repeated_ $field _set >]() {
let mut msg = TestAllTypes::new();
let mut mutator = msg.[<repeated_ $field _mut>]();
let mut msg2 = TestAllTypes::new();
let mut mutator2 = msg2.[<repeated_ $field _mut>]();
for i in 0..5 {
mutator2.push(i as $t);
}
protobuf::MutProxy::set(&mut mutator, mutator2.as_view());
msg.[<set_repeated_ $field >](mutator2.as_view());
let view = msg.[<repeated_ $field>]();
assert_that!(
mutator.iter().collect::<Vec<_>>(),
view.iter().collect::<Vec<_>>(),
eq(mutator2.iter().collect::<Vec<_>>())
);
}
@ -177,15 +178,16 @@ fn test_repeated_enum_accessors() {
#[test]
fn test_repeated_bool_set() {
let mut msg = TestAllTypes::new();
let mut mutator = msg.repeated_bool_mut();
let mut msg2 = TestAllTypes::new();
let mut mutator2 = msg2.repeated_bool_mut();
for _ in 0..5 {
mutator2.push(true);
}
protobuf::MutProxy::set(&mut mutator, mutator2.as_view());
assert_that!(mutator.iter().collect::<Vec<_>>(), eq(mutator2.iter().collect::<Vec<_>>()));
msg.set_repeated_bool(mutator2.as_view());
let view = msg.repeated_bool();
assert_that!(view.iter().collect::<Vec<_>>(), eq(mutator2.iter().collect::<Vec<_>>()));
}
#[test]

@ -42,6 +42,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field,
std::string field_name = FieldNameWithCollisionAvoidance(field);
ctx.Emit({{"field", RsSafeName(field_name)},
{"raw_field_name", field_name}, // Never r# prefixed
{"Key", RsTypePath(ctx, key_type)},
{"Value", RsTypePath(ctx, value_type)},
{"view_lifetime", ViewLifetime(accessor_case)},
@ -99,10 +100,23 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field,
unsafe { $pb$::MapMut::from_inner($pbi$::Private, inner) }
})rs");
}
}},
{"setter",
[&] {
if (accessor_case == AccessorCase::VIEW) {
return;
}
ctx.Emit({}, R"rs(
pub fn set_$raw_field_name$(&mut self, src: $pb$::MapView<'_, $Key$, $Value$>) {
// TODO: Implement IntoProxied and avoid copying.
self.$field$_mut().copy_from(src);
}
)rs");
}}},
R"rs(
$getter$
$getter_mut$
$setter$
)rs");
}

@ -23,16 +23,19 @@ namespace rust {
void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
AccessorCase accessor_case) const {
std::string field_name = FieldNameWithCollisionAvoidance(field);
ctx.Emit({{"field", RsSafeName(field_name)},
{"RsType", RsTypePath(ctx, field)},
{"view_lifetime", ViewLifetime(accessor_case)},
{"view_self", ViewReceiver(accessor_case)},
{"getter_thunk", ThunkName(ctx, field, "get")},
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")},
{"getter",
[&] {
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
ctx.Emit(
{
{"field", RsSafeName(field_name)},
{"raw_field_name", field_name}, // Never r# prefixed
{"RsType", RsTypePath(ctx, field)},
{"view_lifetime", ViewLifetime(accessor_case)},
{"view_self", ViewReceiver(accessor_case)},
{"getter_thunk", ThunkName(ctx, field, "get")},
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")},
{"getter",
[&] {
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
pub fn $field$($view_self$) -> $pb$::RepeatedView<$view_lifetime$, $RsType$> {
unsafe {
$getter_thunk$(
@ -47,8 +50,8 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
)
}
)rs");
} else {
ctx.Emit({}, R"rs(
} else {
ctx.Emit({}, R"rs(
pub fn $field$($view_self$) -> $pb$::RepeatedView<$view_lifetime$, $RsType$> {
unsafe {
$pb$::RepeatedView::from_raw(
@ -58,16 +61,16 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
}
}
)rs");
}
}},
{"clearer_thunk", ThunkName(ctx, field, "clear")},
{"getter_mut",
[&] {
if (accessor_case == AccessorCase::VIEW) {
return;
}
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
}
}},
{"clearer_thunk", ThunkName(ctx, field, "clear")},
{"getter_mut",
[&] {
if (accessor_case == AccessorCase::VIEW) {
return;
}
if (ctx.is_upb()) {
ctx.Emit({}, R"rs(
pub fn $field$_mut(&mut self) -> $pb$::RepeatedMut<'_, $RsType$> {
unsafe {
$pb$::RepeatedMut::from_inner(
@ -85,8 +88,8 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
}
}
)rs");
} else {
ctx.Emit({}, R"rs(
} else {
ctx.Emit({}, R"rs(
pub fn $field$_mut(&mut self) -> $pb$::RepeatedMut<'_, $RsType$> {
unsafe {
$pb$::RepeatedMut::from_inner(
@ -99,11 +102,25 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
}
}
)rs");
}
}}},
R"rs(
}
}},
{"setter",
[&] {
if (accessor_case == AccessorCase::VIEW) {
return;
}
ctx.Emit({}, R"rs(
pub fn set_$raw_field_name$(&mut self, src: $pb$::RepeatedView<'_, $RsType$>) {
// TODO: Implement IntoProxied and avoid copying.
self.$field$_mut().copy_from(src);
}
)rs");
}},
},
R"rs(
$getter$
$getter_mut$
$setter$
)rs");
}
@ -180,6 +197,8 @@ void RepeatedField::InThunkCc(Context& ctx,
{"clearer_thunk", ThunkName(ctx, field, "clear")},
{"getter_thunk", ThunkName(ctx, field, "get")},
{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")},
{"repeated_copy_from_thunk",
ThunkName(ctx, field, "repeated_copy_from")},
{"impls",
[&] {
ctx.Emit(

Loading…
Cancel
Save