Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies #16

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
target
Cargo.lock
*.rs.bk
[._]*.sw?
[._]sw?
*~
/_book
/node_modules
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ appveyor = { repository = "mcarton/rust-derivative" }
proc-macro = true

[dependencies]
itertools = "~0.5"
quote = "^0.3"
syn = { version = "0.10", features = ["aster", "full", "visit"] }
compiletest_rs = { version = "^0.2", optional = true }
quote = "0.5"
syn = { version = "0.13.1", features = ["extra-traits", "full", "visit"] }
compiletest_rs = { version = "0.3", optional = true }

[features]
nightly = ["compiletest_rs"]
70 changes: 39 additions & 31 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use syn;
#[derive(Debug)]
pub struct Input<'a> {
pub attrs: attr::Input,
pub body: Body<'a>,
pub data: Data<'a>,
pub generics: &'a syn::Generics,
pub ident: syn::Ident,
}

#[derive(Debug)]
pub enum Body<'a> {
pub enum Data<'a> {
Enum(Vec<Variant<'a>>),
Struct(Style, Vec<Field<'a>>),
}
Expand All @@ -27,7 +27,7 @@ pub struct Variant<'a> {
pub struct Field<'a> {
pub attrs: attr::Field,
pub ident: Option<syn::Ident>,
pub ty: &'a syn::Ty,
pub type_: &'a syn::Type,
}

#[derive(Clone, Copy, Debug)]
Expand All @@ -38,79 +38,87 @@ pub enum Style {
}

impl<'a> Input<'a> {
pub fn from_ast(item: &'a syn::MacroInput) -> Result<Input<'a>, String> {
let attrs = try!(attr::Input::from_ast(&item.attrs));
pub fn from_ast(item: &'a syn::DeriveInput) -> Result<Input<'a>, String> {
let attrs = attr::Input::from_ast(&item.attrs)?;

let body = match item.body {
syn::Body::Enum(ref variants) => {
Body::Enum(try!(enum_from_ast(variants)))
let data = match item.data {
syn::Data::Enum(ref data_enum) => {
Data::Enum(enum_from_ast(&data_enum.variants)?)
}
syn::Body::Struct(ref variant_data) => {
let (style, fields) = try!(struct_from_ast(variant_data));
Body::Struct(style, fields)
syn::Data::Struct(ref data_struct) => {
let (style, fields) = struct_like_data_from_ast(&data_struct.fields)?;
Data::Struct(style, fields)
}
syn::Data::Union(_) => {
// TODO: support or not support?
return Err("`derivative` doesn't support unions".to_string());
}
};

Ok(Input {
attrs: attrs,
body: body,
data: data,
generics: &item.generics,
ident: item.ident.clone(),
ident: item.ident,
})
}
}

impl<'a> Body<'a> {
impl<'a> Data<'a> {
pub fn all_fields(&self) -> Vec<&Field> {
match *self {
Body::Enum(ref variants) => {
Data::Enum(ref variants) => {
variants
.iter()
.flat_map(|variant| variant.fields.iter())
.collect()
}
Body::Struct(_, ref fields) => fields.iter().collect(),
Data::Struct(_, ref fields) => fields.iter().collect(),
}
}
}

fn enum_from_ast<'a>(variants: &'a [syn::Variant]) -> Result<Vec<Variant<'a>>, String> {
fn enum_from_ast<'a>(
variants: &'a syn::punctuated::Punctuated<syn::Variant, Token![,]>,
) -> Result<Vec<Variant<'a>>, String> {
variants
.iter()
.map(|variant| {
let (style, fields) = try!(struct_from_ast(&variant.data));
let (style, fields) = struct_like_data_from_ast(&variant.fields)?;
Ok(Variant {
attrs: try!(attr::Input::from_ast(&variant.attrs)),
attrs: attr::Input::from_ast(&variant.attrs)?,
fields: fields,
ident: variant.ident.clone(),
ident: variant.ident,
style: style,
})
})
.collect()
}

fn struct_from_ast<'a>(data: &'a syn::VariantData) -> Result<(Style, Vec<Field<'a>>), String> {
match *data {
syn::VariantData::Struct(ref fields) => {
Ok((Style::Struct, try!(fields_from_ast(fields))))
fn struct_like_data_from_ast<'a>(fields: &'a syn::Fields) -> Result<(Style, Vec<Field<'a>>), String> {
match *fields {
syn::Fields::Named(syn::FieldsNamed { ref named, .. }) => {
Ok((Style::Struct, fields_from_ast(named)?))
}
syn::VariantData::Tuple(ref fields) => {
Ok((Style::Tuple, try!(fields_from_ast(fields))))
syn::Fields::Unnamed(syn::FieldsUnnamed { ref unnamed, .. }) => {
Ok((Style::Tuple, fields_from_ast(unnamed)?))
}
syn::VariantData::Unit => {
syn::Fields::Unit => {
Ok((Style::Unit, Vec::new()))
}
}
}

fn fields_from_ast<'a>(fields: &'a [syn::Field]) -> Result<Vec<Field<'a>>, String> {
fn fields_from_ast<'a>(
fields: &'a syn::punctuated::Punctuated<syn::Field, Token![,]>,
) -> Result<Vec<Field<'a>>, String> {
fields
.iter()
.map(|field| {
Ok(Field {
attrs: try!(attr::Field::from_ast(field)),
ident: field.ident.clone(),
ty: &field.ty,
attrs: attr::Field::from_ast(field)?,
ident: field.ident,
type_: &field.ty,
})
})
.collect()
Expand Down
Loading