Skip to content

Commit d5f2ff5

Browse files
committed
proc_macro: use macros to simplify aggregate Mark/Unmark definitions
1 parent 0f4f8e5 commit d5f2ff5

File tree

1 file changed

+53
-24
lines changed
  • library/proc_macro/src/bridge

1 file changed

+53
-24
lines changed

library/proc_macro/src/bridge/mod.rs

+53-24
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,58 @@ rpc_encode_decode!(
401401
}
402402
);
403403

404+
macro_rules! mark_compound {
405+
(struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
406+
impl<$($T: Mark),+> Mark for $name <$($T),+> {
407+
type Unmarked = $name <$($T::Unmarked),+>;
408+
fn mark(unmarked: Self::Unmarked) -> Self {
409+
$name {
410+
$($field: Mark::mark(unmarked.$field)),*
411+
}
412+
}
413+
}
414+
415+
impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
416+
type Unmarked = $name <$($T::Unmarked),+>;
417+
fn unmark(self) -> Self::Unmarked {
418+
$name {
419+
$($field: Unmark::unmark(self.$field)),*
420+
}
421+
}
422+
}
423+
};
424+
(enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
425+
impl<$($T: Mark),+> Mark for $name <$($T),+> {
426+
type Unmarked = $name <$($T::Unmarked),+>;
427+
fn mark(unmarked: Self::Unmarked) -> Self {
428+
match unmarked {
429+
$($name::$variant $(($field))? => {
430+
$name::$variant $((Mark::mark($field)))?
431+
})*
432+
}
433+
}
434+
}
435+
436+
impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
437+
type Unmarked = $name <$($T::Unmarked),+>;
438+
fn unmark(self) -> Self::Unmarked {
439+
match self {
440+
$($name::$variant $(($field))? => {
441+
$name::$variant $((Unmark::unmark($field)))?
442+
})*
443+
}
444+
}
445+
}
446+
}
447+
}
448+
449+
macro_rules! compound_traits {
450+
($($t:tt)*) => {
451+
rpc_encode_decode!($($t)*);
452+
mark_compound!($($t)*);
453+
};
454+
}
455+
404456
#[derive(Clone)]
405457
pub enum TokenTree<G, P, I, L> {
406458
Group(G),
@@ -409,30 +461,7 @@ pub enum TokenTree<G, P, I, L> {
409461
Literal(L),
410462
}
411463

412-
impl<G: Mark, P: Mark, I: Mark, L: Mark> Mark for TokenTree<G, P, I, L> {
413-
type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
414-
fn mark(unmarked: Self::Unmarked) -> Self {
415-
match unmarked {
416-
TokenTree::Group(tt) => TokenTree::Group(G::mark(tt)),
417-
TokenTree::Punct(tt) => TokenTree::Punct(P::mark(tt)),
418-
TokenTree::Ident(tt) => TokenTree::Ident(I::mark(tt)),
419-
TokenTree::Literal(tt) => TokenTree::Literal(L::mark(tt)),
420-
}
421-
}
422-
}
423-
impl<G: Unmark, P: Unmark, I: Unmark, L: Unmark> Unmark for TokenTree<G, P, I, L> {
424-
type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
425-
fn unmark(self) -> Self::Unmarked {
426-
match self {
427-
TokenTree::Group(tt) => TokenTree::Group(tt.unmark()),
428-
TokenTree::Punct(tt) => TokenTree::Punct(tt.unmark()),
429-
TokenTree::Ident(tt) => TokenTree::Ident(tt.unmark()),
430-
TokenTree::Literal(tt) => TokenTree::Literal(tt.unmark()),
431-
}
432-
}
433-
}
434-
435-
rpc_encode_decode!(
464+
compound_traits!(
436465
enum TokenTree<G, P, I, L> {
437466
Group(tt),
438467
Punct(tt),

0 commit comments

Comments
 (0)