actix_default_responder/
lib.rs1extern crate proc_macro;
2extern crate quote;
3
4use proc_macro::TokenStream;
5use quote::quote;
6
7enum ResponderType {
8 Json,
9 Xml,
10 Bincode,
11}
12
13#[proc_macro_derive(JsonResponder)]
14pub fn json_responder_derive(input: TokenStream) -> TokenStream {
15 let ast = syn::parse(input).unwrap();
16 impl_responder(&ast, ResponderType::Json)
17}
18
19#[proc_macro_derive(XMLResponder)]
20pub fn xml_responder_derive(input: TokenStream) -> TokenStream {
21 let ast = syn::parse(input).unwrap();
22 impl_responder(&ast, ResponderType::Xml)
23}
24
25#[proc_macro_derive(BincodeResponder)]
26pub fn bincode_responder_derive(input: TokenStream) -> TokenStream {
27 let ast = syn::parse(input).unwrap();
28 impl_responder(&ast, ResponderType::Bincode)
29}
30
31fn impl_responder(ast: &syn::DeriveInput, responder: ResponderType) -> TokenStream {
32 let name = &ast.ident;
33
34 let body = match responder {
35 ResponderType::Json => quote! {
36 match serde_json::to_string(&self) {
37 Ok(_body) => actix_web::HttpResponse::Ok().content_type("application/json").body(_body),
38 Err(_err) => actix_web::HttpResponse::build(
39 actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
40 ).body(_err.to_string()),
41 }
42 },
43 ResponderType::Xml => quote! {
44 match serde_xml_rs::to_string(&self) {
45 Ok(_body) => actix_web::HttpResponse::Ok().content_type("application/xml").body(_body),
46 Err(_err) => actix_web::HttpResponse::build(
47 actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
48 ).body(_err.to_string()),
49 }
50 },
51 ResponderType::Bincode => quote! {
52 match bincode::serialize(&self) {
53 Ok(_body) => actix_web::HttpResponse::Ok().content_type("multipart/form-data").body(_body),
54 Err(_err) => actix_web::HttpResponse::build(
55 actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
56 ).body(_err.to_string()),
57 }
58 },
59 };
60
61 let gen = quote! {
62 impl actix_web::Responder for #name {
63 type Body = actix_web::body::BoxBody;
64
65 #[inline]
66 fn respond_to(mut self, req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> {
67 #body
68 }
69
70 }
71 };
72
73 gen.into()
74}