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