Skip to content

Commit 196ed41

Browse files
author
Oliver Scherer
committed
Deduplicate recurring logic
1 parent 816f0bd commit 196ed41

File tree

1 file changed

+19
-44
lines changed

1 file changed

+19
-44
lines changed

src/lib.rs

+19-44
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,11 @@ fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
165165
pub fn from_primitive(input: TokenStream) -> TokenStream {
166166
let ast: syn::DeriveInput = syn::parse(input).unwrap();
167167
let name = &ast.ident;
168-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
168+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
169169

170170
let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
171-
let bound = quote! { #inner_ty: _num_traits::FromPrimitive };
172-
let where_ = match where_ {
173-
Some(where_) => quote!{ #where_, #bound },
174-
None => quote!{ where #bound },
175-
};
176171
quote! {
177-
impl #impl_ _num_traits::FromPrimitive for #name #type_ #where_ {
172+
impl #impl_ _num_traits::FromPrimitive for #name #type_ #where_ #inner_ty: _num_traits::FromPrimitive {
178173
fn from_i64(n: i64) -> Option<Self> {
179174
<#inner_ty as _num_traits::FromPrimitive>::from_i64(n).map(#name)
180175
}
@@ -327,16 +322,11 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
327322
pub fn to_primitive(input: TokenStream) -> TokenStream {
328323
let ast: syn::DeriveInput = syn::parse(input).unwrap();
329324
let name = &ast.ident;
330-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
325+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
331326

332327
let impl_ = if let Some(inner_ty) = newtype_inner(&ast.data) {
333-
let bound = quote! { #inner_ty: _num_traits::ToPrimitive };
334-
let where_ = match where_ {
335-
Some(where_) => quote!{ #where_, #bound },
336-
None => quote!{ where #bound },
337-
};
338328
quote! {
339-
impl #impl_ _num_traits::ToPrimitive for #name #type_ #where_ {
329+
impl #impl_ _num_traits::ToPrimitive for #name #type_ #where_ #inner_ty: _num_traits::ToPrimitive {
340330
fn to_i64(&self) -> Option<i64> {
341331
<#inner_ty as _num_traits::ToPrimitive>::to_i64(&self.0)
342332
}
@@ -452,12 +442,8 @@ const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
452442
pub fn num_ops(input: TokenStream) -> TokenStream {
453443
let ast: syn::DeriveInput = syn::parse(input).unwrap();
454444
let name = &ast.ident;
455-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
445+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
456446
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
457-
let where_ = match where_ {
458-
Some(where_) => quote!{ #where_, },
459-
None => quote!{ where },
460-
};
461447
dummy_const_trick(
462448
"NumOps",
463449
&name,
@@ -505,12 +491,8 @@ pub fn num_ops(input: TokenStream) -> TokenStream {
505491
pub fn num_cast(input: TokenStream) -> TokenStream {
506492
let ast: syn::DeriveInput = syn::parse(input).unwrap();
507493
let name = &ast.ident;
508-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
494+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
509495
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
510-
let where_ = match where_ {
511-
Some(where_) => quote!{ #where_, },
512-
None => quote!{ where },
513-
};
514496
let fn_param = proc_macro2::Ident::new("FROM_T", name.span());
515497
dummy_const_trick(
516498
"NumCast",
@@ -534,12 +516,8 @@ pub fn num_cast(input: TokenStream) -> TokenStream {
534516
pub fn zero(input: TokenStream) -> TokenStream {
535517
let ast: syn::DeriveInput = syn::parse(input).unwrap();
536518
let name = &ast.ident;
537-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
519+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
538520
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
539-
let where_ = match where_ {
540-
Some(where_) => quote!{ #where_, },
541-
None => quote!{ where },
542-
};
543521
dummy_const_trick(
544522
"Zero",
545523
&name,
@@ -564,12 +542,8 @@ pub fn zero(input: TokenStream) -> TokenStream {
564542
pub fn one(input: TokenStream) -> TokenStream {
565543
let ast: syn::DeriveInput = syn::parse(input).unwrap();
566544
let name = &ast.ident;
567-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
545+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
568546
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
569-
let where_ = match where_ {
570-
Some(where_) => quote!{ #where_, },
571-
None => quote!{ where },
572-
};
573547
dummy_const_trick(
574548
"One",
575549
&name,
@@ -587,19 +561,24 @@ pub fn one(input: TokenStream) -> TokenStream {
587561
.into()
588562
}
589563

564+
fn split_for_impl(generics: &syn::Generics) -> (syn::ImplGenerics, syn::TypeGenerics, impl quote::ToTokens) {
565+
let (impl_, type_, where_) = generics.split_for_impl();
566+
let where_ = match where_ {
567+
Some(where_) => quote!{ #where_, },
568+
None => quote!{ where },
569+
};
570+
(impl_, type_, where_)
571+
}
572+
590573
/// Derives [`num_traits::Num`][num] for newtypes. The inner type must already implement `Num`.
591574
///
592575
/// [num]: https://docs.rs/num-traits/0.2/num_traits/trait.Num.html
593576
#[proc_macro_derive(Num)]
594577
pub fn num(input: TokenStream) -> TokenStream {
595578
let ast: syn::DeriveInput = syn::parse(input).unwrap();
596579
let name = &ast.ident;
597-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
580+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
598581
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
599-
let where_ = match where_ {
600-
Some(where_) => quote!{ #where_, },
601-
None => quote!{ where },
602-
};
603582
dummy_const_trick(
604583
"Num",
605584
&name,
@@ -623,12 +602,8 @@ pub fn num(input: TokenStream) -> TokenStream {
623602
pub fn float(input: TokenStream) -> TokenStream {
624603
let ast: syn::DeriveInput = syn::parse(input).unwrap();
625604
let name = &ast.ident;
626-
let (impl_, type_, where_) = &ast.generics.split_for_impl();
605+
let (impl_, type_, where_) = split_for_impl(&ast.generics);
627606
let inner_ty = newtype_inner(&ast.data).expect(NEWTYPE_ONLY);
628-
let where_ = match where_ {
629-
Some(where_) => quote!{ #where_, },
630-
None => quote!{ where },
631-
};
632607
dummy_const_trick(
633608
"Float",
634609
&name,

0 commit comments

Comments
 (0)