Skip to content

Commit 6babb73

Browse files
committed
Add CloneGettes
1 parent 76bf93c commit 6babb73

File tree

3 files changed

+294
-15
lines changed

3 files changed

+294
-15
lines changed

src/generate.rs

+37-15
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use syn::{
44
self, ext::IdentExt, spanned::Spanned, Expr, Field, Lit, Meta, MetaNameValue, Visibility,
55
};
66

7-
use self::GenMode::{Get, GetCopy, GetMut, Set, SetWith};
7+
use self::GenMode::{Get, GetClone, GetCopy, GetMut, Set, SetWith};
88
use super::parse_attr;
99

1010
pub struct GenParams {
@@ -15,6 +15,7 @@ pub struct GenParams {
1515
#[derive(PartialEq, Eq, Copy, Clone)]
1616
pub enum GenMode {
1717
Get,
18+
GetClone,
1819
GetCopy,
1920
GetMut,
2021
Set,
@@ -25,6 +26,7 @@ impl GenMode {
2526
pub fn name(self) -> &'static str {
2627
match self {
2728
Get => "get",
29+
GetClone => "get_clone",
2830
GetCopy => "get_copy",
2931
GetMut => "get_mut",
3032
Set => "set",
@@ -34,23 +36,23 @@ impl GenMode {
3436

3537
pub fn prefix(self) -> &'static str {
3638
match self {
37-
Get | GetCopy | GetMut => "",
39+
Get | GetClone | GetCopy | GetMut => "",
3840
Set => "set_",
3941
SetWith => "with_",
4042
}
4143
}
4244

4345
pub fn suffix(self) -> &'static str {
4446
match self {
45-
Get | GetCopy | Set | SetWith => "",
47+
Get | GetClone | GetCopy | Set | SetWith => "",
4648
GetMut => "_mut",
4749
}
4850
}
4951

5052
fn is_get(self) -> bool {
5153
match self {
52-
GenMode::Get | GenMode::GetCopy | GenMode::GetMut => true,
53-
GenMode::Set | GenMode::SetWith => false,
54+
Get | GetClone | GetCopy | GetMut => true,
55+
Set | SetWith => false,
5456
}
5557
}
5658
}
@@ -112,6 +114,7 @@ fn has_prefix_attr(f: &Field, params: &GenParams) -> bool {
112114
.filter_map(|attr| parse_attr(attr, params.mode))
113115
.find(|meta| {
114116
meta.path().is_ident("get")
117+
|| meta.path().is_ident("get_clone")
115118
|| meta.path().is_ident("get_copy")
116119
|| meta.path().is_ident("get_mut")
117120
})
@@ -167,7 +170,7 @@ pub fn implement(field: &Field, params: &GenParams) -> TokenStream2 {
167170
// Generate nothing for skipped field
168171
Some(meta) if meta.path().is_ident("skip") => quote! {},
169172
Some(_) => match params.mode {
170-
GenMode::Get => {
173+
Get => {
171174
quote! {
172175
#(#doc)*
173176
#[inline(always)]
@@ -176,7 +179,16 @@ pub fn implement(field: &Field, params: &GenParams) -> TokenStream2 {
176179
}
177180
}
178181
}
179-
GenMode::GetCopy => {
182+
GetClone => {
183+
quote! {
184+
#(#doc)*
185+
#[inline(always)]
186+
#visibility fn #fn_name(&self) -> #ty {
187+
self.#field_name.clone()
188+
}
189+
}
190+
}
191+
GetCopy => {
180192
quote! {
181193
#(#doc)*
182194
#[inline(always)]
@@ -185,7 +197,7 @@ pub fn implement(field: &Field, params: &GenParams) -> TokenStream2 {
185197
}
186198
}
187199
}
188-
GenMode::Set => {
200+
Set => {
189201
quote! {
190202
#(#doc)*
191203
#[inline(always)]
@@ -195,7 +207,7 @@ pub fn implement(field: &Field, params: &GenParams) -> TokenStream2 {
195207
}
196208
}
197209
}
198-
GenMode::GetMut => {
210+
GetMut => {
199211
quote! {
200212
#(#doc)*
201213
#[inline(always)]
@@ -204,7 +216,7 @@ pub fn implement(field: &Field, params: &GenParams) -> TokenStream2 {
204216
}
205217
}
206218
}
207-
GenMode::SetWith => {
219+
SetWith => {
208220
quote! {
209221
#(#doc)*
210222
#[inline(always)]
@@ -234,7 +246,7 @@ pub fn implement_for_unnamed(field: &Field, params: &GenParams) -> TokenStream2
234246
// Generate nothing for skipped field
235247
Some(meta) if meta.path().is_ident("skip") => quote! {},
236248
Some(_) => match params.mode {
237-
GenMode::Get => {
249+
Get => {
238250
let fn_name = Ident::new("get", Span::call_site());
239251
quote! {
240252
#(#doc)*
@@ -244,7 +256,17 @@ pub fn implement_for_unnamed(field: &Field, params: &GenParams) -> TokenStream2
244256
}
245257
}
246258
}
247-
GenMode::GetCopy => {
259+
GetClone => {
260+
let fn_name = Ident::new("get", Span::call_site());
261+
quote! {
262+
#(#doc)*
263+
#[inline(always)]
264+
#visibility fn #fn_name(&self) -> #ty {
265+
self.0.clone()
266+
}
267+
}
268+
}
269+
GetCopy => {
248270
let fn_name = Ident::new("get", Span::call_site());
249271
quote! {
250272
#(#doc)*
@@ -254,7 +276,7 @@ pub fn implement_for_unnamed(field: &Field, params: &GenParams) -> TokenStream2
254276
}
255277
}
256278
}
257-
GenMode::Set => {
279+
Set => {
258280
let fn_name = Ident::new("set", Span::call_site());
259281
quote! {
260282
#(#doc)*
@@ -265,7 +287,7 @@ pub fn implement_for_unnamed(field: &Field, params: &GenParams) -> TokenStream2
265287
}
266288
}
267289
}
268-
GenMode::GetMut => {
290+
GetMut => {
269291
let fn_name = Ident::new("get_mut", Span::call_site());
270292
quote! {
271293
#(#doc)*
@@ -275,7 +297,7 @@ pub fn implement_for_unnamed(field: &Field, params: &GenParams) -> TokenStream2
275297
}
276298
}
277299
}
278-
GenMode::SetWith => {
300+
SetWith => {
279301
let fn_name = Ident::new("set_with", Span::call_site());
280302
quote! {
281303
#(#doc)*

src/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ pub fn getters(input: TokenStream) -> TokenStream {
226226
produce(&ast, &params).into()
227227
}
228228

229+
#[proc_macro_derive(CloneGetters, attributes(get_clone, with_prefix, getset))]
230+
#[proc_macro_error]
231+
pub fn clone_getters(input: TokenStream) -> TokenStream {
232+
let ast = parse_macro_input!(input as DeriveInput);
233+
let params = GenParams {
234+
mode: GenMode::GetClone,
235+
global_attr: parse_global_attr(&ast.attrs, GenMode::GetClone),
236+
};
237+
238+
produce(&ast, &params).into()
239+
}
240+
229241
#[proc_macro_derive(CopyGetters, attributes(get_copy, with_prefix, getset))]
230242
#[proc_macro_error]
231243
pub fn copy_getters(input: TokenStream) -> TokenStream {
@@ -292,6 +304,7 @@ fn parse_attr(attr: &syn::Attribute, mode: GenMode) -> Option<syn::Meta> {
292304
.into_iter()
293305
.inspect(|meta| {
294306
if !(meta.path().is_ident("get")
307+
|| meta.path().is_ident("get_clone")
295308
|| meta.path().is_ident("get_copy")
296309
|| meta.path().is_ident("get_mut")
297310
|| meta.path().is_ident("set")

0 commit comments

Comments
 (0)