Repository: pacak/bpaf
Pull request #193 (2023-03-26 15:19:42)

top level doc comments on a parser are now group_help
Fixes https://github.com/pacak/bpaf/issues/150


Patch:
diff --git a/bpaf_derive/src/top.rs b/bpaf_derive/src/top.rs
index 9b7b442..454a5d9 100644
--- a/bpaf_derive/src/top.rs
+++ b/bpaf_derive/src/top.rs
@@ -32,7 +32,7 @@ pub struct Top {
 #[derive(Debug)]
 #[allow(clippy::large_enum_variant)]
 enum ParserKind {
-    BParser(BParser),
+    BParser(BParser, Option<String>),
     OParser(OParser),
 }
 
@@ -394,7 +394,7 @@ fn decorate_with_kind(outer: Outer, inner: BParser) -> ParserKind {
     };
 
     match outer.kind.unwrap_or(OuterKind::Construct) {
-        OuterKind::Construct => ParserKind::BParser(inner),
+        OuterKind::Construct => ParserKind::BParser(inner, outer.decor.descr),
         OuterKind::Options(maybe_cargo) => {
             let inner = match maybe_cargo {
                 Some(cargo) => BParser::CargoHelper(cargo, Box::new(inner)),
@@ -412,7 +412,7 @@ fn decorate_with_kind(outer: Outer, inner: BParser) -> ParserKind {
             };
 
             let cmd = BParser::Command(cmd_attr, Box::new(oparser), outer.adjacent);
-            ParserKind::BParser(cmd)
+            ParserKind::BParser(cmd, None)
         }
     }
 }
@@ -549,7 +549,7 @@ impl ToTokens for Top {
             kind,
         } = self;
         let outer_kind = match kind {
-            ParserKind::BParser(_) => quote!(impl ::bpaf::Parser<#outer_ty>),
+            ParserKind::BParser(_, _) => quote!(impl ::bpaf::Parser<#outer_ty>),
             ParserKind::OParser(_) => quote!(::bpaf::OptionParser<#outer_ty>),
         };
         quote!(
@@ -566,7 +566,14 @@ impl ToTokens for Top {
 impl ToTokens for ParserKind {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         match self {
-            ParserKind::BParser(bp) => bp.to_tokens(tokens),
+            ParserKind::BParser(bp, None) => bp.to_tokens(tokens),
+            ParserKind::BParser(bp, Some(msg)) => {
+                bp.to_tokens(tokens);
+                quote!(
+                    .group_help(#msg)
+                )
+                .to_tokens(tokens);
+            }
             ParserKind::OParser(op) => op.to_tokens(tokens),
         }
     }


Test patch:
diff --git a/bpaf_derive/src/top_tests.rs b/bpaf_derive/src/top_tests.rs
index 49d1f0d..b6bb011 100644
--- a/bpaf_derive/src/top_tests.rs
+++ b/bpaf_derive/src/top_tests.rs
@@ -200,7 +200,7 @@ fn empty_enum() {
 #[test]
 fn enum_command() {
     let input: Top = parse_quote! {
-        /// those are options
+        // those are options
         enum Opt {
             #[bpaf(command("foo"))]
             /// foo doc
@@ -814,3 +814,59 @@ fn single_unit_command() {
 
     assert_eq!(top.to_token_stream().to_string(), expected.to_string());
 }
+
+#[test]
+fn top_comment_is_group_help_enum() {
+    let top: Top = parse_quote! {
+        #[derive(Debug, Clone, Bpaf)]
+        /// present
+        enum Mode {
+            /// help
+            Intel,
+            /// help
+            Att,
+        }
+    };
+
+    let expected = quote! {
+        fn mode() -> impl ::bpaf::Parser<Mode> {
+            #[allow(unused_imports)]
+            use ::bpaf::Parser;
+            {
+                let alt0 = ::bpaf::long("intel").help("help").req_flag(Mode::Intel);
+                let alt1 = ::bpaf::long("att").help("help").req_flag(Mode::Att);
+                ::bpaf::construct!([alt0, alt1])
+            }
+            .group_help("present")
+        }
+    };
+    assert_eq!(top.to_token_stream().to_string(), expected.to_string());
+}
+
+#[test]
+fn top_comment_is_group_help_struct() {
+    let top: Top = parse_quote! {
+        #[derive(Debug, Clone, Bpaf)]
+        /// present
+        struct Mode {
+            /// help
+            intel: bool,
+            /// help
+            att: bool,
+        }
+    };
+
+    let expected = quote! {
+        fn mode() -> impl ::bpaf::Parser<Mode> {
+            #[allow(unused_imports)]
+            use ::bpaf::Parser;
+            {
+                let intel = ::bpaf::long("intel").help("help").switch();
+                let att = ::bpaf::long("att").help("help").switch();
+                ::bpaf::construct!(Mode { intel, att })
+            }
+            .group_help("present")
+        }
+    };
+    assert_eq!(top.to_token_stream().to_string(), expected.to_string());
+}
diff --git a/tests/help_format.rs b/tests/help_format.rs
index d40ee5e..612219a 100644
--- a/tests/help_format.rs
+++ b/tests/help_format.rs
@@ -161,9 +161,7 @@ Available options:
 #[test]
 fn enum_with_docs() {
     #[derive(Debug, Clone, Bpaf)]
-    /// present
-    ///
-    /// Absent
+    /// group help
     enum Mode {
         /// help
         ///
@@ -177,7 +175,6 @@ fn enum_with_docs() {
     }
 
     let r = mode()
-        .group_help("group help")
         .to_options()
         .run_inner(Args::from(&["--help"]))
         .unwrap_err()