thruster_socketio_proc/
lib.rs1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use proc_macro2::{Ident, Span as Span2};
5use quote::quote;
6
7#[proc_macro_attribute]
8pub fn socketio_handler(attr: TokenStream, item: TokenStream) -> TokenStream {
9 if let syn::Item::Fn(mut function_item) = syn::parse(item.clone()).unwrap() {
10 let name = function_item.ident.clone();
11 let new_name = Ident::new(&format!("__async_{}", name.clone()), Span2::call_site());
12 function_item.ident = new_name.clone();
13
14 let visibility = function_item.vis.clone();
15 let arguments = function_item.decl.inputs.clone();
16 let generics = function_item.decl.generics.clone();
17
18 let context_type = match &arguments[0] {
19 syn::FnArg::Captured(cap) => &cap.ty,
20 _ => panic!("Expected the first argument to be a context type"),
21 };
22 let socket_io_type = Ident::new(&format!("__SocketIO_{}", name.clone()), Span2::call_site());
23 let crate_path = match attr.to_string().as_str() {
24 "_internal" => quote! {
25 crate::core::{ IOSocketWrapper as #socket_io_type }
26 },
27 _ => quote! {
28 thruster_socketio::{ SocketIO as #socket_io_type }
29 },
30 };
31
32 let gen = quote! {
33 #function_item
34
35 use #crate_path;
36 #visibility fn #name#generics(socket: #context_type) -> Pin<Box<dyn Future<Output = Result<#context_type, ()>> + Send>> {
37 Box::pin(#new_name(socket))
38 }
39 };
40
41 gen.into()
47 } else {
48 item
49 }
50}
51
52#[proc_macro_attribute]
53pub fn socketio_listener(attr: TokenStream, item: TokenStream) -> TokenStream {
54 if let syn::Item::Fn(mut function_item) = syn::parse(item.clone()).unwrap() {
55 let name = function_item.ident.clone();
56 let new_name = Ident::new(&format!("__async_{}", name.clone()), Span2::call_site());
57 function_item.ident = new_name.clone();
58
59 let visibility = function_item.vis.clone();
60 let arguments = function_item.decl.inputs.clone();
61 let generics = function_item.decl.generics.clone();
62
63 let socket_type = match &arguments[0] {
64 syn::FnArg::Captured(cap) => &cap.ty,
65 _ => panic!("Expected the first argument to be a socket type"),
66 };
67
68 let socket_io_type = Ident::new(&format!("__SocketIOListener_{}", name.clone()), Span2::call_site());
69 let crate_path = match attr.to_string().as_str() {
70 "_internal" => quote! {
71 crate::core::{ IOSocketWrapper as #socket_io_type }
72 },
73 _ => quote! {
74 thruster_socketio::{ SocketIO as #socket_io_type }
75 },
76 };
77
78 let gen = quote! {
79 #function_item
80
81 use #crate_path;
82 #visibility fn #name#generics(socket: #socket_type, value: String) -> Pin<Box<dyn Future<Output = Result<(), ()>> + Send>> {
83 Box::pin(#new_name(socket, value))
84 }
85 };
86
87 gen.into()
93 } else {
94 item
95 }
96}