Skip to content

Commit

Permalink
proc_macro: use macros to simplify aggregate Mark/Unmark definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
mystor committed Jul 2, 2021
1 parent 0f4f8e5 commit d5f2ff5
Showing 1 changed file with 53 additions and 24 deletions.
77 changes: 53 additions & 24 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,58 @@ rpc_encode_decode!(
}
);

macro_rules! mark_compound {
(struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
impl<$($T: Mark),+> Mark for $name <$($T),+> {
type Unmarked = $name <$($T::Unmarked),+>;
fn mark(unmarked: Self::Unmarked) -> Self {
$name {
$($field: Mark::mark(unmarked.$field)),*
}
}
}

impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
type Unmarked = $name <$($T::Unmarked),+>;
fn unmark(self) -> Self::Unmarked {
$name {
$($field: Unmark::unmark(self.$field)),*
}
}
}
};
(enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
impl<$($T: Mark),+> Mark for $name <$($T),+> {
type Unmarked = $name <$($T::Unmarked),+>;
fn mark(unmarked: Self::Unmarked) -> Self {
match unmarked {
$($name::$variant $(($field))? => {
$name::$variant $((Mark::mark($field)))?
})*
}
}
}

impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
type Unmarked = $name <$($T::Unmarked),+>;
fn unmark(self) -> Self::Unmarked {
match self {
$($name::$variant $(($field))? => {
$name::$variant $((Unmark::unmark($field)))?
})*
}
}
}
}
}

macro_rules! compound_traits {
($($t:tt)*) => {
rpc_encode_decode!($($t)*);
mark_compound!($($t)*);
};
}

#[derive(Clone)]
pub enum TokenTree<G, P, I, L> {
Group(G),
Expand All @@ -409,30 +461,7 @@ pub enum TokenTree<G, P, I, L> {
Literal(L),
}

impl<G: Mark, P: Mark, I: Mark, L: Mark> Mark for TokenTree<G, P, I, L> {
type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
fn mark(unmarked: Self::Unmarked) -> Self {
match unmarked {
TokenTree::Group(tt) => TokenTree::Group(G::mark(tt)),
TokenTree::Punct(tt) => TokenTree::Punct(P::mark(tt)),
TokenTree::Ident(tt) => TokenTree::Ident(I::mark(tt)),
TokenTree::Literal(tt) => TokenTree::Literal(L::mark(tt)),
}
}
}
impl<G: Unmark, P: Unmark, I: Unmark, L: Unmark> Unmark for TokenTree<G, P, I, L> {
type Unmarked = TokenTree<G::Unmarked, P::Unmarked, I::Unmarked, L::Unmarked>;
fn unmark(self) -> Self::Unmarked {
match self {
TokenTree::Group(tt) => TokenTree::Group(tt.unmark()),
TokenTree::Punct(tt) => TokenTree::Punct(tt.unmark()),
TokenTree::Ident(tt) => TokenTree::Ident(tt.unmark()),
TokenTree::Literal(tt) => TokenTree::Literal(tt.unmark()),
}
}
}

rpc_encode_decode!(
compound_traits!(
enum TokenTree<G, P, I, L> {
Group(tt),
Punct(tt),
Expand Down

0 comments on commit d5f2ff5

Please sign in to comment.