Skip to content

ir: Allow replacing enums and enum variants. #1268

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

Merged
merged 3 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,23 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe {
}

/// This function should return whether, given the a given enum variant
/// name, and value, returns whether this enum variant will forcibly be a
/// constant.
/// name, and value, this enum variant will forcibly be a constant.
fn enum_variant_behavior(
&self,
_enum_name: Option<&str>,
_variant_name: &str,
_original_variant_name: &str,
_variant_value: EnumVariantValue,
) -> Option<EnumVariantCustomBehavior> {
None
}

/// Allows to rename an enum variant, replacing `_original_variant_name`.
fn enum_variant_name(
&self,
_enum_name: Option<&str>,
_original_variant_name: &str,
_variant_value: EnumVariantValue,
) -> Option<String> {
None
}
}
6 changes: 3 additions & 3 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2228,7 +2228,7 @@ impl<'a> EnumBuilder<'a> {
self,
ctx: &BindgenContext,
variant: &EnumVariant,
mangling_prefix: Option<&String>,
mangling_prefix: Option<&str>,
rust_ty: quote::Tokens,
result: &mut CodegenResult<'b>,
) -> Self {
Expand Down Expand Up @@ -2548,9 +2548,9 @@ impl CodeGenerator for Enum {

let constant_mangling_prefix = if ctx.options().prepend_enum_name {
if enum_ty.name().is_none() {
parent_canonical_name.as_ref().map(|n| &*n)
parent_canonical_name.as_ref().map(|n| &**n)
} else {
Some(&name)
Some(&*name)
}
} else {
None
Expand Down
3 changes: 2 additions & 1 deletion src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,7 @@ impl BindgenContext {
match *ty.kind() {
TypeKind::Comp(..) |
TypeKind::TemplateAlias(..) |
TypeKind::Enum(..) |
TypeKind::Alias(..) => {}
_ => continue,
}
Expand Down Expand Up @@ -2065,7 +2066,7 @@ impl BindgenContext {

/// Has the item with the given `name` and `id` been replaced by another
/// type?
pub fn is_replaced_type<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
fn is_replaced_type<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
let id = id.into();
match self.replacements.get(path) {
Some(replaced_by) if *replaced_by != id => true,
Expand Down
33 changes: 21 additions & 12 deletions src/ir/enum_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,31 @@ impl Enum {
};
if let Some(val) = value {
let name = cursor.spelling();
let annotations = Annotations::new(&cursor);
let custom_behavior = ctx.parse_callbacks()
.and_then(
|t| t.enum_variant_behavior(type_name, &name, val),
)
.and_then(|callbacks| {
callbacks.enum_variant_behavior(type_name, &name, val)
})
.or_else(|| {
Annotations::new(&cursor).and_then(
|anno| if anno.hide() {
Some(EnumVariantCustomBehavior::Hide)
} else if anno.constify_enum_variant() {
Some(EnumVariantCustomBehavior::Constify)
} else {
None
},
)
let annotations = annotations.as_ref()?;
if annotations.hide() {
Some(EnumVariantCustomBehavior::Hide)
} else if annotations.constify_enum_variant() {
Some(EnumVariantCustomBehavior::Constify)
} else {
None
}
});

let name = ctx.parse_callbacks()
.and_then(|callbacks| {
callbacks.enum_variant_name(type_name, &name, val)
})
.or_else(|| {
annotations.as_ref()?.use_instead_of()?.last().cloned()
})
.unwrap_or(name);

let comment = cursor.raw_comment();
variants.push(EnumVariant::new(
name,
Expand Down
14 changes: 14 additions & 0 deletions tests/expectations/tests/enum-variant-replaces.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* automatically generated by rust-bindgen */

#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]

/// <div rustbindgen replaces="PASS"></div>
///
/// Should see PASS below.
pub const OGRErr_PASS: OGRErr = 0;
/// <div rustbindgen replaces="OGRERR_NONE"></div>
///
/// Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below.
pub const OGRErr_OGRERR_NONE: OGRErr = 1;
/// <div rustbindgen replaces="OGRErr"></div>
pub type OGRErr = u32;
34 changes: 34 additions & 0 deletions tests/headers/enum-variant-replaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

/** Type for a OGR error */
typedef enum
{
OGRERR_NONE, /**< Success */
OGRERR_NOT_ENOUGH_DATA, /**< Not enough data to deserialize */
OGRERR_NOT_ENOUGH_MEMORY, /**< Not enough memory */
OGRERR_UNSUPPORTED_GEOMETRY_TYPE, /**< Unsupported geometry type */
OGRERR_UNSUPPORTED_OPERATION, /**< Unsupported operation */
OGRERR_CORRUPT_DATA, /**< Corrupt data */
OGRERR_FAILURE, /**< Failure */
OGRERR_UNSUPPORTED_SRS, /**< Unsupported SRS */
OGRERR_INVALID_HANDLE, /**< Invalid handle */
OGRERR_NON_EXISTING_FEATURE /**< Non existing feature. Added in GDAL 2.0 */
} OGRErr;

/**
* <div rustbindgen replaces="OGRErr"></div>
*/
typedef enum
{
/**
* <div rustbindgen replaces="PASS"></div>
*
* Should see PASS below.
*/
FAIL,
/**
* <div rustbindgen replaces="OGRERR_NONE"></div>
*
* Should see OGRERR_NONE instead of CUSTOM_OGRERR_NONE below.
*/
CUSTOM_OGRERR_NONE
} StrictOGRErr;