rtic_syntax/parse/
hardware_task.rs
1use syn::{parse, ForeignItemFn, ItemFn, Stmt};
2
3use crate::parse::util::FilterAttrs;
4use crate::{
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)
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 name == "init" || name == "idle" {
19 return Err(parse::Error::new(
20 span,
21 "tasks cannot be named `init` or `idle`",
22 ));
23 }
24
25 if valid_signature {
26 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
27 if rest.is_empty() {
28 let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
29
30 return Ok(HardwareTask {
31 args,
32 cfgs,
33 attrs,
34 context,
35 stmts: item.block.stmts,
36 is_extern: false,
37 });
38 }
39 }
40 }
41
42 Err(parse::Error::new(
43 span,
44 format!(
45 "this task handler must have type signature `fn({}::Context)`",
46 name
47 ),
48 ))
49 }
50}
51
52impl HardwareTask {
53 pub(crate) fn parse_foreign(
54 args: HardwareTaskArgs,
55 item: ForeignItemFn,
56 ) -> parse::Result<Self> {
57 let span = item.sig.ident.span();
58 let valid_signature = util::check_foreign_fn_signature(&item)
59 && item.sig.inputs.len() == 1
60 && util::type_is_unit(&item.sig.output);
61
62 let name = item.sig.ident.to_string();
63
64 if name == "init" || name == "idle" {
65 return Err(parse::Error::new(
66 span,
67 "tasks cannot be named `init` or `idle`",
68 ));
69 }
70
71 if valid_signature {
72 if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
73 if rest.is_empty() {
74 let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
75
76 return Ok(HardwareTask {
77 args,
78 cfgs,
79 attrs,
80 context,
81 stmts: Vec::<Stmt>::new(),
82 is_extern: true,
83 });
84 }
85 }
86 }
87
88 Err(parse::Error::new(
89 span,
90 format!(
91 "this task handler must have type signature `fn({}::Context)`",
92 name
93 ),
94 ))
95 }
96}