From b8772b8b4bee82dbea32691baca6eef24271269e Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Tue, 19 Mar 2019 07:51:23 -0700 Subject: [PATCH 01/10] Improve darling_core::options::shape docs --- core/src/options/shape.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/options/shape.rs b/core/src/options/shape.rs index fe9f25f..7c27adb 100644 --- a/core/src/options/shape.rs +++ b/core/src/options/shape.rs @@ -1,9 +1,24 @@ +//! Types for "shape" validation. This allows types deriving `FromDeriveInput` etc. to declare +//! that they only work on - for example - structs with named fields, or newtype enum variants. + use proc_macro2::TokenStream; use quote::{ToTokens, TokenStreamExt}; use syn::{Meta, NestedMeta}; use {Error, FromMeta, Result}; +/// Receiver struct for shape validation. Shape validation allows a deriving type +/// to declare that it only accepts - for example - named structs, or newtype enum +/// variants. +/// +/// # Usage +/// Because `Shape` implements `FromMeta`, the name of the field where it appears is +/// controlled by the struct that declares `Shape` as a member. That field name is +/// shown as `ignore` below. +/// +/// ```rust,ignore +/// #[ignore(any, struct_named, enum_newtype)] +/// ``` #[derive(Debug, Clone)] pub struct Shape { enum_values: DataShape, @@ -97,6 +112,8 @@ impl ToTokens for Shape { } } +/// Receiver for shape information within a struct or enum context. See `Shape` for more information +/// on valid uses of shape validation. #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct DataShape { /// The kind of shape being described. This can be `struct_` or `enum_`. From c0ee99aab773b5393d85abca58d348a278b99de5 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:13:25 -0700 Subject: [PATCH 02/10] Enable suggestions by default * Reduce strsim to 0.7.0 so it works on rustc 1.18.0 --- .travis.yml | 6 ++++-- CHANGELOG.md | 3 +++ Cargo.toml | 1 + core/Cargo.toml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8687339..c74d80a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,7 @@ env: # Test with and without the suggestion feature enabled # See https://github.com/servo/rust-smallvec/blob/master/.travis.yml for guide script: | - cargo test --verbose && - ([ $TRAVIS_RUST_VERSION = 1.18.0 ] || cargo test --verbose --features suggestions) \ No newline at end of file + cargo test --verbose + +# To enable version-specific feature tests, add `&&` to the script, followed by this line: +# ([ $TRAVIS_RUST_VERSION = 1.18.0 ] || cargo test --verbose --features suggestions) \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f91819..dd654e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## v0.9.0 +- Enable "did you mean" suggestions by default + ## v0.8.6 (March 18, 2019) - Added "did you mean" suggestions for unknown fields behind the `suggestions` flag [#60](https://github.com/TedDriggs/issues/60) - Added `Error::unknown_field_with_alts` to support the suggestion use-case. diff --git a/Cargo.toml b/Cargo.toml index 2ea187e..b8a78ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ quote = "0.6" syn = "0.15.26" [features] +default = ["suggestions"] diagnostics = ["darling_core/diagnostics"] suggestions = ["darling_core/suggestions"] diff --git a/core/Cargo.toml b/core/Cargo.toml index 3e8b9bc..866d862 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -22,4 +22,4 @@ proc-macro2 = "0.4.26" quote = "0.6" syn = { version = "0.15.26", features = ["extra-traits"] } fnv = "1.0.6" -strsim = { version = "0.8.0", optional = true } \ No newline at end of file +strsim = { version = "0.7.0", optional = true } \ No newline at end of file From 419dd5d7d00ebaa4be2c0b3952a377a9492f845e Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:13:52 -0700 Subject: [PATCH 03/10] Fix test issues on rustc 1.18.0 --- core/src/error/mod.rs | 2 +- core/src/usage/mod.rs | 2 +- core/src/util/ident_list.rs | 5 +++-- tests/supports.rs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/error/mod.rs b/core/src/error/mod.rs index 74e7f88..4b5b198 100644 --- a/core/src/error/mod.rs +++ b/core/src/error/mod.rs @@ -110,7 +110,7 @@ impl Error { /// /// impl FromMeta for Foo { /// fn from_value(value: &Lit) -> Result { - /// if let Lit::Str(ref lit_str) = value { + /// if let Lit::Str(ref lit_str) = *value { /// Ok(Foo(lit_str.value())) /// } else { /// Err(Error::unexpected_lit_type(value)) diff --git a/core/src/usage/mod.rs b/core/src/usage/mod.rs index bc1d1e0..fe8f12f 100644 --- a/core/src/usage/mod.rs +++ b/core/src/usage/mod.rs @@ -48,7 +48,7 @@ //! .params //! .into_iter() //! .filter(|gp| { -//! match gp { +//! match *gp { //! GenericParam::Type(ref ty) => int_type_params.contains(&ty.ident), //! GenericParam::Lifetime(ref lt) => int_lifetimes.contains(<.lifetime), //! _ => true, diff --git a/core/src/util/ident_list.rs b/core/src/util/ident_list.rs index 4da04a9..5dfe5aa 100644 --- a/core/src/util/ident_list.rs +++ b/core/src/util/ident_list.rs @@ -64,11 +64,12 @@ impl FromMeta for IdentList { mod tests { use super::IdentList; use proc_macro2::TokenStream; + use syn::{Attribute, Meta}; use FromMeta; /// parse a string as a syn::Meta instance. - fn pm(tokens: TokenStream) -> ::std::result::Result { - let attribute: syn::Attribute = parse_quote!(#[#tokens]); + fn pm(tokens: TokenStream) -> ::std::result::Result { + let attribute: Attribute = parse_quote!(#[#tokens]); attribute.interpret_meta().ok_or("Unable to parse".into()) } diff --git a/tests/supports.rs b/tests/supports.rs index 9408a49..ead3bad 100644 --- a/tests/supports.rs +++ b/tests/supports.rs @@ -28,7 +28,7 @@ pub struct StructContainer { } mod source { - use syn::{self, DeriveInput}; + use syn::DeriveInput; pub fn newtype_enum() -> DeriveInput { parse_quote!{ From 038614fd9118933be399c1687076afa8362ec8b5 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Tue, 19 Mar 2019 07:55:42 -0700 Subject: [PATCH 04/10] Make darling_core::{codegen, options} crate-private This will make internal refactoring easier going forward. This change also removes dead code exposed by making the crates private. Fixes #58 --- core/src/codegen/trait_impl.rs | 9 +++------ core/src/lib.rs | 4 ++-- core/src/options/shape.rs | 9 --------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/core/src/codegen/trait_impl.rs b/core/src/codegen/trait_impl.rs index a2fa989..2f4f4ae 100644 --- a/core/src/codegen/trait_impl.rs +++ b/core/src/codegen/trait_impl.rs @@ -27,16 +27,13 @@ impl<'a> TraitImpl<'a> { .collect() } - /// Get the type parameters which are used by non-skipped fields. + /// Get the type parameters which are used by non-skipped, non-magic fields. + /// These type parameters will have a `FromMeta` bound applied to them in emitted + /// code. pub fn used_type_params(&self) -> IdentSet { self.type_params_matching(|f| !f.skip, |v| !v.skip) } - /// Get the type parameters which are used by skipped fields. - pub fn skipped_type_params(&self) -> IdentSet { - self.type_params_matching(|f| f.skip, |v| v.skip) - } - fn type_params_matching<'b, F, V>(&'b self, field_filter: F, variant_filter: V) -> IdentSet where F: Fn(&&Field) -> bool, diff --git a/core/src/lib.rs b/core/src/lib.rs index 4cb73a4..6ce361b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -19,7 +19,7 @@ mod macros_private; mod macros_public; pub mod ast; -pub mod codegen; +pub(crate) mod codegen; pub mod derive; pub mod error; mod from_derive_input; @@ -29,7 +29,7 @@ mod from_generics; mod from_meta; mod from_type_param; mod from_variant; -pub mod options; +pub(crate) mod options; pub mod usage; pub mod util; diff --git a/core/src/options/shape.rs b/core/src/options/shape.rs index 7c27adb..8759669 100644 --- a/core/src/options/shape.rs +++ b/core/src/options/shape.rs @@ -26,15 +26,6 @@ pub struct Shape { any: bool, } -impl Shape { - pub fn all() -> Self { - Shape { - any: true, - ..Default::default() - } - } -} - impl Default for Shape { fn default() -> Self { Shape { From 4e4637143fe3cbd850864534bef4830525fc1782 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:16:14 -0700 Subject: [PATCH 05/10] Make util::Override::as_mut return &mut T Fixes #66 --- core/src/util/over_ride.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/util/over_ride.rs b/core/src/util/over_ride.rs index 668676c..5223a02 100644 --- a/core/src/util/over_ride.rs +++ b/core/src/util/over_ride.rs @@ -59,7 +59,7 @@ impl Override { /// Converts from `Override` to `Override<&mut T>`. /// /// Produces a new `Override`, containing a mutable reference into the original. - pub fn as_mut<'a>(&'a mut self) -> Override<&'a T> { + pub fn as_mut<'a>(&'a mut self) -> Override<&'a mut T> { match *self { Inherit => Inherit, Explicit(ref mut val) => Explicit(val), From 80743521d24c10aaa1037528aa06b73fe9fe9fe4 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:22:18 -0700 Subject: [PATCH 06/10] Bump version to 0.9.0 * Update changelog * Remove racer hack from darling_core/Cargo.toml --- CHANGELOG.md | 4 +++- Cargo.toml | 8 ++++---- core/Cargo.toml | 7 ++----- macro/Cargo.toml | 4 ++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd654e0..0416336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # Changelog -## v0.9.0 +## v0.9.0 (March 20, 2019) - Enable "did you mean" suggestions by default +- Make `darling_core::{codegen, options}` private [#58](https://github.com/TedDriggs/darling/issues/58) +- Fix `Override::as_mut`: [#66](https://github.com/TedDriggs/darling/issues/66) ## v0.8.6 (March 18, 2019) - Added "did you mean" suggestions for unknown fields behind the `suggestions` flag [#60](https://github.com/TedDriggs/issues/60) diff --git a/Cargo.toml b/Cargo.toml index b8a78ba..19cd750 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "darling" -version = "0.8.6" +version = "0.9.0" authors = ["Ted Driggs "] repository = "https://github.com/TedDriggs/darling" -documentation = "https://docs.rs/darling/0.8.6" +documentation = "https://docs.rs/darling/0.9.0" description = """ A proc-macro library for reading attributes into structs when implementing custom derives. @@ -16,8 +16,8 @@ exclude = ["/.travis.yml", "/publish.sh"] travis-ci = { repository = "TedDriggs/darling" } [dependencies] -darling_core = { version = "=0.8.6", path = "core" } -darling_macro = { version = "=0.8.6", path = "macro" } +darling_core = { version = "=0.9.0", path = "core" } +darling_macro = { version = "=0.9.0", path = "macro" } [dev-dependencies] proc-macro2 = "0.4" diff --git a/core/Cargo.toml b/core/Cargo.toml index 866d862..04c66e5 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "darling_core" -version = "0.8.6" +version = "0.9.0" authors = ["Ted Driggs "] repository = "https://github.com/TedDriggs/darling" description = """ @@ -10,9 +10,6 @@ implementing custom derives. Use https://crates.io/crates/darling in your code. license = "MIT" [features] -# temporary hack to make Racer autocomplete work; it requires a 3-part version -# number and doesn't allow for any feature declarations. -default = ["syn/full"] diagnostics = [] suggestions = ["strsim"] @@ -20,6 +17,6 @@ suggestions = ["strsim"] ident_case = "1.0.0" proc-macro2 = "0.4.26" quote = "0.6" -syn = { version = "0.15.26", features = ["extra-traits"] } +syn = { version = "0.15.26", features = ["full", "extra-traits"] } fnv = "1.0.6" strsim = { version = "0.7.0", optional = true } \ No newline at end of file diff --git a/macro/Cargo.toml b/macro/Cargo.toml index eef723a..d3cd15a 100644 --- a/macro/Cargo.toml +++ b/macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "darling_macro" -version = "0.8.6" +version = "0.9.0" authors = ["Ted Driggs "] repository = "https://github.com/TedDriggs/darling" description = """ @@ -12,7 +12,7 @@ license = "MIT" [dependencies] quote = "0.6" syn = "0.15.26" -darling_core = { version = "=0.8.6", path = "../core" } +darling_core = { version = "=0.9.0", path = "../core" } [lib] proc-macro = true From b179505a8d3b4c20489f3d118a7e0fc628b9ffde Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:28:54 -0700 Subject: [PATCH 07/10] Add maintenance badge to main crate Fixes #69 --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 19cd750..7d9afd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ exclude = ["/.travis.yml", "/publish.sh"] [badges] travis-ci = { repository = "TedDriggs/darling" } +maintenance = { status = "actively-developed" } [dependencies] darling_core = { version = "=0.9.0", path = "core" } From ab36a656a899af3032b400f361bbf5dd32a36785 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:30:36 -0700 Subject: [PATCH 08/10] Add rustc min version badge Fixes #68 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 28d07cf..af5bb8c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ Darling [![Build Status](https://travis-ci.org/TedDriggs/darling.svg?branch=master)](https://travis-ci.org/TedDriggs/darling) [![Latest Version](https://img.shields.io/crates/v/darling.svg)](https://crates.io/crates/darling) +[![Rustc Version 1.18+](https://img.shields.io/badge/rustc-1.18+-lightgray.svg)](https://blog.rust-lang.org/2017/06/08/Rust-1.18.html) `darling` is a crate for proc macro authors, which enables parsing attributes into structs. It is heavily inspired by `serde` both in its internals and in its API. From c1c6d7200807f1747a9c7f7fb01ad017f22a87a5 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:39:08 -0700 Subject: [PATCH 09/10] Expand README content * Add "Benefits" section * Add "Additional Modules" section --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index af5bb8c..ae128af 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ Darling `darling` is a crate for proc macro authors, which enables parsing attributes into structs. It is heavily inspired by `serde` both in its internals and in its API. +# Benefits +* Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment. +* Great validation and errors, no work required. When users of your proc-macro make a mistake, `darling` makes sure they get error markers at the right place in their source, and provides "did you mean" suggestions for misspelled fields. + # Usage `darling` provides a set of traits which can be derived or manually implemented. @@ -15,6 +19,11 @@ Darling 3. `FromField` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity (if it exists), type, and visibility of the field. 4. `FromVariant` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity and contents of the variant, which can be transformed the same as any other `darling` input. +## Additional Modules +* `darling::ast` provides generic types for representing the AST. +* `darling::usage` provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum. +* `darling::util` provides helper types with special `FromMeta` implementations, such as `IdentList`. + # Example ```rust,ignore @@ -101,3 +110,4 @@ Darling's features are built to work well for real-world projects. * **Skip fields**: Use `#[darling(skip)]` to mark a field that shouldn't be read from attribute meta-items. * **Multiple-occurrence fields**: Use `#[darling(multiple)]` on a `Vec` field to allow that field to appear multiple times in the meta-item. Each occurrence will be pushed into the `Vec`. * **Span access**: Use `darling::util::SpannedValue` in a struct to get access to that meta item's source code span. This can be used to emit warnings that point at a specific field from your proc macro. In addition, you can use `darling::Error::write_errors` to automatically get precise error location details in most cases. +* **"Did you mean" suggestions**: Compile errors from derived darling trait impls include suggestions for misspelled fields. \ No newline at end of file From cd92bc74d08905f1029156e52acbd522a7c0ee36 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 20 Mar 2019 07:44:57 -0700 Subject: [PATCH 10/10] Remove deprecated items --- core/src/ast/data.rs | 6 ------ core/src/error/mod.rs | 9 --------- 2 files changed, 15 deletions(-) diff --git a/core/src/ast/data.rs b/core/src/ast/data.rs index 8ea42bd..a0c765c 100644 --- a/core/src/ast/data.rs +++ b/core/src/ast/data.rs @@ -16,9 +16,6 @@ pub enum Data { Struct(Fields), } -#[deprecated(since = "0.3.0", note = "this has been renamed to Data")] -pub type Body = Data; - impl Data { /// Creates an empty body of the same shape as the passed-in body. pub fn empty_from(src: &syn::Data) -> Self { @@ -159,9 +156,6 @@ pub struct Fields { pub fields: Vec, } -#[deprecated(since = "0.3.0", note = "this has been renamed to Fields")] -pub type VariantData = Fields; - impl Fields { pub fn empty_from(vd: &syn::Fields) -> Self { Fields { diff --git a/core/src/error/mod.rs b/core/src/error/mod.rs index 4b5b198..f38b2a2 100644 --- a/core/src/error/mod.rs +++ b/core/src/error/mod.rs @@ -183,15 +183,6 @@ impl Error { self.span.is_some() } - /// Override the source code location of this error with a new one. - #[deprecated( - since = "0.8.3", - note = "Callers should not broaden error spans. Use with_span instead." - )] - pub fn set_span(&mut self, span: Span) { - self.span = Some(span) - } - /// Tie a span to the error if none is already present. This is used in `darling::FromMeta` /// and other traits to attach errors to the most specific possible location in the input /// source code.