rtic_macros/syntax/parse/
idle.rs
1use proc_macro2::TokenStream as TokenStream2;
2use syn::{parse, ForeignItemFn, ItemFn, Stmt};
3
4use crate::syntax::{
5 ast::{Idle, IdleArgs},
6 parse::util,
7};
8
9impl IdleArgs {
10 pub(crate) fn parse(tokens: TokenStream2) -> parse::Result<Self> {
11 crate::syntax::parse::idle_args(tokens)
12 }
13}
14
15impl Idle {
16 pub(crate) fn parse(args: IdleArgs, item: ItemFn) -> parse::Result<Self> {
17 let valid_signature = util::check_fn_signature(&item, false)
18 && item.sig.inputs.len() == 1
19 && util::type_is_bottom(&item.sig.output);
20
21 let name = item.sig.ident.to_string();
22
23 if valid_signature {
24 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
25 if rest.is_empty() {
26 return Ok(Idle {
27 args,
28 attrs: item.attrs,
29 context,
30 name: item.sig.ident,
31 stmts: item.block.stmts,
32 is_extern: false,
33 });
34 }
35 }
36 }
37
38 Err(parse::Error::new(
39 item.sig.ident.span(),
40 format!("this `#[idle]` function must have signature `fn({name}::Context) -> !`"),
41 ))
42 }
43
44 pub(crate) fn parse_foreign(args: IdleArgs, item: ForeignItemFn) -> parse::Result<Self> {
45 let valid_signature = util::check_foreign_fn_signature(&item, false)
46 && item.sig.inputs.len() == 1
47 && util::type_is_bottom(&item.sig.output);
48
49 let name = item.sig.ident.to_string();
50
51 if valid_signature {
52 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
53 if rest.is_empty() {
54 return Ok(Idle {
55 args,
56 attrs: item.attrs,
57 context,
58 name: item.sig.ident,
59 stmts: Vec::<Stmt>::new(),
60 is_extern: true,
61 });
62 }
63 }
64 }
65
66 Err(parse::Error::new(
67 item.sig.ident.span(),
68 format!("this `#[idle]` function must have signature `fn({name}::Context) -> !`"),
69 ))
70 }
71}