cgp_macro_lib/
product.rs

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}