Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The enum_name argument for enum_variant_name fn of ParseCallbacks trait includes the enum keyword along with the name #3113

Open
coderedart opened this issue Feb 5, 2025 · 3 comments

Comments

@coderedart
Copy link

coderedart commented Feb 5, 2025

If I run the following code with bindgen version 0.71.1 (latest as of this moment):

fn main() {
    let code = r"
        typedef enum MyEnum {
            MyEnumVariantA,
            MyEnumVariantB,
        } MyEnum;
    ";
    #[derive(Debug)]
    struct ParseCb;
    impl bindgen::callbacks::ParseCallbacks for ParseCb {
        fn enum_variant_name(
            &self,
            enum_name: Option<&str>,
            _original_variant_name: &str,
            _variant_value: bindgen::callbacks::EnumVariantValue,
        ) -> Option<String> {
            dbg!(enum_name);
            None
        }
    }
    bindgen::builder()
        .parse_callbacks(Box::new(ParseCb))
        .header_contents("temp.h", code)
        .generate()
        .unwrap();
}

I get this output:

[src/main.rs:17:13] enum_name = Some(
    "enum MyEnum",
)
[src/main.rs:17:13] enum_name = Some(
    "enum MyEnum",
)

We should only get the MyEnum part. If this is not a bug, then, it should at least be documented in the function docs.

Temporary workaround: just do enum_name.strip_prefix("enum ") (note the space after the enum keyword).

@ojeda
Copy link
Contributor

ojeda commented Feb 5, 2025

Yeah, it would be best to document it and add a test (I couldn't find one from a quick look).

However, to clarify, what should be the expected output given the following?

typedef enum E { A } T;

@coderedart
Copy link
Author

By default, E seems to be the obvious name to use, because T is just an alias. For example, if I used

        typedef enum MyEnum {
            MyEnumVariantA,
            MyEnumVariantB,
        } Foo;

I get this (using rust enum style):

#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum MyEnum { // E stays as name
    MyEnumVariantA = 0,
    MyEnumVariantB = 1,
}
pub use self::MyEnum as Foo; // T stays as alias

If there's no E, then T can be used as convenience?

In the context of enum_variant_name callback, having another argument called enum_alias is enough for people who want to customize the variant names based on alias.

@ojeda
Copy link
Contributor

ojeda commented Feb 5, 2025

I agree E should be the one picked -- I was trying to disambiguate/clarify the example in OP.

If there's no E, then T can be used as convenience?

That creates ambiguity, so I think that should be avoided and instead provided separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants