Repository: pacak/bpaf (rust)

Issue:
support raw identifiers in the derive macro
```
#[derive(Bpaf)]
struct Opts {
  r#in: PathBuf
}
```

then it generates a flag like `--r#in` whereas I'd have expected `--in` , is this intended?

Pull request description:
support raw identifiers in derive macro
Fixes #282

Patch:
diff --git a/Changelog.md b/Changelog.md
index 6a5014e..7930197 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,7 @@
 
 ## bpaf [0.9.6], bpaf_derive [0.5.6] - Unreleased
 - make sure env-only arguments and flags are working
+- support raw identifiers in derive macro (#282)
 
 ## bpaf [0.9.5], bpaf_derive [0.5.5] - 2023-08-24
 - fancier squashing: parse `-abfoo` as `-a -b=foo` if b is a short argument
diff --git a/bpaf_derive/src/utils.rs b/bpaf_derive/src/utils.rs
index d20ed09..2b38432 100644
--- a/bpaf_derive/src/utils.rs
+++ b/bpaf_derive/src/utils.rs
@@ -84,7 +84,7 @@ pub(crate) fn to_kebab_case(input: &str) -> String {
 
 pub(crate) fn to_custom_case(input: &str, sep: char) -> String {
     let mut res = String::with_capacity(input.len() * 2);
-    for c in input.chars() {
+    for c in input.strip_prefix("r#").unwrap_or(input).chars() {
         if c.is_ascii_uppercase() {
             if !res.is_empty() {
                 res.push(sep);
@@ -104,6 +104,7 @@ fn check_to_snake_case() {
     assert_eq!(to_snake_case("Foo"), "foo");
     assert_eq!(to_snake_case("FooBar"), "foo_bar");
     assert_eq!(to_snake_case("FOO"), "f_o_o");
+    assert_eq!(to_snake_case("r#in"), "in");
 }
 
 /// Contains a slice of strings that used to represent doc comment lines


Test patch:
diff --git a/bpaf_derive/src/field_tests.rs b/bpaf_derive/src/field_tests.rs
index e81165f..1184532 100644
--- a/bpaf_derive/src/field_tests.rs
+++ b/bpaf_derive/src/field_tests.rs
@@ -897,3 +897,14 @@ fn positional_bool() {
     };
     assert_eq!(input.to_token_stream().to_string(), output.to_string());
 }
+
+#[test]
+fn raw_literal() {
+    let input: NamedField = parse_quote! {
+        r#in: bool
+    };
+    let output = quote! {
+        ::bpaf::long("in").switch()
+    };
+    assert_eq!(input.to_token_stream().to_string(), output.to_string());
+}