Skip to content

Commit

Permalink
add .. operator to proto! for merge_from. This mimics Rust's struct u…
Browse files Browse the repository at this point in the history
  • Loading branch information
dbenson24 authored and Copybara-Service committed Jul 1, 2024
1 parent 894fd31 commit 91dfd86
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
18 changes: 18 additions & 0 deletions rust/proto_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ macro_rules! proto {
#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! proto_internal {
(@merge $msg:ident $ident:ident : $expr:expr, $($rest:tt)*) => {
proto_internal!(@merge $msg $($rest)*);
};

(@merge $msg:ident $ident:ident : $expr:expr) => {
};

(@merge $msg:ident ..$expr:expr) => {
$msg.merge_from($expr);
};

// nested message,
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { $field:ident : $($value:tt)* }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : $($msgtype)::+ { $field : $($value)* });
Expand All @@ -54,12 +65,14 @@ macro_rules! proto_internal {
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => {
{
let mut $msg: <$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
proto_internal!(@merge $msg $field : $($value)*);
proto_internal!(@msg $msg $field : $($value)*);
}
};
(@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => {
{
let mut $msg: <::$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
proto_internal!(@merge $msg $field : $($value)*);
proto_internal!(@msg $msg $field : $($value)*);
}
};
Expand Down Expand Up @@ -98,12 +111,17 @@ macro_rules! proto_internal {
$crate::__internal::paste!($msg.[<set_ $ident>]($expr));
};

(@msg $msg:ident ..$expr:expr) => {
};

(@msg $msg:ident) => {};
(@merge $msg:ident) => {};

// entry point
($msgtype:ty { $($tt:tt)* }) => {
{
let mut message = <$msgtype>::new();
proto_internal!(@merge message $($tt)*);
proto_internal!(@msg message $($tt)*);
message
}
Expand Down
29 changes: 29 additions & 0 deletions rust/test/shared/proto_macro_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,32 @@ fn test_recursive_msg() {
assert_that!(msg.child().child().payload().optional_int32(), eq(42));
assert_that!(msg.child().child().child().payload().optional_int32(), eq(43));
}

#[test]
fn test_spread_msg() {
let msg = proto!(TestAllTypes { optional_nested_message: NestedMessage { bb: 42 } });
let msg2 = proto!(TestAllTypes { ..msg.as_view() });
assert_that!(msg2.optional_nested_message().bb(), eq(42));
let msg3 = proto!(TestAllTypes { optional_int32: 1, ..msg.as_view() });
assert_that!(msg3.optional_nested_message().bb(), eq(42));
assert_that!(msg3.optional_int32(), eq(1));
}

#[test]
fn test_spread_nested_msg() {
let msg = proto!(NestedTestAllTypes {
child: NestedTestAllTypes {
payload: TestAllTypes { optional_int32: 41 },
child: NestedTestAllTypes {
child: NestedTestAllTypes { payload: TestAllTypes { optional_int32: 43 } },
payload: TestAllTypes { optional_int32: 42 }
}
}
});
let msg2 = proto!(NestedTestAllTypes {
child: NestedTestAllTypes { payload: TestAllTypes { optional_int32: 100 }, ..msg.child() }
});
assert_that!(msg2.child().payload().optional_int32(), eq(100));
assert_that!(msg2.child().child().payload().optional_int32(), eq(42));
assert_that!(msg2.child().child().child().payload().optional_int32(), eq(43));
}

0 comments on commit 91dfd86

Please sign in to comment.