Rust: fix proto! msgtype matcher to look for :: separated idents instead of a ty to avoid syntax errors during parse

PiperOrigin-RevId: 626093074
pull/16536/head
Derek Benson 2024-04-18 11:15:06 -07:00 committed by Copybara-Service
parent a2d4a4af2c
commit b4bd664b07
2 changed files with 41 additions and 15 deletions

View File

@ -33,7 +33,7 @@
#[macro_export]
macro_rules! proto {
($msgtype:ty { $($tt:tt)* }) => {
$crate::proto_internal!($msgtype { $($tt)* });
$crate::proto_internal!($msgtype { $($tt)* })
}
}
@ -41,29 +41,48 @@ macro_rules! proto {
#[doc(hidden)]
macro_rules! proto_internal {
// nested message,
(@msg $msg:ident $submsg:ident : $msgtype:ty { $field:ident : $($value:tt)* }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : $msgtype { $field : $($value)* });
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { $field:ident : $($value:tt)* }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : $($msgtype)::+ { $field : $($value)* });
proto_internal!(@msg $msg $($rest)*);
};
(@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { $field:ident : $($value:tt)* }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : ::$($msgtype)::+ { $field : $($value)* });
proto_internal!(@msg $msg $($rest)*);
};
// nested message
(@msg $msg:ident $submsg:ident : $msgtype:ty { $field:ident : $($value:tt)* }) => {
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => {
{
let mut $msg: <$msgtype as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
let mut $msg: <$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
proto_internal!(@msg $msg $field : $($value)*);
}
};
(@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => {
{
let mut $msg: <::$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
proto_internal!(@msg $msg $field : $($value)*);
}
};
// empty nested message,
(@msg $msg:ident $submsg:ident : $msgtype:ty { }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : $msgtype { });
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : $($msgtype)::+ { });
proto_internal!(@msg $msg $($rest)*);
};
(@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { }, $($rest:tt)*) => {
proto_internal!(@msg $msg $submsg : ::$($msgtype)::+ { });
proto_internal!(@msg $msg $($rest)*);
};
// empty nested message
(@msg $msg:ident $submsg:ident : $msgtype:ty { }) => {
(@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { }) => {
{
let mut $msg = $crate::__internal::paste!($msg.[<$submsg _mut>]());
let mut $msg: <$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
}
};
(@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { }) => {
{
let mut $msg: <::$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]());
}
};
@ -76,9 +95,7 @@ macro_rules! proto_internal {
// field: expr
(@msg $msg:ident $ident:ident : $expr:expr) => {
$crate::__internal::paste!{
$msg.[<set_ $ident>]($expr);
}
$crate::__internal::paste!($msg.[<set_ $ident>]($expr));
};
(@msg $msg:ident) => {};

View File

@ -14,17 +14,26 @@ use unittest_proto::{
NestedTestAllTypes, TestAllTypes,
};
struct TestValue {
val: i64,
}
#[test]
fn test_setting_literals() {
let fixed64 = || 108;
let test_ref = |x: &i64| *x;
let test_ref_b = |x: &u32| *x;
let one_oh_seven = [107_u32];
let value = TestValue { val: 106 };
let msg = proto!(TestAllTypes {
optional_int32: 101,
optional_int64: 102,
optional_uint32: 103,
optional_uint64: 104,
optional_uint64: if true { 104 } else { 99 },
optional_sint32: -105,
optional_sint64: 106,
optional_fixed32: 107,
optional_sint64: (test_ref(&value.val)),
optional_fixed32: { test_ref_b(&one_oh_seven[0]) },
optional_fixed64: fixed64(), //108
optional_sfixed32: 100 + 9,
optional_sfixed64: {