Skip to content

Commit

Permalink
✨ Support deep path enum for auto! macro.
Browse files Browse the repository at this point in the history
  • Loading branch information
langyo committed Nov 14, 2024
1 parent ab11d3c commit 6530b1a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 23 deletions.
4 changes: 4 additions & 0 deletions yuuka-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,9 @@ pub fn auto(input: TokenStream) -> TokenStream {
.into()
}
}
AutoMacrosType::EnumSinglePath((key, next_key)) => quote! {
#ident::#key(#macro_ident!(#key 0 #next_key))
}
.into(),
}
}
41 changes: 18 additions & 23 deletions yuuka-macros/src/template/auto_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,24 @@ pub(crate) fn generate_enums_auto_macros(enums: EnumsFlatten) -> Vec<TokenStream
}
}
EnumValueFlatten::Tuple(items) => {
if items.len() == 1 {
let ty = items.first().expect("Failed to get first item");
quote! {
(#name { $($val:tt)+ }) => {
::yuuka::auto!(#ty { $($val)+ })
};
}
} else {
let list = items
.iter()
.enumerate()
.map(|(i, ty)| {
let i = syn::Index::from(i);
quote! {
(#name #i { $($val:tt)+ }) => {
::yuuka::auto!(#ty { $($val)+ })
};
}
})
.collect::<Vec<_>>();
quote! {
#(#list)*
}
let list = items
.iter()
.enumerate()
.map(|(i, ty)| {
let i = syn::Index::from(i);
quote! {
(#name #i $($val:tt)+) => {
::yuuka::auto!(#ty::$($val)+)
};

(#name #i { $($val:tt)+ }) => {
::yuuka::auto!(#ty { $($val)+ })
};
}
})
.collect::<Vec<_>>();
quote! {
#(#list)*
}
}
})
Expand Down
11 changes: 11 additions & 0 deletions yuuka-macros/src/tools/auto_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum AutoMacrosType {
EnumEmpty(Ident),
EnumStruct((Ident, Vec<(Ident, TokenStream)>)),
EnumTuple((Ident, Vec<TokenStream>)),
EnumSinglePath((Ident, TokenStream)),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -168,6 +169,16 @@ impl Parse for AutoMacros {
ident,
body: AutoMacrosType::EnumTuple((key, items)),
})
} else if input.peek(Token![::]) {
// Sth::Sth::Sth

input.parse::<Token![::]>()?;
let next_key: TokenStream = input.parse()?;

Ok(AutoMacros {
ident,
body: AutoMacrosType::EnumSinglePath((key, next_key)),
})
} else {
// Sth::Sth

Expand Down
55 changes: 55 additions & 0 deletions yuuka/tests/auto_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,59 @@ mod test {
})
);
}

#[test]
fn multi_level_enum() {
derive_enum!(
#[derive(PartialEq)]
enum A {
B(enum {
C(enum {
D(enum {
E(enum {
F,
G(String),
})
})
})
})
}
);

assert_eq!(
auto!(A::B::C::D::E::F),
A::B(_A_0_anonymous::C(_A_1_anonymous::D(_A_2_anonymous::E(
_A_3_anonymous::F
))))
);
assert_eq!(
auto!(A::B::C::D::E::G("いいよ!こいよ!".to_string())),
A::B(_A_0_anonymous::C(_A_1_anonymous::D(_A_2_anonymous::E(
_A_3_anonymous::G("いいよ!こいよ!".to_string())
))))
);
}

#[test]
fn mixed_auto() {
derive_struct!(
#[derive(PartialEq)]
Root {
outer: {
a: enum B {
C {
c: i32,
d: f64,
}
}
}
}
);

auto!(Root {
outer: {
a: auto!(B::C { c: 42, d: 3.14 })
}
});
}
}

0 comments on commit 6530b1a

Please sign in to comment.