enumeration: Only propagate derive_ostream annotation if not present.

It seems reasonable to want to derive it for a variant, but want to
provide your own for the containing enum or such, for example.
This commit is contained in:
Emilio Cobos Álvarez
2020-10-01 12:29:14 +02:00
parent 36a3f8ba6e
commit d1d97d4482
10 changed files with 177 additions and 16 deletions
+6 -2
View File
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::collections::hash_map::Entry;
use std::collections::HashMap; use std::collections::HashMap;
use std::str::FromStr; use std::str::FromStr;
@@ -115,8 +116,11 @@ impl AnnotationSet {
}) })
} }
pub fn add(&mut self, name: &str, value: AnnotationValue) { /// Adds an annotation value if none is specified.
self.annotations.insert(name.to_string(), value); pub fn add_default(&mut self, name: &str, value: AnnotationValue) {
if let Entry::Vacant(e) = self.annotations.entry(name.to_string()) {
e.insert(value);
}
} }
pub fn list(&self, name: &str) -> Option<Vec<String>> { pub fn list(&self, name: &str) -> Option<Vec<String>> {
+1 -1
View File
@@ -145,7 +145,7 @@ impl EnumVariant {
let variant_cfg = Cfg::append(mod_cfg, Cfg::load(&variant.attrs)); let variant_cfg = Cfg::append(mod_cfg, Cfg::load(&variant.attrs));
let mut annotations = AnnotationSet::load(&variant.attrs)?; let mut annotations = AnnotationSet::load(&variant.attrs)?;
if let Some(b) = enum_annotations.bool("derive-ostream") { if let Some(b) = enum_annotations.bool("derive-ostream") {
annotations.add("derive-ostream", AnnotationValue::Bool(b)); annotations.add_default("derive-ostream", AnnotationValue::Bool(b));
} }
let body = match variant.fields { let body = match variant.fields {
syn::Fields::Unit => VariantBody::Empty(annotations), syn::Fields::Unit => VariantBody::Empty(annotations),
+19 -1
View File
@@ -72,4 +72,22 @@ typedef struct H {
}; };
} H; } H;
void root(A a, B b, C c, D d, F f, H h); enum I_Tag {
ThereAgain,
SomethingElse,
};
typedef uint8_t I_Tag;
typedef struct ThereAgain_Body {
uint8_t x;
int16_t y;
} ThereAgain_Body;
typedef struct I {
I_Tag tag;
union {
ThereAgain_Body there_again;
};
} I;
void root(A a, B b, C c, D d, F f, H h, I i);
@@ -90,11 +90,35 @@ typedef struct H {
}; };
} H; } H;
enum I_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
ThereAgain,
SomethingElse,
};
#ifndef __cplusplus
typedef uint8_t I_Tag;
#endif // __cplusplus
typedef struct ThereAgain_Body {
uint8_t x;
int16_t y;
} ThereAgain_Body;
typedef struct I {
I_Tag tag;
union {
ThereAgain_Body there_again;
};
} I;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
void root(A a, B b, C c, D d, F f, H h); void root(A a, B b, C c, D d, F f, H h, I i);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
+19 -1
View File
@@ -72,4 +72,22 @@ typedef struct {
}; };
} H; } H;
void root(A a, B b, C c, D d, F f, H h); enum I_Tag {
ThereAgain,
SomethingElse,
};
typedef uint8_t I_Tag;
typedef struct {
uint8_t x;
int16_t y;
} ThereAgain_Body;
typedef struct {
I_Tag tag;
union {
ThereAgain_Body there_again;
};
} I;
void root(A a, B b, C c, D d, F f, H h, I i);
+25 -1
View File
@@ -90,11 +90,35 @@ typedef struct {
}; };
} H; } H;
enum I_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
ThereAgain,
SomethingElse,
};
#ifndef __cplusplus
typedef uint8_t I_Tag;
#endif // __cplusplus
typedef struct {
uint8_t x;
int16_t y;
} ThereAgain_Body;
typedef struct {
I_Tag tag;
union {
ThereAgain_Body there_again;
};
} I;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
void root(A a, B b, C c, D d, F f, H h); void root(A a, B b, C c, D d, F f, H h, I i);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
+23 -1
View File
@@ -155,8 +155,30 @@ struct H {
}; };
}; };
struct I {
enum class Tag : uint8_t {
ThereAgain,
SomethingElse,
};
struct ThereAgain_Body {
uint8_t x;
int16_t y;
friend std::ostream& operator<<(std::ostream& stream, const ThereAgain_Body& instance) {
return stream << "{ " << "x=" << instance.x << ", "
<< "y=" << instance.y << " }";
}
};
Tag tag;
union {
ThereAgain_Body there_again;
};
};
extern "C" { extern "C" {
void root(A a, B b, C c, D d, F f, H h); void root(A a, B b, C c, D d, F f, H h, I i);
} // extern "C" } // extern "C"
+19 -1
View File
@@ -72,4 +72,22 @@ struct H {
}; };
}; };
void root(struct A a, struct B b, C c, struct D d, union F f, struct H h); enum I_Tag {
ThereAgain,
SomethingElse,
};
typedef uint8_t I_Tag;
struct ThereAgain_Body {
uint8_t x;
int16_t y;
};
struct I {
I_Tag tag;
union {
struct ThereAgain_Body there_again;
};
};
void root(struct A a, struct B b, C c, struct D d, union F f, struct H h, struct I i);
+25 -1
View File
@@ -90,11 +90,35 @@ struct H {
}; };
}; };
enum I_Tag
#ifdef __cplusplus
: uint8_t
#endif // __cplusplus
{
ThereAgain,
SomethingElse,
};
#ifndef __cplusplus
typedef uint8_t I_Tag;
#endif // __cplusplus
struct ThereAgain_Body {
uint8_t x;
int16_t y;
};
struct I {
I_Tag tag;
union {
struct ThereAgain_Body there_again;
};
};
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
void root(struct A a, struct B b, C c, struct D d, union F f, struct H h); void root(struct A a, struct B b, C c, struct D d, union F f, struct H h, struct I i);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
+15 -6
View File
@@ -1,22 +1,22 @@
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(C)] #[repr(C)]
struct A(i32); pub struct A(i32);
/// cbindgen:field-names=[x, y] /// cbindgen:field-names=[x, y]
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(C)] #[repr(C)]
struct B(i32, f32); pub struct B(i32, f32);
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(u32)] #[repr(u32)]
enum C { pub enum C {
X = 2, X = 2,
Y, Y,
} }
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(C)] #[repr(C)]
struct D { pub struct D {
List: u8, List: u8,
Of: usize, Of: usize,
Things: B, Things: B,
@@ -24,7 +24,7 @@ struct D {
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(u8)] #[repr(u8)]
enum F { pub enum F {
Foo(i16), Foo(i16),
Bar { x: u8, y: i16 }, Bar { x: u8, y: i16 },
Baz Baz
@@ -32,12 +32,20 @@ enum F {
/// cbindgen:derive-ostream /// cbindgen:derive-ostream
#[repr(C, u8)] #[repr(C, u8)]
enum H { pub enum H {
Hello(i16), Hello(i16),
There { x: u8, y: i16 }, There { x: u8, y: i16 },
Everyone Everyone
} }
/// cbindgen:derive-ostream=false
#[repr(C, u8)]
pub enum I {
/// cbindgen:derive-ostream=true
ThereAgain { x: u8, y: i16 },
SomethingElse
}
#[no_mangle] #[no_mangle]
pub extern "C" fn root( pub extern "C" fn root(
a: A, a: A,
@@ -46,5 +54,6 @@ pub extern "C" fn root(
d: D, d: D,
f: F, f: F,
h: H, h: H,
i: I,
) { } ) { }