@@ -2155,6 +2155,12 @@ impl From<anyhow::Error> for ConfigError {
21552155 }
21562156}
21572157
2158+ #[ derive( Debug ) ]
2159+ enum KeyOrIdx {
2160+ Key ( String ) ,
2161+ Idx ( usize ) ,
2162+ }
2163+
21582164#[ derive( Eq , PartialEq , Clone ) ]
21592165pub enum ConfigValue {
21602166 Integer ( i64 , Definition ) ,
@@ -2197,26 +2203,56 @@ impl ConfigValue {
21972203 }
21982204
21992205 fn from_toml ( def : Definition , toml : toml:: Value ) -> CargoResult < ConfigValue > {
2206+ let mut error_path = Vec :: new ( ) ;
2207+ Self :: from_toml_inner ( def, toml, & mut error_path) . with_context ( || {
2208+ let mut it = error_path. iter ( ) . rev ( ) . peekable ( ) ;
2209+ let mut key_path = String :: with_capacity ( error_path. len ( ) * 3 ) ;
2210+ while let Some ( k) = it. next ( ) {
2211+ match k {
2212+ KeyOrIdx :: Key ( s) => key_path. push_str ( & key:: escape_key_part ( & s) ) ,
2213+ KeyOrIdx :: Idx ( i) => key_path. push_str ( & format ! ( "[{i}]" ) ) ,
2214+ }
2215+ if matches ! ( it. peek( ) , Some ( KeyOrIdx :: Key ( _) ) ) {
2216+ key_path. push ( '.' ) ;
2217+ }
2218+ }
2219+ format ! ( "failed to parse config at `{key_path}`" )
2220+ } )
2221+ }
2222+
2223+ fn from_toml_inner (
2224+ def : Definition ,
2225+ toml : toml:: Value ,
2226+ path : & mut Vec < KeyOrIdx > ,
2227+ ) -> CargoResult < ConfigValue > {
22002228 match toml {
22012229 toml:: Value :: String ( val) => Ok ( CV :: String ( val, def) ) ,
22022230 toml:: Value :: Boolean ( b) => Ok ( CV :: Boolean ( b, def) ) ,
22032231 toml:: Value :: Integer ( i) => Ok ( CV :: Integer ( i, def) ) ,
22042232 toml:: Value :: Array ( val) => Ok ( CV :: List (
22052233 val. into_iter ( )
2206- . map ( |toml| match toml {
2234+ . enumerate ( )
2235+ . map ( |( i, toml) | match toml {
22072236 toml:: Value :: String ( val) => Ok ( ( val, def. clone ( ) ) ) ,
2208- v => bail ! ( "expected string but found {} in list" , v. type_str( ) ) ,
2237+ v => {
2238+ path. push ( KeyOrIdx :: Idx ( i) ) ;
2239+ bail ! ( "expected string but found {} in list" , v. type_str( ) )
2240+ }
22092241 } )
22102242 . collect :: < CargoResult < _ > > ( ) ?,
22112243 def,
22122244 ) ) ,
22132245 toml:: Value :: Table ( val) => Ok ( CV :: Table (
22142246 val. into_iter ( )
2215- . map ( |( key, value) | {
2216- let value = CV :: from_toml ( def. clone ( ) , value)
2217- . with_context ( || format ! ( "failed to parse key `{}`" , key) ) ?;
2218- Ok ( ( key, value) )
2219- } )
2247+ . map (
2248+ |( key, value) | match CV :: from_toml_inner ( def. clone ( ) , value, path) {
2249+ Ok ( value) => Ok ( ( key, value) ) ,
2250+ Err ( e) => {
2251+ path. push ( KeyOrIdx :: Key ( key) ) ;
2252+ Err ( e)
2253+ }
2254+ } ,
2255+ )
22202256 . collect :: < CargoResult < _ > > ( ) ?,
22212257 def,
22222258 ) ) ,
0 commit comments