#![deny(warnings)]
use proc_macro2::{Span, TokenStream};
use syn::{
ItemFn,
parse::{self},
};
pub fn main(args: TokenStream, f: ItemFn) -> TokenStream {
if f.sig.asyncness.is_some() {
return parse::Error::new(
Span::call_site(),
"If you want to use `async` please use `esp-rtos`'s `#[esp_rtos::main]` macro instead.",
)
.to_compile_error();
}
if !args.is_empty() {
return parse::Error::new(Span::call_site(), "This attribute accepts no arguments")
.to_compile_error();
}
let root = match proc_macro_crate::crate_name("esp-hal") {
Ok(proc_macro_crate::FoundCrate::Name(ref name)) => quote::format_ident!("{name}"),
_ => quote::format_ident!("esp_hal"),
};
quote::quote!(
#[doc = "The main entry point of the firmware, generated by the `#[main]` macro."]
#[#root::__macro_implementation::__entry]
#f
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic() {
let result = main(
quote::quote! {}.into(),
syn::parse2(quote::quote! {
fn main() {}
})
.unwrap(),
);
assert_eq!(
result.to_string(),
quote::quote! {
#[doc = "The main entry point of the firmware, generated by the `#[main]` macro."]
#[esp_hal::__macro_implementation::__entry]
fn main () { }
}
.to_string()
);
}
#[test]
fn test_try_async() {
let result = main(
quote::quote! {}.into(),
syn::parse2(quote::quote! {
async fn main() {}
})
.unwrap(),
);
assert_eq!(
result.to_string(),
quote::quote! {
::core::compile_error!{ "If you want to use `async` please use `esp-rtos`'s `#[esp_rtos::main]` macro instead." }
}
.to_string()
);
}
#[test]
fn test_try_non_emptyargs() {
let result = main(
quote::quote! {non_empty}.into(),
syn::parse2(quote::quote! {
fn main() {}
})
.unwrap(),
);
assert_eq!(
result.to_string(),
quote::quote! {
::core::compile_error!{ "This attribute accepts no arguments" }
}
.to_string()
);
}
}