11#![ no_std]
22
3- type MenuCallbackFn < T > = fn ( menu : & Menu < T > ) ;
3+ type MenuCallbackFn < T > = fn ( menu : & Menu < T > , context : & mut T ) ;
44type ItemCallbackFn < T > = fn ( menu : & Menu < T > , item : & Item < T > , args : & str , context : & mut T ) ;
55
66pub enum ItemType < ' a , T >
5656{
5757 pub fn new ( menu : & ' a Menu < ' a , T > , buffer : & ' a mut [ u8 ] , context : & ' a mut T ) -> Runner < ' a , T > {
5858 if let Some ( cb_fn) = menu. entry {
59- cb_fn ( menu) ;
59+ cb_fn ( menu, context ) ;
6060 }
6161 let mut r = Runner {
6262 menus : [ Some ( menu) , None , None , None ] ,
@@ -96,25 +96,30 @@ where
9696 if let Ok ( s) = core:: str:: from_utf8 ( & self . buffer [ 0 ..self . used ] ) {
9797 if s == "help" {
9898 let menu = self . menus [ self . depth ] . unwrap ( ) ;
99+ let mut max_len = 1 ;
100+ for item in menu. items {
101+ max_len = max_len. max ( item. command . len ( ) ) ;
102+ }
99103 for item in menu. items {
100104 if let Some ( help) = item. help {
101- writeln ! ( self . context, "{} - {}" , item. command, help) . unwrap ( ) ;
105+ writeln ! ( self . context, "* {:width$} - {}" , item. command, help, width=max_len ) . unwrap ( ) ;
102106 } else {
103- writeln ! ( self . context, "{}" , item. command) . unwrap ( ) ;
107+ writeln ! ( self . context, "* {}" , item. command) . unwrap ( ) ;
104108 }
105109 }
106110 if self . depth != 0 {
107- writeln ! ( self . context, "exit - leave this menu." ) . unwrap ( ) ;
111+ writeln ! ( self . context, "* {:width$} - leave this menu." , "exit" , width=max_len ) . unwrap ( ) ;
108112 }
109- writeln ! ( self . context, "help - print this help text." ) . unwrap ( ) ;
113+ writeln ! ( self . context, "* {:width$} - print this help text." , "help" , width=max_len ) . unwrap ( ) ;
110114 Outcome :: CommandProcessed
111- } else if s == "exit" && self . depth != 0 {
112- if self . depth == self . menus . len ( ) {
113- writeln ! ( self . context , "Can't enter menu - structure too deep." ) . unwrap ( ) ;
114- } else {
115- self . menus [ self . depth ] = None ;
116- self . depth -= 1 ;
115+ } else if s == "exit" && self . depth > 0 {
116+ // Can't be None if we've managed to get to this level
117+ let menu = self . menus [ self . depth ] . unwrap ( ) ;
118+ self . menus [ self . depth ] = None ;
119+ if let Some ( cb_fn ) = menu . exit {
120+ cb_fn ( menu , & mut self . context ) ;
117121 }
122+ self . depth -= 1 ;
118123 Outcome :: CommandProcessed
119124 } else {
120125 let mut parts = s. split ( ' ' ) ;
@@ -126,8 +131,16 @@ where
126131 match item. item_type {
127132 ItemType :: Callback ( f) => f ( menu, item, s, & mut self . context ) ,
128133 ItemType :: Menu ( m) => {
129- self . depth += 1 ;
130- self . menus [ self . depth ] = Some ( m) ;
134+ if ( self . depth + 1 ) >= self . menus . len ( ) {
135+ writeln ! ( self . context, "Can't enter menu - structure too deep." ) . unwrap ( ) ;
136+ } else {
137+ // self.menus[0] is the root menu, so go up one level first.
138+ self . depth += 1 ;
139+ self . menus [ self . depth ] = Some ( m) ;
140+ if let Some ( cb_fn) = m. entry {
141+ cb_fn ( m, & mut self . context ) ;
142+ }
143+ }
131144 }
132145 }
133146 found = true ;
0 commit comments