rtic_macros/syntax/parse/
hardware_task.rs

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