Add enum_class option

This option allows specifying that a C++ enum should be emitted with
plain `enum` rather than `enum class`. It's true that `enum class` should
generally be preferred, but sometimes there's existing code which is
already using plain `enum`, and porting that code to Rust becomes easier when
`cbindgen` can emit plain `enum`.

This option can be overridden on a per-enum basis using a `cbindgen:` annotation.

It defaults to true for two reasons:

* Backward compatibility.
* `enum class` is probably actually what you want, in general.
This commit is contained in:
Evan Shaw
2019-12-29 18:39:12 +13:00
committed by Emilio Cobos Álvarez
parent 16fe3ec142
commit 6a9066f7cd
12 changed files with 272 additions and 12 deletions
+5
View File
@@ -269,6 +269,7 @@ The rest are just local overrides for the same options found in the cbindgen.tom
* derive-mut-casts
* derive-tagged-enum-destructor
* derive-tagged-enum-copy-constructor
* enum-class
* prefix-with-name
* private-default-tagged-enum-constructor
@@ -672,6 +673,10 @@ add_sentinel = false
# default: false
prefix_with_name = false
# Whether to emit enums using "enum class" when targeting C++.
# default: true
enum_class = true
# Whether to generate static `::MyVariant(..)` constructors and `bool IsMyVariant()`
# methods for enums with fields.
#
+30 -1
View File
@@ -391,7 +391,7 @@ impl StructConfig {
}
/// Settings to apply to generated enums.
#[derive(Debug, Clone, Default, Deserialize)]
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
@@ -425,11 +425,34 @@ pub struct EnumConfig {
/// This is only generated if a copy constructor for the same tagged enum is
/// generated as well.
pub derive_tagged_enum_copy_assignment: bool,
/// Declare the enum as an enum class.
/// Only relevant when targeting C++.
pub enum_class: bool,
/// Whether to generate empty, private default-constructors for tagged
/// enums.
pub private_default_tagged_enum_constructor: bool,
}
impl Default for EnumConfig {
fn default() -> EnumConfig {
EnumConfig {
rename_variants: None,
add_sentinel: false,
prefix_with_name: false,
derive_helper_methods: false,
derive_const_casts: false,
derive_mut_casts: false,
cast_assert_name: None,
must_use: None,
derive_tagged_enum_destructor: false,
derive_tagged_enum_copy_constructor: false,
derive_tagged_enum_copy_assignment: false,
enum_class: true,
private_default_tagged_enum_constructor: false,
}
}
}
impl EnumConfig {
pub(crate) fn add_sentinel(&self, annotations: &AnnotationSet) -> bool {
if let Some(x) = annotations.bool("add-sentinel") {
@@ -473,6 +496,12 @@ impl EnumConfig {
}
self.derive_tagged_enum_copy_assignment
}
pub(crate) fn enum_class(&self, annotations: &AnnotationSet) -> bool {
if let Some(x) = annotations.bool("enum-class") {
return x;
}
self.enum_class
}
pub(crate) fn private_default_tagged_enum_constructor(
&self,
annotations: &AnnotationSet,
+5 -1
View File
@@ -559,7 +559,11 @@ impl Source for Enum {
}
}
} else {
out.write("enum class");
if config.enumeration.enum_class(&self.annotations) {
out.write("enum class");
} else {
out.write("enum");
}
if self.annotations.must_use {
if let Some(ref anno) = config.enumeration.must_use {
+1
View File
@@ -103,6 +103,7 @@ derive_mut_casts = false
# cast_assert_name = "ASSERT"
derive_tagged_enum_destructor = false
derive_tagged_enum_copy_constructor = false
enum_class = true
private_default_tagged_enum_constructor = false
+31 -1
View File
@@ -65,6 +65,21 @@ enum M {
};
typedef int8_t M;
typedef enum N {
n1,
n2,
n3,
n4,
} N;
enum O {
o1,
o2,
o3,
o4,
};
typedef int8_t O;
typedef struct J J;
typedef struct K K;
@@ -142,4 +157,19 @@ typedef struct I {
};
} I;
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m);
void root(Opaque *opaque,
A a,
B b,
C c,
D d,
E e,
F f,
G g,
H h,
I i,
J j,
K k,
L l,
M m,
N n,
O o);
+37 -1
View File
@@ -107,6 +107,27 @@ enum M
typedef int8_t M;
#endif // __cplusplus
typedef enum N {
n1,
n2,
n3,
n4,
} N;
enum O
#ifdef __cplusplus
: int8_t
#endif // __cplusplus
{
o1,
o2,
o3,
o4,
};
#ifndef __cplusplus
typedef int8_t O;
#endif // __cplusplus
typedef struct J J;
typedef struct K K;
@@ -200,7 +221,22 @@ typedef struct I {
extern "C" {
#endif // __cplusplus
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m);
void root(Opaque *opaque,
A a,
B b,
C c,
D d,
E e,
F f,
G g,
H h,
I i,
J j,
K k,
L l,
M m,
N n,
O o);
#ifdef __cplusplus
} // extern "C"
+31 -1
View File
@@ -65,6 +65,21 @@ enum M {
};
typedef int8_t M;
typedef enum {
n1,
n2,
n3,
n4,
} N;
enum O {
o1,
o2,
o3,
o4,
};
typedef int8_t O;
typedef struct J J;
typedef struct K K;
@@ -142,4 +157,19 @@ typedef struct {
};
} I;
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m);
void root(Opaque *opaque,
A a,
B b,
C c,
D d,
E e,
F f,
G g,
H h,
I i,
J j,
K k,
L l,
M m,
N n,
O o);
+37 -1
View File
@@ -107,6 +107,27 @@ enum M
typedef int8_t M;
#endif // __cplusplus
typedef enum {
n1,
n2,
n3,
n4,
} N;
enum O
#ifdef __cplusplus
: int8_t
#endif // __cplusplus
{
o1,
o2,
o3,
o4,
};
#ifndef __cplusplus
typedef int8_t O;
#endif // __cplusplus
typedef struct J J;
typedef struct K K;
@@ -200,7 +221,22 @@ typedef struct {
extern "C" {
#endif // __cplusplus
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m);
void root(Opaque *opaque,
A a,
B b,
C c,
D d,
E e,
F f,
G g,
H h,
I i,
J j,
K k,
L l,
M m,
N n,
O o);
#ifdef __cplusplus
} // extern "C"
+30 -1
View File
@@ -58,6 +58,20 @@ enum class M : int8_t {
m3 = 1,
};
enum N {
n1,
n2,
n3,
n4,
};
enum O : int8_t {
o1,
o2,
o3,
o4,
};
struct J;
struct K;
@@ -137,6 +151,21 @@ struct I {
extern "C" {
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m);
void root(Opaque *opaque,
A a,
B b,
C c,
D d,
E e,
F f,
G g,
H h,
I i,
J j,
K k,
L l,
M m,
N n,
O o);
} // extern "C"
+19 -2
View File
@@ -65,6 +65,21 @@ enum M {
};
typedef int8_t M;
enum N {
n1,
n2,
n3,
n4,
};
enum O {
o1,
o2,
o3,
o4,
};
typedef int8_t O;
struct J;
struct K;
@@ -142,7 +157,7 @@ struct I {
};
};
void root(struct Opaque *o,
void root(struct Opaque *opaque,
A a,
B b,
C c,
@@ -155,4 +170,6 @@ void root(struct Opaque *o,
struct J j,
struct K k,
enum L l,
M m);
M m,
enum N n,
O o);
+25 -2
View File
@@ -107,6 +107,27 @@ enum M
typedef int8_t M;
#endif // __cplusplus
enum N {
n1,
n2,
n3,
n4,
};
enum O
#ifdef __cplusplus
: int8_t
#endif // __cplusplus
{
o1,
o2,
o3,
o4,
};
#ifndef __cplusplus
typedef int8_t O;
#endif // __cplusplus
struct J;
struct K;
@@ -200,7 +221,7 @@ struct I {
extern "C" {
#endif // __cplusplus
void root(struct Opaque *o,
void root(struct Opaque *opaque,
A a,
B b,
C c,
@@ -213,7 +234,9 @@ void root(struct Opaque *o,
struct J j,
struct K k,
enum L l,
M m);
M m,
enum N n,
O o);
#ifdef __cplusplus
} // extern "C"
+21 -1
View File
@@ -103,9 +103,27 @@ enum M {
m3 = 1,
}
/// cbindgen:enum-class=false
#[repr(C)]
enum N {
n1,
n2,
n3,
n4,
}
/// cbindgen:enum-class=false
#[repr(i8)]
enum O {
o1,
o2,
o3,
o4,
}
#[no_mangle]
pub extern "C" fn root(
o: *mut Opaque,
opaque: *mut Opaque,
a: A,
b: B,
c: C,
@@ -119,5 +137,7 @@ pub extern "C" fn root(
k: K,
l: L,
m: M,
n: N,
o: O,
) {
}