Skip to content

Commit

Permalink
Merge pull request #55 from CreepySkeleton/tmp
Browse files Browse the repository at this point in the history
Remerge #48 and #49
  • Loading branch information
Hoverbear authored Jan 21, 2020
2 parents 8ca0d17 + a04a903 commit 895f47b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ proc-macro = true
quote = "1"
syn = "1"
proc-macro2 = { version = "1", default-features = false }
proc-macro-error = "0.4"
28 changes: 12 additions & 16 deletions src/generate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use proc_macro2::TokenStream as TokenStream2;
use proc_macro2::{Ident, Span};
use syn::{self, Field, Lit, Meta, MetaNameValue, Visibility};
use proc_macro_error::abort;
use syn::{self, spanned::Spanned, Field, Lit, Meta, MetaNameValue, Visibility};

pub struct GenParams {
pub attribute_name: &'static str,
Expand Down Expand Up @@ -35,10 +36,10 @@ pub fn parse_visibility(attr: Option<&Meta>, meta_name: &str) -> Option<Visibili
..
})) => {
if path.is_ident(meta_name) {
s.value()
.split(' ')
.find(|v| *v != "with_prefix")
.map(|v| syn::parse(v.parse().unwrap()).expect("invalid visibility found"))
s.value().split(' ').find(|v| *v != "with_prefix").map(|v| {
syn::parse_str(v)
.unwrap_or_else(|_| abort!(s.span(), "invalid visibility found"))
})
} else {
None
}
Expand All @@ -53,16 +54,11 @@ fn has_prefix_attr(f: &Field) -> bool {
let inner = f
.attrs
.iter()
.filter_map(|v| {
let meta = v.parse_meta().expect("Could not get attribute");
if ["get", "get_copy"]
.filter_map(|v| v.parse_meta().ok())
.filter(|meta| {
["get", "get_copy"]
.iter()
.any(|ident| meta.path().is_ident(ident))
{
Some(meta)
} else {
None
}
})
.last();
match inner {
Expand All @@ -82,7 +78,7 @@ pub fn implement(field: &Field, mode: &GenMode, params: &GenParams) -> TokenStre
let field_name = field
.clone()
.ident
.expect("Expected the field to have a name");
.unwrap_or_else(|| abort!(field.span(), "Expected the field to have a name"));

let fn_name = Ident::new(
&format!(
Expand All @@ -104,8 +100,8 @@ pub fn implement(field: &Field, mode: &GenMode, params: &GenParams) -> TokenStre
let attr = field
.attrs
.iter()
.filter_map(|v| {
let meta = v.parse_meta().expect("attribute");
.filter_map(|v| v.parse_meta().ok().map(|meta| (v, meta)))
.filter_map(|(v, meta)| {
if meta.path().is_ident("doc") {
doc.push(v);
None
Expand Down
25 changes: 12 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,17 @@ extern crate proc_macro2;

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::{abort_call_site, proc_macro_error, ResultExt};
use syn::{DataStruct, DeriveInput, Meta};

mod generate;
use crate::generate::{GenMode, GenParams};

#[proc_macro_derive(Getters, attributes(get, with_prefix))]
#[proc_macro_error]
pub fn getters(input: TokenStream) -> TokenStream {
// Parse the string representation
let ast: DeriveInput = syn::parse(input).expect("Couldn't parse for getters");
let ast: DeriveInput = syn::parse(input).expect_or_abort("Couldn't parse for getters");
let params = GenParams {
attribute_name: "get",
fn_name_prefix: "",
Expand All @@ -172,9 +174,10 @@ pub fn getters(input: TokenStream) -> TokenStream {
}

#[proc_macro_derive(CopyGetters, attributes(get_copy, with_prefix))]
#[proc_macro_error]
pub fn copy_getters(input: TokenStream) -> TokenStream {
// Parse the string representation
let ast: DeriveInput = syn::parse(input).expect("Couldn't parse for getters");
let ast: DeriveInput = syn::parse(input).expect_or_abort("Couldn't parse for getters");
let params = GenParams {
attribute_name: "get_copy",
fn_name_prefix: "",
Expand All @@ -190,9 +193,10 @@ pub fn copy_getters(input: TokenStream) -> TokenStream {
}

#[proc_macro_derive(MutGetters, attributes(get_mut))]
#[proc_macro_error]
pub fn mut_getters(input: TokenStream) -> TokenStream {
// Parse the string representation
let ast: DeriveInput = syn::parse(input).expect("Couldn't parse for getters");
let ast: DeriveInput = syn::parse(input).expect_or_abort("Couldn't parse for getters");
let params = GenParams {
attribute_name: "get_mut",
fn_name_prefix: "",
Expand All @@ -207,9 +211,10 @@ pub fn mut_getters(input: TokenStream) -> TokenStream {
}

#[proc_macro_derive(Setters, attributes(set))]
#[proc_macro_error]
pub fn setters(input: TokenStream) -> TokenStream {
// Parse the string representation
let ast: DeriveInput = syn::parse(input).expect("Couldn't parse for setters");
let ast: DeriveInput = syn::parse(input).expect_or_abort("Couldn't parse for setters");
let params = GenParams {
attribute_name: "set",
fn_name_prefix: "set_",
Expand All @@ -227,14 +232,8 @@ pub fn setters(input: TokenStream) -> TokenStream {
fn parse_global_attr(attrs: &[syn::Attribute], attribute_name: &str) -> Option<Meta> {
attrs
.iter()
.filter_map(|v| {
let meta = v.parse_meta().expect("attribute");
if meta.path().is_ident(attribute_name) {
Some(meta)
} else {
None
}
})
.filter_map(|v| v.parse_meta().ok()) // non "meta" attributes are not our concern
.filter(|meta| meta.path().is_ident(attribute_name))
.last()
}

Expand All @@ -257,6 +256,6 @@ fn produce(ast: &DeriveInput, mode: &GenMode, params: &GenParams) -> TokenStream
}
} else {
// Nope. This is an Enum. We cannot handle these!
panic!("#[derive(Getters)] is only defined for structs, not for enums!");
abort_call_site!("#[derive(Getters)] is only defined for structs, not for enums!");
}
}

0 comments on commit 895f47b

Please sign in to comment.