purescript_waterslide_derive/
lib.rs1#![deny(warnings)]
2
3extern crate syn;
4extern crate proc_macro;
5extern crate proc_macro2;
6#[macro_use]
7extern crate quote;
8
9extern crate purescript_waterslide;
10
11mod purescript;
12mod generics;
13
14use quote::Tokens;
15use purescript::{make_purs_constructor_impl, make_purs_type};
16
17#[proc_macro_derive(AsPursType)]
18pub fn derive_purstype(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
19 let input = input.to_string();
20 let ast =
21 syn::parse_derive_input(&input).expect("Purescript waterslide could not parse input type");
22
23 let name = &ast.ident;
24 let generics = generics::shift_generics(&ast);
25 let placeholder_generics: Vec<Tokens> = ast.generics
26 .ty_params
27 .iter()
28 .map(generics::make_dummy_generic)
29 .collect();
30 let placeholder_generics_clone = placeholder_generics.clone();
31
32 let as_purs_constructor_impl = match make_purs_constructor_impl(&ast) {
33 Ok(generated_impl) => generated_impl,
34 Err(err) => panic!(
35 "Could not convert the input to Purescript type constructor: {:?}",
36 err
37 ),
38 };
39
40 let as_purs_impl = match make_purs_type(&ast) {
41 Ok(generated_impl) => generated_impl,
42 Err(err) => panic!("Could not convert the input to Purescript AST: {:?}", err),
43 };
44
45 let expanded = quote! {
46 impl#generics ::purescript_waterslide::AsPursConstructor for #name#generics {
47 fn as_purs_constructor() -> ::purescript_waterslide::PursConstructor {
48 #( #placeholder_generics )*
49
50 #as_purs_constructor_impl
51 }
52 }
53
54 impl#generics ::purescript_waterslide::AsPursType for #name#generics {
55 fn as_purs_type() -> ::purescript_waterslide::PursType {
56 #( #placeholder_generics_clone )*
57
58 #as_purs_impl
59 }
60 }
61 };
62
63 expanded.parse().unwrap()
64}