use crate::*;
use syn::Ident;
pub(crate) fn generate_stream(
context: &Ident,
stream_method: &str,
data: &FromStreamData,
stmts: &[Stmt],
) -> TokenStream2 {
let method_ident: Ident = Ident::new(stream_method, proc_macro2::Span::call_site());
match data.variable_name.clone() {
Some(variable_name) => {
quote! {
while let Ok(#variable_name) = #context.#method_ident().await {
#(#stmts)*
}
}
}
None => {
quote! {
while #context.#method_ident().await.is_ok() {
#(#stmts)*
}
}
}
}
}
pub(crate) fn http_from_stream_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
let data: FromStreamData = parse_macro_input!(attr as FromStreamData);
let input_fn: ItemFn = parse_macro_input!(item as ItemFn);
let vis: &Visibility = &input_fn.vis;
let sig: &Signature = &input_fn.sig;
let block: &Block = &input_fn.block;
let attrs: &Vec<Attribute> = &input_fn.attrs;
match parse_context_from_signature(sig) {
Ok(context) => {
let stmts: &Vec<Stmt> = &block.stmts;
let loop_stream: TokenStream2 =
generate_stream(context, "http_from_stream", &data, stmts);
quote! {
#(#attrs)*
#vis #sig {
#loop_stream
}
}
.into()
}
Err(err) => err.to_compile_error().into(),
}
}
pub(crate) fn ws_from_stream_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
let data: FromStreamData = parse_macro_input!(attr as FromStreamData);
let input_fn: ItemFn = parse_macro_input!(item as ItemFn);
let vis: &Visibility = &input_fn.vis;
let sig: &Signature = &input_fn.sig;
let block: &Block = &input_fn.block;
let attrs: &Vec<Attribute> = &input_fn.attrs;
match parse_context_from_signature(sig) {
Ok(context) => {
let stmts: &Vec<Stmt> = &block.stmts;
let loop_stream: TokenStream2 =
generate_stream(context, "ws_from_stream", &data, stmts);
quote! {
#(#attrs)*
#vis #sig {
#loop_stream
}
}
.into()
}
Err(err) => err.to_compile_error().into(),
}
}