rtic_macros/syntax/parse/
init.rs
1use crate::syntax::TokenStream2;
2use syn::{parse, ForeignItemFn, ItemFn, Stmt};
3
4use crate::syntax::{
5 ast::{Init, InitArgs},
6 parse::{self as syntax_parse, util},
7};
8
9impl InitArgs {
10 pub(crate) fn parse(tokens: TokenStream2) -> parse::Result<Self> {
11 syntax_parse::init_args(tokens)
12 }
13}
14
15impl Init {
16 pub(crate) fn parse(args: InitArgs, item: ItemFn) -> parse::Result<Self> {
17 let valid_signature = util::check_fn_signature(&item, false) && item.sig.inputs.len() == 1;
18
19 let span = item.sig.ident.span();
20
21 let name = item.sig.ident.to_string();
22
23 if valid_signature {
24 if let Ok((user_shared_struct, user_local_struct)) =
25 util::type_is_init_return(&item.sig.output)
26 {
27 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
28 if rest.is_empty() {
29 return Ok(Init {
30 args,
31 attrs: item.attrs,
32 context,
33 name: item.sig.ident,
34 stmts: item.block.stmts,
35 user_shared_struct,
36 user_local_struct,
37 is_extern: false,
38 });
39 }
40 }
41 }
42 }
43
44 Err(parse::Error::new(
45 span,
46 format!(
47 "the `#[init]` function must have signature `fn({name}::Context) -> (Shared resources struct, Local resources struct)`"
48 ),
49 ))
50 }
51
52 pub(crate) fn parse_foreign(args: InitArgs, item: ForeignItemFn) -> parse::Result<Self> {
53 let valid_signature =
54 util::check_foreign_fn_signature(&item, false) && item.sig.inputs.len() == 1;
55
56 let span = item.sig.ident.span();
57
58 let name = item.sig.ident.to_string();
59
60 if valid_signature {
61 if let Ok((user_shared_struct, user_local_struct)) =
62 util::type_is_init_return(&item.sig.output)
63 {
64 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
65 if rest.is_empty() {
66 return Ok(Init {
67 args,
68 attrs: item.attrs,
69 context,
70 name: item.sig.ident,
71 stmts: Vec::<Stmt>::new(),
72 user_shared_struct,
73 user_local_struct,
74 is_extern: true,
75 });
76 }
77 }
78 }
79 }
80
81 Err(parse::Error::new(
82 span,
83 format!(
84 "the `#[init]` function must have signature `fn({name}::Context) -> (Shared resources struct, Local resources struct)`"
85 ),
86 ))
87 }
88}