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 syn to 0.12 and quote to 0.4 #20

Merged
merged 4 commits into from
Jan 26, 2018
Merged
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: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ darling_core = { version = "=0.2.2", path = "core" }
darling_macro = { version = "=0.2.2", path = "macro" }

[dev-dependencies]
syn = "0.11.11"
quote = "0.3.15"
syn = "0.12.10"
quote = "0.4"

[workspace]
members = ["macro", "core"]
5 changes: 2 additions & 3 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ default = ["syn/full"]

[dependencies]
ident_case = "1.0.0"
lazy_static = "1.0.0"
syn = "0.11.11"
quote = "0.3.15"
syn = { version = "0.12.10", features = ["extra-traits"] }
quote = "0.4"
197 changes: 115 additions & 82 deletions core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,96 +8,100 @@ use {Error, FromField, FromVariant, Result};
///
/// `V` is the type which receives any encountered variants, and `F` receives struct fields.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Body<V, F> {
pub enum Data<V, F> {
Enum(Vec<V>),
Struct(VariantData<F>),
Struct(Fields<F>),
}

impl<V, F> Body<V, F> {
#[deprecated(since="0.3", note="this has been renamed to Data")]
pub type Body<V, F> = Data<V, F>;

impl<V, F> Data<V, F> {
/// Creates an empty body of the same shape as the passed-in body.
pub fn empty_from(src: &syn::Body) -> Self {
pub fn empty_from(src: &syn::Data) -> Self {
match *src {
syn::Body::Enum(_) => Body::Enum(vec![]),
syn::Body::Struct(ref vd) => Body::Struct(VariantData::empty_from(vd)),
syn::Data::Enum(_) => Data::Enum(vec![]),
syn::Data::Struct(ref vd) => Data::Struct(Fields::empty_from(&vd.fields)),
syn::Data::Union(_) => unreachable!(),
}
}

/// Creates a new `Body<&'a V, &'a F>` instance from `Body<V, F>`.
pub fn as_ref<'a>(&'a self) -> Body<&'a V, &'a F> {
/// Creates a new `Data<&'a V, &'a F>` instance from `Data<V, F>`.
pub fn as_ref<'a>(&'a self) -> Data<&'a V, &'a F> {
match *self {
Body::Enum(ref variants) => Body::Enum(variants.into_iter().collect()),
Body::Struct(ref data) => Body::Struct(data.as_ref()),
Data::Enum(ref variants) => Data::Enum(variants.into_iter().collect()),
Data::Struct(ref data) => Data::Struct(data.as_ref()),
}
}

/// Applies a function `V -> U` on enum variants, if this is an enum.
pub fn map_enum_variants<T, U>(self, map: T) -> Body<U, F>
pub fn map_enum_variants<T, U>(self, map: T) -> Data<U, F>
where T: FnMut(V) -> U
{
match self {
Body::Enum(v) => Body::Enum(v.into_iter().map(map).collect()),
Body::Struct(f) => Body::Struct(f),
Data::Enum(v) => Data::Enum(v.into_iter().map(map).collect()),
Data::Struct(f) => Data::Struct(f),
}
}

/// Applies a function `F -> U` on struct fields, if this is a struct.
pub fn map_struct_fields<T, U>(self, map: T) -> Body<V, U>
pub fn map_struct_fields<T, U>(self, map: T) -> Data<V, U>
where T: FnMut(F) -> U
{
match self {
Body::Enum(v) => Body::Enum(v),
Body::Struct(f) => Body::Struct(f.map(map)),
Data::Enum(v) => Data::Enum(v),
Data::Struct(f) => Data::Struct(f.map(map)),
}
}

/// Applies a function to the `VariantData` if this is a struct.
pub fn map_struct<T, U>(self, mut map: T) -> Body<V, U>
where T: FnMut(VariantData<F>) -> VariantData<U>
/// Applies a function to the `Fields` if this is a struct.
pub fn map_struct<T, U>(self, mut map: T) -> Data<V, U>
where T: FnMut(Fields<F>) -> Fields<U>
{
match self {
Body::Enum(v) => Body::Enum(v),
Body::Struct(f) => Body::Struct(map(f)),
Data::Enum(v) => Data::Enum(v),
Data::Struct(f) => Data::Struct(map(f)),
}
}

/// Consumes the `Body`, returning `VariantData<F>` if it was a struct.
pub fn take_struct(self) -> Option<VariantData<F>> {
/// Consumes the `Data`, returning `Fields<F>` if it was a struct.
pub fn take_struct(self) -> Option<Fields<F>> {
match self {
Body::Enum(_) => None,
Body::Struct(f) => Some(f),
Data::Enum(_) => None,
Data::Struct(f) => Some(f),
}
}

/// Consumes the `Body`, returning `Vec<V>` if it was an enum.
/// Consumes the `Data`, returning `Vec<V>` if it was an enum.
pub fn take_enum(self) -> Option<Vec<V>> {
match self {
Body::Enum(v) => Some(v),
Body::Struct(_) => None,
Data::Enum(v) => Some(v),
Data::Struct(_) => None,
}
}

/// Returns `true` if this instance is `Body::Enum`.
/// Returns `true` if this instance is `Data::Enum`.
pub fn is_enum(&self) -> bool {
match *self {
Body::Enum(_) => true,
Body::Struct(_) => false,
Data::Enum(_) => true,
Data::Struct(_) => false,
}
}

/// Returns `true` if this instance is `Body::Struct`.
/// Returns `true` if this instance is `Data::Struct`.
pub fn is_struct(&self) -> bool {
!self.is_enum()
}
}

impl<V: FromVariant, F: FromField> Body<V, F> {
/// Attempt to convert from a `syn::Body` instance.
pub fn try_from(body: &syn::Body) -> Result<Self> {
impl<V: FromVariant, F: FromField> Data<V, F> {
/// Attempt to convert from a `syn::Data` instance.
pub fn try_from(body: &syn::Data) -> Result<Self> {
match *body {
syn::Body::Enum(ref variants) => {
let mut items = Vec::with_capacity(variants.len());
syn::Data::Enum(ref data) => {
let mut items = Vec::with_capacity(data.variants.len());
let mut errors = Vec::new();
for v_result in variants.into_iter().map(FromVariant::from_variant) {
for v_result in data.variants.clone().into_iter().map(|v| FromVariant::from_variant(&v)) {
match v_result {
Ok(val) => items.push(val),
Err(err) => errors.push(err)
Expand All @@ -107,29 +111,33 @@ impl<V: FromVariant, F: FromField> Body<V, F> {
if !errors.is_empty() {
Err(Error::multiple(errors))
} else {
Ok(Body::Enum(items))
Ok(Data::Enum(items))
}
}
syn::Body::Struct(ref data) => Ok(Body::Struct(VariantData::try_from(data)?)),
syn::Data::Struct(ref data) => Ok(Data::Struct(Fields::try_from(&data.fields)?)),
syn::Data::Union(_) => unreachable!(),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantData<T> {
pub struct Fields<T> {
pub style: Style,
pub fields: Vec<T>,
}

impl<T> VariantData<T> {
pub fn empty_from(vd: &syn::VariantData) -> Self {
VariantData {
#[deprecated(since="0.3", note="this has been renamed to Fields")]
pub type VariantData<T> = Fields<T>;

impl<T> Fields<T> {
pub fn empty_from(vd: &syn::Fields) -> Self {
Fields {
style: vd.into(),
fields: Vec::new(),
}
}

/// Splits the `VariantData` into its style and fields for further processing.
/// Splits the `Fields` into its style and fields for further processing.
/// Returns an empty `Vec` for `Unit` data.
pub fn split(self) -> (Style, Vec<T>) {
(self.style, self.fields)
Expand All @@ -152,60 +160,85 @@ impl<T> VariantData<T> {
self.style.is_struct()
}

pub fn as_ref<'a>(&'a self) -> VariantData<&'a T> {
VariantData {
pub fn as_ref<'a>(&'a self) -> Fields<&'a T> {
Fields {
style: self.style,
fields: self.fields.iter().collect(),
}
}

pub fn map<F, U>(self, map: F) -> VariantData<U> where F: FnMut(T) -> U {
VariantData {
pub fn map<F, U>(self, map: F) -> Fields<U> where F: FnMut(T) -> U {
Fields {
style: self.style,
fields: self.fields.into_iter().map(map).collect()
}
}
}

impl<F: FromField> VariantData<F> {
pub fn try_from(data: &syn::VariantData) -> Result<Self> {
let fields = data.fields();
let mut items = Vec::with_capacity(fields.len());
let mut errors = Vec::new();

for field in fields {
let f_result = FromField::from_field(field);
match f_result {
Ok(val) => items.push(val),
Err(err) => errors.push(if let Some(ref ident) = field.ident {
err.at(ident.as_ref())
} else {
err
})
impl<F: FromField> Fields<F> {
pub fn try_from(fields: &syn::Fields) -> Result<Self> {
let (items, errors) = match *fields {
syn::Fields::Named(ref fields) => {
let mut items = Vec::with_capacity(fields.named.len());
let mut errors = Vec::new();

for field in &fields.named {
let f_result = FromField::from_field(field);
match f_result {
Ok(val) => items.push(val),
Err(err) => errors.push(if let Some(ref ident) = field.ident {
err.at(ident.as_ref())
} else {
err
})
}
}

(items, errors)
}
}
syn::Fields::Unnamed(ref fields) => {
let mut items = Vec::with_capacity(fields.unnamed.len());
let mut errors = Vec::new();

for field in &fields.unnamed {
let f_result = FromField::from_field(field);
match f_result {
Ok(val) => items.push(val),
Err(err) => errors.push(if let Some(ref ident) = field.ident {
err.at(ident.as_ref())
} else {
err
})
}
}

(items, errors)
}
syn::Fields::Unit => (vec![], vec![]),
};


if !errors.is_empty() {
Err(Error::multiple(errors))
} else {
Ok(VariantData {
style: data.into(),
Ok(Fields {
style: fields.into(),
fields: items,
})
})
}
}
}

impl<T> From<Style> for VariantData<T> {
impl<T> From<Style> for Fields<T> {
fn from(style: Style) -> Self {
VariantData {
Fields {
style,
fields: Vec::new(),
}
}
}

impl<T, U: Into<Vec<T>>> From<(Style, U)> for VariantData<T> {
impl<T, U: Into<Vec<T>>> From<(Style, U)> for Fields<T> {
fn from((style, fields): (Style, U)) -> Self {
style.with_fields(fields)
}
Expand All @@ -231,27 +264,27 @@ impl Style {
*self == Style::Struct
}

/// Creates a new `VariantData` of the specified style with the passed-in fields.
fn with_fields<T, U: Into<Vec<T>>>(self, fields: U) -> VariantData<T> {
VariantData {
/// Creates a new `Fields` of the specified style with the passed-in fields.
fn with_fields<T, U: Into<Vec<T>>>(self, fields: U) -> Fields<T> {
Fields {
style: self,
fields: fields.into(),
}
}
}

impl From<syn::VariantData> for Style {
fn from(vd: syn::VariantData) -> Self {
impl From<syn::Fields> for Style {
fn from(vd: syn::Fields) -> Self {
(&vd).into()
}
}

impl<'a> From<&'a syn::VariantData> for Style {
fn from(vd: &syn::VariantData) -> Self {
impl<'a> From<&'a syn::Fields> for Style {
fn from(vd: &syn::Fields) -> Self {
match *vd {
syn::VariantData::Struct(_) => Style::Struct,
syn::VariantData::Tuple(_) => Style::Tuple,
syn::VariantData::Unit => Style::Unit,
syn::Fields::Named(_) => Style::Struct,
syn::Fields::Unnamed(_) => Style::Tuple,
syn::Fields::Unit => Style::Unit,
}
}
}
}
10 changes: 5 additions & 5 deletions core/src/codegen/default_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ impl<'a> DefaultExpression<'a> {

impl<'a> ToTokens for DefaultExpression<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append(match *self {
tokens.append_all(match *self {
DefaultExpression::Inherit(ident) => {
let dsn = Ident::new(DEFAULT_STRUCT_NAME);
let dsn = Ident::from(DEFAULT_STRUCT_NAME);
quote!(#dsn.#ident)
},
DefaultExpression::Explicit(path) => quote!(#path()),
Expand All @@ -38,8 +38,8 @@ pub struct DefaultDeclaration<'a>(&'a DefaultExpression<'a>);

impl<'a> ToTokens for DefaultDeclaration<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
let name = Ident::new(DEFAULT_STRUCT_NAME);
let name = Ident::from(DEFAULT_STRUCT_NAME);
let expr = self.0;
tokens.append(quote!(let #name: Self = #expr;));
tokens.append_all(quote!(let #name: Self = #expr;));
}
}
}
6 changes: 3 additions & 3 deletions core/src/codegen/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl ErrorDeclaration {

impl ToTokens for ErrorDeclaration {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append(quote! {
tokens.append_all(quote! {
let mut __errors = Vec::new();
})
}
Expand Down Expand Up @@ -51,10 +51,10 @@ impl<'a> ToTokens for ErrorCheck<'a> {
quote!()
};

tokens.append(quote! {
tokens.append_all(quote! {
if !__errors.is_empty() {
return ::darling::export::Err(::darling::Error::multiple(__errors) #at_call);
}
})
}
}
}
Loading