@@ -383,7 +383,46 @@ impl App {
383383 for item in mod_. items {
384384 if let ForeignItem :: Fn ( mut item) = item {
385385 let span = item. sig . ident . span ( ) ;
386+ // Find externally defined #[init] tasks
386387 if let Some ( pos) = item
388+ . attrs
389+ . iter ( )
390+ . position ( |attr| util:: attr_eq ( attr, "init" ) )
391+ {
392+ let args = InitArgs :: parse ( item. attrs . remove ( pos) . tokens ) ?;
393+
394+ // If an init function already exists, error
395+ if init. is_some ( ) {
396+ return Err ( parse:: Error :: new (
397+ span,
398+ "`#[init]` function must appear at most once" ,
399+ ) ) ;
400+ }
401+
402+ check_ident ( & item. sig . ident ) ?;
403+
404+ init = Some ( Init :: parse_foreign ( args, item. clone ( ) ) ?) ;
405+
406+ // Find externally defined #[idle] tasks
407+ } else if let Some ( pos) = item
408+ . attrs
409+ . iter ( )
410+ . position ( |attr| util:: attr_eq ( attr, "idle" ) )
411+ {
412+ let args = IdleArgs :: parse ( item. attrs . remove ( pos) . tokens ) ?;
413+
414+ // If an idle function already exists, error
415+ if idle. is_some ( ) {
416+ return Err ( parse:: Error :: new (
417+ span,
418+ "`#[idle]` function must appear at most once" ,
419+ ) ) ;
420+ }
421+
422+ check_ident ( & item. sig . ident ) ?;
423+
424+ idle = Some ( Idle :: parse_foreign ( args, item. clone ( ) ) ?) ;
425+ } else if let Some ( pos) = item
387426 . attrs
388427 . iter ( )
389428 . position ( |attr| util:: attr_eq ( attr, "task" ) )
@@ -400,7 +439,7 @@ impl App {
400439 if item. attrs . len ( ) != 1 {
401440 return Err ( parse:: Error :: new (
402441 span,
403- "`extern` task required `#[task(..)]` attribute " ,
442+ "`extern` tasks only supports one attribute: `#[task(..)]`" ,
404443 ) ) ;
405444 }
406445
@@ -430,14 +469,10 @@ impl App {
430469 } else {
431470 return Err ( parse:: Error :: new (
432471 span,
433- "`extern` task required `#[task(..)]` attribute" ,
472+ "`extern` task, init or idle must have either `#[task(..)]`,
473+ `#[init(..)]` or `#[idle(..)]` attribute" ,
434474 ) ) ;
435475 }
436- } else {
437- return Err ( parse:: Error :: new (
438- item. span ( ) ,
439- "this item must live outside the `#[app]` module" ,
440- ) ) ;
441476 }
442477 }
443478 }
0 commit comments