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}