rtic_syntax/parse/
software_task.rs

1use syn::{parse, ForeignItemFn, ItemFn, Stmt};
2
3use crate::parse::util::FilterAttrs;
4use crate::{
5    ast::{SoftwareTask, SoftwareTaskArgs},
6    parse::util,
7};
8
9impl SoftwareTask {
10    pub(crate) fn parse(args: SoftwareTaskArgs, item: ItemFn) -> parse::Result<Self> {
11        let valid_signature =
12            util::check_fn_signature(&item) && util::type_is_unit(&item.sig.output);
13
14        let span = item.sig.ident.span();
15
16        let name = item.sig.ident.to_string();
17
18        if valid_signature {
19            if let Some((context, Ok(inputs))) = util::parse_inputs(item.sig.inputs, &name) {
20                let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
21
22                return Ok(SoftwareTask {
23                    args,
24                    attrs,
25                    cfgs,
26                    context,
27                    inputs,
28                    stmts: item.block.stmts,
29                    is_extern: false,
30                });
31            }
32        }
33
34        Err(parse::Error::new(
35            span,
36            format!(
37                "this task handler must have type signature `fn({}::Context, ..)`",
38                name
39            ),
40        ))
41    }
42}
43
44impl SoftwareTask {
45    pub(crate) fn parse_foreign(
46        args: SoftwareTaskArgs,
47        item: ForeignItemFn,
48    ) -> parse::Result<Self> {
49        let valid_signature =
50            util::check_foreign_fn_signature(&item) && util::type_is_unit(&item.sig.output);
51
52        let span = item.sig.ident.span();
53
54        let name = item.sig.ident.to_string();
55
56        if valid_signature {
57            if let Some((context, Ok(inputs))) = util::parse_inputs(item.sig.inputs, &name) {
58                let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
59
60                return Ok(SoftwareTask {
61                    args,
62                    attrs,
63                    cfgs,
64                    context,
65                    inputs,
66                    stmts: Vec::<Stmt>::new(),
67                    is_extern: true,
68                });
69            }
70        }
71
72        Err(parse::Error::new(
73            span,
74            format!(
75                "this task handler must have type signature `fn({}::Context, ..)`",
76                name
77            ),
78        ))
79    }
80}