aboutsummaryrefslogtreecommitdiff
path: root/macros/src/syntax/parse
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/syntax/parse')
-rw-r--r--macros/src/syntax/parse/hardware_task.rs58
-rw-r--r--macros/src/syntax/parse/idle.rs18
-rw-r--r--macros/src/syntax/parse/init.rs22
-rw-r--r--macros/src/syntax/parse/software_task.rs10
-rw-r--r--macros/src/syntax/parse/util.rs30
5 files changed, 72 insertions, 66 deletions
diff --git a/macros/src/syntax/parse/hardware_task.rs b/macros/src/syntax/parse/hardware_task.rs
index c13426f4..7f6dfbe4 100644
--- a/macros/src/syntax/parse/hardware_task.rs
+++ b/macros/src/syntax/parse/hardware_task.rs
@@ -15,25 +15,20 @@ impl HardwareTask {
let name = item.sig.ident.to_string();
- if name == "init" || name == "idle" {
- return Err(parse::Error::new(
- span,
- "tasks cannot be named `init` or `idle`",
- ));
- }
-
if valid_signature {
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
- let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
+ if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
+ if rest.is_empty() {
+ let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
- return Ok(HardwareTask {
- args,
- cfgs,
- attrs,
- context,
- stmts: item.block.stmts,
- is_extern: false,
- });
+ return Ok(HardwareTask {
+ args,
+ cfgs,
+ attrs,
+ context,
+ stmts: item.block.stmts,
+ is_extern: false,
+ });
+ }
}
}
@@ -56,25 +51,20 @@ impl HardwareTask {
let name = item.sig.ident.to_string();
- if name == "init" || name == "idle" {
- return Err(parse::Error::new(
- span,
- "tasks cannot be named `init` or `idle`",
- ));
- }
-
if valid_signature {
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
- let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
+ if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
+ if rest.is_empty() {
+ let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
- return Ok(HardwareTask {
- args,
- cfgs,
- attrs,
- context,
- stmts: Vec::<Stmt>::new(),
- is_extern: true,
- });
+ return Ok(HardwareTask {
+ args,
+ cfgs,
+ attrs,
+ context,
+ stmts: Vec::<Stmt>::new(),
+ is_extern: true,
+ });
+ }
}
}
diff --git a/macros/src/syntax/parse/idle.rs b/macros/src/syntax/parse/idle.rs
index f049cca8..124c1366 100644
--- a/macros/src/syntax/parse/idle.rs
+++ b/macros/src/syntax/parse/idle.rs
@@ -21,14 +21,16 @@ impl Idle {
let name = item.sig.ident.to_string();
if valid_signature {
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
- return Ok(Idle {
- args,
- attrs: item.attrs,
- context,
- name: item.sig.ident,
- stmts: item.block.stmts,
- });
+ if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
+ if rest.is_empty() {
+ return Ok(Idle {
+ args,
+ attrs: item.attrs,
+ context,
+ name: item.sig.ident,
+ stmts: item.block.stmts,
+ });
+ }
}
}
diff --git a/macros/src/syntax/parse/init.rs b/macros/src/syntax/parse/init.rs
index 23130c85..0aea20bd 100644
--- a/macros/src/syntax/parse/init.rs
+++ b/macros/src/syntax/parse/init.rs
@@ -25,16 +25,18 @@ impl Init {
if let Ok((user_shared_struct, user_local_struct)) =
util::type_is_init_return(&item.sig.output)
{
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
- return Ok(Init {
- args,
- attrs: item.attrs,
- context,
- name: item.sig.ident,
- stmts: item.block.stmts,
- user_shared_struct,
- user_local_struct,
- });
+ if let Some((context, Ok(rest))) = util::parse_inputs(item.sig.inputs, &name) {
+ if rest.is_empty() {
+ return Ok(Init {
+ args,
+ attrs: item.attrs,
+ context,
+ name: item.sig.ident,
+ stmts: item.block.stmts,
+ user_shared_struct,
+ user_local_struct,
+ });
+ }
}
}
}
diff --git a/macros/src/syntax/parse/software_task.rs b/macros/src/syntax/parse/software_task.rs
index fb9b37c4..769aa653 100644
--- a/macros/src/syntax/parse/software_task.rs
+++ b/macros/src/syntax/parse/software_task.rs
@@ -17,7 +17,7 @@ impl SoftwareTask {
let name = item.sig.ident.to_string();
if valid_signature {
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
+ if let Some((context, Ok(inputs))) = util::parse_inputs(item.sig.inputs, &name) {
let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
return Ok(SoftwareTask {
@@ -25,6 +25,7 @@ impl SoftwareTask {
attrs,
cfgs,
context,
+ inputs,
stmts: item.block.stmts,
is_extern: false,
});
@@ -33,7 +34,7 @@ impl SoftwareTask {
Err(parse::Error::new(
span,
- format!("this task handler must have type signature `async fn({name}::Context)`"),
+ format!("this task handler must have type signature `async fn({name}::Context, ..)`"),
))
}
}
@@ -52,7 +53,7 @@ impl SoftwareTask {
let name = item.sig.ident.to_string();
if valid_signature {
- if let Some(context) = util::parse_inputs(item.sig.inputs, &name) {
+ if let Some((context, Ok(inputs))) = util::parse_inputs(item.sig.inputs, &name) {
let FilterAttrs { cfgs, attrs, .. } = util::filter_attributes(item.attrs);
return Ok(SoftwareTask {
@@ -60,6 +61,7 @@ impl SoftwareTask {
attrs,
cfgs,
context,
+ inputs,
stmts: Vec::<Stmt>::new(),
is_extern: true,
});
@@ -68,7 +70,7 @@ impl SoftwareTask {
Err(parse::Error::new(
span,
- format!("this task handler must have type signature `async fn({name}::Context)`"),
+ format!("this task handler must have type signature `async fn({name}::Context, ..)`"),
))
}
}
diff --git a/macros/src/syntax/parse/util.rs b/macros/src/syntax/parse/util.rs
index 900ef9d6..5a5e0c0e 100644
--- a/macros/src/syntax/parse/util.rs
+++ b/macros/src/syntax/parse/util.rs
@@ -3,8 +3,8 @@ use syn::{
parse::{self, ParseStream},
punctuated::Punctuated,
spanned::Spanned,
- Abi, AttrStyle, Attribute, Expr, FnArg, ForeignItemFn, Ident, ItemFn, Pat, Path, PathArguments,
- ReturnType, Token, Type, Visibility,
+ Abi, AttrStyle, Attribute, Expr, FnArg, ForeignItemFn, Ident, ItemFn, Pat, PatType, Path,
+ PathArguments, ReturnType, Token, Type, Visibility,
};
use crate::syntax::{
@@ -231,19 +231,29 @@ pub fn parse_local_resources(content: ParseStream<'_>) -> parse::Result<LocalRes
Ok(resources)
}
-pub fn parse_inputs(inputs: Punctuated<FnArg, Token![,]>, name: &str) -> Option<Box<Pat>> {
+type ParseInputResult = Option<(Box<Pat>, Result<Vec<PatType>, FnArg>)>;
+
+pub fn parse_inputs(inputs: Punctuated<FnArg, Token![,]>, name: &str) -> ParseInputResult {
let mut inputs = inputs.into_iter();
- if let Some(FnArg::Typed(first)) = inputs.next() {
- if type_is_path(&first.ty, &[name, "Context"]) {
- // No more inputs
- if inputs.next().is_none() {
- return Some(first.pat);
+ match inputs.next() {
+ Some(FnArg::Typed(first)) => {
+ if type_is_path(&first.ty, &[name, "Context"]) {
+ let rest = inputs
+ .map(|arg| match arg {
+ FnArg::Typed(arg) => Ok(arg),
+ _ => Err(arg),
+ })
+ .collect::<Result<Vec<_>, _>>();
+
+ Some((first.pat, rest))
+ } else {
+ None
}
}
- }
- None
+ _ => None,
+ }
}
pub fn type_is_bottom(ty: &ReturnType) -> bool {