Handle derives on shared enums
diff --git a/macro/src/derive.rs b/macro/src/derive.rs
index 3010dc6..8988012 100644
--- a/macro/src/derive.rs
+++ b/macro/src/derive.rs
@@ -1,4 +1,4 @@
-use crate::syntax::{Struct, Trait};
+use crate::syntax::{Enum, Struct, Trait};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned, ToTokens};
@@ -16,6 +16,36 @@
expanded
}
+pub fn expand_enum(enm: &Enum) -> TokenStream {
+ let mut expanded = TokenStream::new();
+ let mut has_copy = false;
+ let mut has_clone = false;
+
+ for derive in &enm.derives {
+ let span = derive.span;
+ match derive.what {
+ Trait::Copy => {
+ expanded.extend(enum_copy(enm, span));
+ has_copy = true;
+ }
+ Trait::Clone => {
+ expanded.extend(enum_clone(enm, span));
+ has_clone = true;
+ }
+ }
+ }
+
+ let span = enm.name.rust.span();
+ if !has_copy {
+ expanded.extend(enum_copy(enm, span));
+ }
+ if !has_clone {
+ expanded.extend(enum_clone(enm, span));
+ }
+
+ expanded
+}
+
fn struct_copy(strct: &Struct, span: Span) -> TokenStream {
let ident = &strct.name.rust;
@@ -55,3 +85,23 @@
}
}
}
+
+fn enum_copy(enm: &Enum, span: Span) -> TokenStream {
+ let ident = &enm.name.rust;
+
+ quote_spanned! {span=>
+ impl ::std::marker::Copy for #ident {}
+ }
+}
+
+fn enum_clone(enm: &Enum, span: Span) -> TokenStream {
+ let ident = &enm.name.rust;
+
+ quote_spanned! {span=>
+ impl ::std::clone::Clone for #ident {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ }
+}
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 09373ff..2917820 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -169,6 +169,7 @@
// usable in patterns.
#[derive(::std::cmp::PartialEq, ::std::cmp::Eq)]
};
+ let derived_traits = derive::expand_enum(enm);
quote! {
#doc
@@ -188,13 +189,7 @@
type Kind = ::cxx::kind::Trivial;
}
- impl ::std::marker::Copy for #ident {}
-
- impl ::std::clone::Clone for #ident {
- fn clone(&self) -> Self {
- *self
- }
- }
+ #derived_traits
}
}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 17b290a..744963b 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -85,6 +85,7 @@
pub struct Enum {
pub doc: Doc,
+ pub derives: Vec<Derive>,
pub enum_token: Token![enum],
pub name: Pair,
pub brace_token: Brace,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index f1a330c..a009e19 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -126,6 +126,7 @@
}
let mut doc = Doc::new();
+ let mut derives = Vec::new();
let mut repr = None;
let mut namespace = namespace.clone();
attrs::parse(
@@ -133,6 +134,7 @@
&item.attrs,
attrs::Parser {
doc: Some(&mut doc),
+ derives: Some(&mut derives),
repr: Some(&mut repr),
namespace: Some(&mut namespace),
..Default::default()
@@ -188,6 +190,7 @@
Ok(Api::Enum(Enum {
doc,
+ derives,
enum_token,
name: Pair::new(namespace, item.ident),
brace_token,