@@ -27,7 +27,8 @@ use {Error, Result};
2727/// * As a raw string literal, e.g. `foo = r#"hello "world""#`.
2828///
2929/// ## ()
30- /// * Word with no value specified, e.g. `foo`. This is best used with `Option`.
30+ /// * Word with no value specified, e.g. `foo`. This is best used with `Option`.
31+ /// See `darling::util::Flag` for a more strongly-typed alternative.
3132///
3233/// ## Option
3334/// * Any format produces `Some`.
@@ -189,6 +190,14 @@ impl<T: FromMetaItem> FromMetaItem for Result<T> {
189190 }
190191}
191192
193+ /// Parses the meta-item, and in case of error preserves a copy of the input for
194+ /// later analysis.
195+ impl < T : FromMetaItem > FromMetaItem for :: std:: result:: Result < T , MetaItem > {
196+ fn from_meta_item ( item : & MetaItem ) -> Result < Self > {
197+ T :: from_meta_item ( item) . map ( Ok ) . or_else ( |_| Ok ( Err ( item. clone ( ) ) ) )
198+ }
199+ }
200+
192201impl < T : FromMetaItem > FromMetaItem for Rc < T > {
193202 fn from_meta_item ( item : & MetaItem ) -> Result < Self > {
194203 Ok ( Rc :: new ( FromMetaItem :: from_meta_item ( item) ?) )
@@ -214,7 +223,11 @@ impl<V: FromMetaItem> FromMetaItem for HashMap<String, V> {
214223 if let syn:: NestedMetaItem :: MetaItem ( ref inner) = * item {
215224 match map. entry ( inner. name ( ) . to_string ( ) ) {
216225 Entry :: Occupied ( _) => return Err ( Error :: duplicate_field ( inner. name ( ) ) ) ,
217- Entry :: Vacant ( entry) => { entry. insert ( FromMetaItem :: from_meta_item ( inner) ?) ; }
226+ Entry :: Vacant ( entry) => {
227+ entry. insert (
228+ FromMetaItem :: from_meta_item ( inner) . map_err ( |e| e. at ( inner. name ( ) ) ) ?
229+ ) ;
230+ }
218231 }
219232 }
220233 }
@@ -229,7 +242,7 @@ impl<V: FromMetaItem> FromMetaItem for HashMap<String, V> {
229242mod tests {
230243 use syn;
231244
232- use { FromMetaItem } ;
245+ use { FromMetaItem , Result } ;
233246
234247 /// parse a string as a syn::MetaItem instance.
235248 fn pmi ( s : & str ) -> :: std:: result:: Result < syn:: MetaItem , String > {
@@ -290,4 +303,12 @@ mod tests {
290303
291304 assert_eq ! ( fmi:: <HashMap <String , bool >>( r#"ignore(hello, world = false, there = "true")"# ) , comparison) ;
292305 }
306+
307+ /// Tests that fallible parsing will always produce an outer `Ok` (from `fmi`),
308+ /// and will accurately preserve the inner contents.
309+ #[ test]
310+ fn darling_result_succeeds ( ) {
311+ fmi :: < Result < ( ) > > ( "ignore" ) . unwrap ( ) ;
312+ fmi :: < Result < ( ) > > ( "ignore(world)" ) . unwrap_err ( ) ;
313+ }
293314}
0 commit comments