1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::punctuated::Punctuated;
5use syn::token::Comma;
6use syn::{Expr, Type};
7
8pub struct ParsePunctuated<T>(pub Punctuated<T, Comma>);
9
10impl<T: Parse> Parse for ParsePunctuated<T> {
11 fn parse(input: ParseStream) -> syn::Result<Self> {
12 let types = Punctuated::parse_terminated(input)?;
13 Ok(ParsePunctuated(types))
14 }
15}
16
17pub fn make_product_type(input: TokenStream) -> TokenStream {
18 let types: ParsePunctuated<Type> = syn::parse2(input).unwrap();
19
20 types.0.iter().rfold(quote! { ε }, |res, item| {
21 quote! {
22 π< #item , #res >
23 }
24 })
25}
26
27pub fn make_sum_type(input: TokenStream) -> TokenStream {
28 let types: ParsePunctuated<Type> = syn::parse2(input).unwrap();
29
30 types.0.iter().rfold(quote! { θ }, |res, item| {
31 quote! {
32 σ< #item , #res >
33 }
34 })
35}
36
37pub fn make_product_expr(input: TokenStream) -> TokenStream {
38 let types: ParsePunctuated<Expr> = syn::parse2(input).unwrap();
39
40 types.0.iter().rfold(quote! { ε }, |res, item| {
41 quote! {
42 π( #item , #res )
43 }
44 })
45}