diff --git a/src/attrs.rs b/src/attrs.rs
new file mode 100644
index 0000000..d75b50c
--- /dev/null
+++ b/src/attrs.rs
@@ -0,0 +1,666 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::doc_comments::process_doc_comment;
+use crate::{parse::*, spanned::Sp, ty::Ty};
+
+use std::env;
+
+use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase};
+use proc_macro2::{Span, TokenStream};
+use proc_macro_error::abort;
+use quote::{quote, quote_spanned, ToTokens};
+use syn::{
+    self, ext::IdentExt, spanned::Spanned, Attribute, Expr, Ident, LitStr, MetaNameValue, Type,
+};
+
+#[derive(Clone)]
+pub enum Kind {
+    Arg(Sp<Ty>),
+    Subcommand(Sp<Ty>),
+    ExternalSubcommand,
+    Flatten,
+    Skip(Option<Expr>),
+}
+
+#[derive(Clone)]
+pub struct Method {
+    name: Ident,
+    args: TokenStream,
+}
+
+#[derive(Clone)]
+pub struct Parser {
+    pub kind: Sp<ParserKind>,
+    pub func: TokenStream,
+}
+
+#[derive(Debug, PartialEq, Clone)]
+pub enum ParserKind {
+    FromStr,
+    TryFromStr,
+    FromOsStr,
+    TryFromOsStr,
+    FromOccurrences,
+    FromFlag,
+}
+
+/// Defines the casing for the attributes long representation.
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum CasingStyle {
+    /// Indicate word boundaries with uppercase letter, excluding the first word.
+    Camel,
+    /// Keep all letters lowercase and indicate word boundaries with hyphens.
+    Kebab,
+    /// Indicate word boundaries with uppercase letter, including the first word.
+    Pascal,
+    /// Keep all letters uppercase and indicate word boundaries with underscores.
+    ScreamingSnake,
+    /// Keep all letters lowercase and indicate word boundaries with underscores.
+    Snake,
+    /// Use the original attribute name defined in the code.
+    Verbatim,
+}
+
+#[derive(Clone)]
+pub enum Name {
+    Derived(Ident),
+    Assigned(TokenStream),
+}
+
+#[derive(Clone)]
+pub struct Attrs {
+    name: Name,
+    casing: Sp<CasingStyle>,
+    env_casing: Sp<CasingStyle>,
+    ty: Option<Type>,
+    doc_comment: Vec<Method>,
+    methods: Vec<Method>,
+    parser: Sp<Parser>,
+    author: Option<Method>,
+    about: Option<Method>,
+    version: Option<Method>,
+    no_version: Option<Ident>,
+    verbatim_doc_comment: Option<Ident>,
+    has_custom_parser: bool,
+    kind: Sp<Kind>,
+}
+
+impl Method {
+    pub fn new(name: Ident, args: TokenStream) -> Self {
+        Method { name, args }
+    }
+
+    fn from_lit_or_env(ident: Ident, lit: Option<LitStr>, env_var: &str) -> Option<Self> {
+        let mut lit = match lit {
+            Some(lit) => lit,
+
+            None => match env::var(env_var) {
+                Ok(val) => LitStr::new(&val, ident.span()),
+                Err(_) => {
+                    abort!(ident,
+                        "cannot derive `{}` from Cargo.toml", ident;
+                        note = "`{}` environment variable is not set", env_var;
+                        help = "use `{} = \"...\"` to set {} manually", ident, ident;
+                    );
+                }
+            },
+        };
+
+        if ident == "author" {
+            let edited = process_author_str(&lit.value());
+            lit = LitStr::new(&edited, lit.span());
+        }
+
+        Some(Method::new(ident, quote!(#lit)))
+    }
+}
+
+impl ToTokens for Method {
+    fn to_tokens(&self, ts: &mut TokenStream) {
+        let Method { ref name, ref args } = self;
+        quote!(.#name(#args)).to_tokens(ts);
+    }
+}
+
+impl Parser {
+    fn default_spanned(span: Span) -> Sp<Self> {
+        let kind = Sp::new(ParserKind::TryFromStr, span);
+        let func = quote_spanned!(span=> ::std::str::FromStr::from_str);
+        Sp::new(Parser { kind, func }, span)
+    }
+
+    fn from_spec(parse_ident: Ident, spec: ParserSpec) -> Sp<Self> {
+        use ParserKind::*;
+
+        let kind = match &*spec.kind.to_string() {
+            "from_str" => FromStr,
+            "try_from_str" => TryFromStr,
+            "from_os_str" => FromOsStr,
+            "try_from_os_str" => TryFromOsStr,
+            "from_occurrences" => FromOccurrences,
+            "from_flag" => FromFlag,
+            s => abort!(spec.kind, "unsupported parser `{}`", s),
+        };
+
+        let func = match spec.parse_func {
+            None => match kind {
+                FromStr | FromOsStr => {
+                    quote_spanned!(spec.kind.span()=> ::std::convert::From::from)
+                }
+                TryFromStr => quote_spanned!(spec.kind.span()=> ::std::str::FromStr::from_str),
+                TryFromOsStr => abort!(
+                    spec.kind,
+                    "you must set parser for `try_from_os_str` explicitly"
+                ),
+                FromOccurrences => quote_spanned!(spec.kind.span()=> { |v| v as _ }),
+                FromFlag => quote_spanned!(spec.kind.span()=> ::std::convert::From::from),
+            },
+
+            Some(func) => match func {
+                syn::Expr::Path(_) => quote!(#func),
+                _ => abort!(func, "`parse` argument must be a function path"),
+            },
+        };
+
+        let kind = Sp::new(kind, spec.kind.span());
+        let parser = Parser { kind, func };
+        Sp::new(parser, parse_ident.span())
+    }
+}
+
+impl CasingStyle {
+    fn from_lit(name: LitStr) -> Sp<Self> {
+        use CasingStyle::*;
+
+        let normalized = name.value().to_camel_case().to_lowercase();
+        let cs = |kind| Sp::new(kind, name.span());
+
+        match normalized.as_ref() {
+            "camel" | "camelcase" => cs(Camel),
+            "kebab" | "kebabcase" => cs(Kebab),
+            "pascal" | "pascalcase" => cs(Pascal),
+            "screamingsnake" | "screamingsnakecase" => cs(ScreamingSnake),
+            "snake" | "snakecase" => cs(Snake),
+            "verbatim" | "verbatimcase" => cs(Verbatim),
+            s => abort!(name, "unsupported casing: `{}`", s),
+        }
+    }
+}
+
+impl Name {
+    pub fn translate(self, style: CasingStyle) -> TokenStream {
+        use CasingStyle::*;
+
+        match self {
+            Name::Assigned(tokens) => tokens,
+            Name::Derived(ident) => {
+                let s = ident.unraw().to_string();
+                let s = match style {
+                    Pascal => s.to_camel_case(),
+                    Kebab => s.to_kebab_case(),
+                    Camel => s.to_mixed_case(),
+                    ScreamingSnake => s.to_shouty_snake_case(),
+                    Snake => s.to_snake_case(),
+                    Verbatim => s,
+                };
+                quote_spanned!(ident.span()=> #s)
+            }
+        }
+    }
+}
+
+impl Attrs {
+    fn new(
+        default_span: Span,
+        name: Name,
+        parent_attrs: Option<&Attrs>,
+        ty: Option<Type>,
+        casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
+    ) -> Self {
+        let no_version = parent_attrs
+            .as_ref()
+            .map(|attrs| attrs.no_version.clone())
+            .unwrap_or(None);
+
+        Self {
+            name,
+            ty,
+            casing,
+            env_casing,
+            doc_comment: vec![],
+            methods: vec![],
+            parser: Parser::default_spanned(default_span),
+            about: None,
+            author: None,
+            version: None,
+            no_version,
+            verbatim_doc_comment: None,
+
+            has_custom_parser: false,
+            kind: Sp::new(Kind::Arg(Sp::new(Ty::Other, default_span)), default_span),
+        }
+    }
+
+    fn push_method(&mut self, name: Ident, arg: impl ToTokens) {
+        if name == "name" {
+            self.name = Name::Assigned(quote!(#arg));
+        } else if name == "version" {
+            self.version = Some(Method::new(name, quote!(#arg)));
+        } else {
+            self.methods.push(Method::new(name, quote!(#arg)))
+        }
+    }
+
+    fn push_attrs(&mut self, attrs: &[Attribute]) {
+        use crate::parse::StructOptAttr::*;
+
+        for attr in parse_structopt_attributes(attrs) {
+            match attr {
+                Short(ident) | Long(ident) => {
+                    self.push_method(ident, self.name.clone().translate(*self.casing));
+                }
+
+                Env(ident) => {
+                    self.push_method(ident, self.name.clone().translate(*self.env_casing));
+                }
+
+                Subcommand(ident) => {
+                    let ty = Sp::call_site(Ty::Other);
+                    let kind = Sp::new(Kind::Subcommand(ty), ident.span());
+                    self.set_kind(kind);
+                }
+
+                ExternalSubcommand(ident) => {
+                    self.kind = Sp::new(Kind::ExternalSubcommand, ident.span());
+                }
+
+                Flatten(ident) => {
+                    let kind = Sp::new(Kind::Flatten, ident.span());
+                    self.set_kind(kind);
+                }
+
+                Skip(ident, expr) => {
+                    let kind = Sp::new(Kind::Skip(expr), ident.span());
+                    self.set_kind(kind);
+                }
+
+                NoVersion(ident) => self.no_version = Some(ident),
+
+                VerbatimDocComment(ident) => self.verbatim_doc_comment = Some(ident),
+
+                DefaultValue(ident, lit) => {
+                    let val = if let Some(lit) = lit {
+                        quote!(#lit)
+                    } else {
+                        let ty = if let Some(ty) = self.ty.as_ref() {
+                            ty
+                        } else {
+                            abort!(
+                                ident,
+                                "#[structopt(default_value)] (without an argument) can be used \
+                                only on field level";
+
+                                note = "see \
+                                    https://docs.rs/structopt/0.3.5/structopt/#magical-methods")
+                        };
+
+                        quote_spanned!(ident.span()=> {
+                            ::structopt::lazy_static::lazy_static! {
+                                static ref DEFAULT_VALUE: &'static str = {
+                                    let val = <#ty as ::std::default::Default>::default();
+                                    let s = ::std::string::ToString::to_string(&val);
+                                    ::std::boxed::Box::leak(s.into_boxed_str())
+                                };
+                            }
+                            *DEFAULT_VALUE
+                        })
+                    };
+
+                    self.methods.push(Method::new(ident, val));
+                }
+
+                About(ident, about) => {
+                    self.about = Method::from_lit_or_env(ident, about, "CARGO_PKG_DESCRIPTION");
+                }
+
+                Author(ident, author) => {
+                    self.author = Method::from_lit_or_env(ident, author, "CARGO_PKG_AUTHORS");
+                }
+
+                Version(ident, version) => {
+                    self.push_method(ident, version);
+                }
+
+                NameLitStr(name, lit) => {
+                    self.push_method(name, lit);
+                }
+
+                NameExpr(name, expr) => {
+                    self.push_method(name, expr);
+                }
+
+                MethodCall(name, args) => self.push_method(name, quote!(#(#args),*)),
+
+                RenameAll(_, casing_lit) => {
+                    self.casing = CasingStyle::from_lit(casing_lit);
+                }
+
+                RenameAllEnv(_, casing_lit) => {
+                    self.env_casing = CasingStyle::from_lit(casing_lit);
+                }
+
+                Parse(ident, spec) => {
+                    self.has_custom_parser = true;
+                    self.parser = Parser::from_spec(ident, spec);
+                }
+            }
+        }
+    }
+
+    fn push_doc_comment(&mut self, attrs: &[Attribute], name: &str) {
+        use crate::Lit::*;
+        use crate::Meta::*;
+
+        let comment_parts: Vec<_> = attrs
+            .iter()
+            .filter(|attr| attr.path.is_ident("doc"))
+            .filter_map(|attr| {
+                if let Ok(NameValue(MetaNameValue { lit: Str(s), .. })) = attr.parse_meta() {
+                    Some(s.value())
+                } else {
+                    // non #[doc = "..."] attributes are not our concern
+                    // we leave them for rustc to handle
+                    None
+                }
+            })
+            .collect();
+
+        self.doc_comment =
+            process_doc_comment(comment_parts, name, self.verbatim_doc_comment.is_none());
+    }
+
+    pub fn from_struct(
+        span: Span,
+        attrs: &[Attribute],
+        name: Name,
+        parent_attrs: Option<&Attrs>,
+        argument_casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
+    ) -> Self {
+        let mut res = Self::new(span, name, parent_attrs, None, argument_casing, env_casing);
+        res.push_attrs(attrs);
+        res.push_doc_comment(attrs, "about");
+
+        if res.has_custom_parser {
+            abort!(
+                res.parser.span(),
+                "`parse` attribute is only allowed on fields"
+            );
+        }
+        match &*res.kind {
+            Kind::Subcommand(_) => abort!(res.kind.span(), "subcommand is only allowed on fields"),
+            Kind::Skip(_) => abort!(res.kind.span(), "skip is only allowed on fields"),
+            Kind::Arg(_) | Kind::ExternalSubcommand | Kind::Flatten => res,
+        }
+    }
+
+    pub fn from_field(
+        field: &syn::Field,
+        parent_attrs: Option<&Attrs>,
+        struct_casing: Sp<CasingStyle>,
+        env_casing: Sp<CasingStyle>,
+    ) -> Self {
+        let name = field.ident.clone().unwrap();
+        let mut res = Self::new(
+            field.span(),
+            Name::Derived(name),
+            parent_attrs,
+            Some(field.ty.clone()),
+            struct_casing,
+            env_casing,
+        );
+        res.push_attrs(&field.attrs);
+        res.push_doc_comment(&field.attrs, "help");
+
+        match &*res.kind {
+            Kind::Flatten => {
+                if res.has_custom_parser {
+                    abort!(
+                        res.parser.span(),
+                        "parse attribute is not allowed for flattened entry"
+                    );
+                }
+                if res.has_explicit_methods() || res.has_doc_methods() {
+                    abort!(
+                        res.kind.span(),
+                        "methods and doc comments are not allowed for flattened entry"
+                    );
+                }
+            }
+
+            Kind::ExternalSubcommand => {}
+
+            Kind::Subcommand(_) => {
+                if res.has_custom_parser {
+                    abort!(
+                        res.parser.span(),
+                        "parse attribute is not allowed for subcommand"
+                    );
+                }
+                if res.has_explicit_methods() {
+                    abort!(
+                        res.kind.span(),
+                        "methods in attributes are not allowed for subcommand"
+                    );
+                }
+
+                let ty = Ty::from_syn_ty(&field.ty);
+                match *ty {
+                    Ty::OptionOption => {
+                        abort!(
+                            field.ty,
+                            "Option<Option<T>> type is not allowed for subcommand"
+                        );
+                    }
+                    Ty::OptionVec => {
+                        abort!(
+                            field.ty,
+                            "Option<Vec<T>> type is not allowed for subcommand"
+                        );
+                    }
+                    _ => (),
+                }
+
+                res.kind = Sp::new(Kind::Subcommand(ty), res.kind.span());
+            }
+            Kind::Skip(_) => {
+                if res.has_explicit_methods() {
+                    abort!(
+                        res.kind.span(),
+                        "methods are not allowed for skipped fields"
+                    );
+                }
+            }
+            Kind::Arg(orig_ty) => {
+                let mut ty = Ty::from_syn_ty(&field.ty);
+                if res.has_custom_parser {
+                    match *ty {
+                        Ty::Option | Ty::Vec | Ty::OptionVec => (),
+                        _ => ty = Sp::new(Ty::Other, ty.span()),
+                    }
+                }
+
+                match *ty {
+                    Ty::Bool => {
+                        if res.is_positional() && !res.has_custom_parser {
+                            abort!(field.ty,
+                                "`bool` cannot be used as positional parameter with default parser";
+                                help = "if you want to create a flag add `long` or `short`";
+                                help = "If you really want a boolean parameter \
+                                    add an explicit parser, for example `parse(try_from_str)`";
+                                note = "see also https://github.com/TeXitoi/structopt/tree/master/examples/true_or_false.rs";
+                            )
+                        }
+                        if let Some(m) = res.find_method("default_value") {
+                            abort!(m.name, "default_value is meaningless for bool")
+                        }
+                        if let Some(m) = res.find_method("required") {
+                            abort!(m.name, "required is meaningless for bool")
+                        }
+                    }
+                    Ty::Option => {
+                        if let Some(m) = res.find_method("default_value") {
+                            abort!(m.name, "default_value is meaningless for Option")
+                        }
+                        if let Some(m) = res.find_method("required") {
+                            abort!(m.name, "required is meaningless for Option")
+                        }
+                    }
+                    Ty::OptionOption => {
+                        if res.is_positional() {
+                            abort!(
+                                field.ty,
+                                "Option<Option<T>> type is meaningless for positional argument"
+                            )
+                        }
+                    }
+                    Ty::OptionVec => {
+                        if res.is_positional() {
+                            abort!(
+                                field.ty,
+                                "Option<Vec<T>> type is meaningless for positional argument"
+                            )
+                        }
+                    }
+
+                    _ => (),
+                }
+                res.kind = Sp::new(Kind::Arg(ty), orig_ty.span());
+            }
+        }
+
+        res
+    }
+
+    fn set_kind(&mut self, kind: Sp<Kind>) {
+        if let Kind::Arg(_) = *self.kind {
+            self.kind = kind;
+        } else {
+            abort!(
+                kind.span(),
+                "subcommand, flatten and skip cannot be used together"
+            );
+        }
+    }
+
+    pub fn has_method(&self, name: &str) -> bool {
+        self.find_method(name).is_some()
+    }
+
+    pub fn find_method(&self, name: &str) -> Option<&Method> {
+        self.methods.iter().find(|m| m.name == name)
+    }
+
+    /// generate methods from attributes on top of struct or enum
+    pub fn top_level_methods(&self) -> TokenStream {
+        let author = &self.author;
+        let about = &self.about;
+        let methods = &self.methods;
+        let doc_comment = &self.doc_comment;
+
+        quote!( #(#doc_comment)* #author #about #(#methods)*  )
+    }
+
+    /// generate methods on top of a field
+    pub fn field_methods(&self) -> TokenStream {
+        let methods = &self.methods;
+        let doc_comment = &self.doc_comment;
+        quote!( #(#doc_comment)* #(#methods)* )
+    }
+
+    pub fn version(&self) -> TokenStream {
+        match (&self.no_version, &self.version) {
+            (None, Some(m)) => m.to_token_stream(),
+
+            (None, None) => std::env::var("CARGO_PKG_VERSION")
+                .map(|version| quote!( .version(#version) ))
+                .unwrap_or_default(),
+
+            _ => quote!(),
+        }
+    }
+
+    pub fn cased_name(&self) -> TokenStream {
+        self.name.clone().translate(*self.casing)
+    }
+
+    pub fn parser(&self) -> &Sp<Parser> {
+        &self.parser
+    }
+
+    pub fn kind(&self) -> Sp<Kind> {
+        self.kind.clone()
+    }
+
+    pub fn casing(&self) -> Sp<CasingStyle> {
+        self.casing.clone()
+    }
+
+    pub fn env_casing(&self) -> Sp<CasingStyle> {
+        self.env_casing.clone()
+    }
+
+    pub fn is_positional(&self) -> bool {
+        self.methods
+            .iter()
+            .all(|m| m.name != "long" && m.name != "short")
+    }
+
+    pub fn has_explicit_methods(&self) -> bool {
+        self.methods
+            .iter()
+            .any(|m| m.name != "help" && m.name != "long_help")
+    }
+
+    pub fn has_doc_methods(&self) -> bool {
+        !self.doc_comment.is_empty()
+            || self.methods.iter().any(|m| {
+                m.name == "help"
+                    || m.name == "long_help"
+                    || m.name == "about"
+                    || m.name == "long_about"
+            })
+    }
+}
+
+/// replace all `:` with `, ` when not inside the `<>`
+///
+/// `"author1:author2:author3" => "author1, author2, author3"`
+/// `"author1 <http://website1.com>:author2" => "author1 <http://website1.com>, author2"
+fn process_author_str(author: &str) -> String {
+    let mut res = String::with_capacity(author.len());
+    let mut inside_angle_braces = 0usize;
+
+    for ch in author.chars() {
+        if inside_angle_braces > 0 && ch == '>' {
+            inside_angle_braces -= 1;
+            res.push(ch);
+        } else if ch == '<' {
+            inside_angle_braces += 1;
+            res.push(ch);
+        } else if inside_angle_braces == 0 && ch == ':' {
+            res.push_str(", ");
+        } else {
+            res.push(ch);
+        }
+    }
+
+    res
+}
diff --git a/src/doc_comments.rs b/src/doc_comments.rs
new file mode 100644
index 0000000..5592a1a
--- /dev/null
+++ b/src/doc_comments.rs
@@ -0,0 +1,103 @@
+//! The preprocessing we apply to doc comments.
+//!
+//! structopt works in terms of "paragraphs". Paragraph is a sequence of
+//! non-empty adjacent lines, delimited by sequences of blank (whitespace only) lines.
+
+use crate::attrs::Method;
+use quote::{format_ident, quote};
+use std::iter;
+
+pub fn process_doc_comment(lines: Vec<String>, name: &str, preprocess: bool) -> Vec<Method> {
+    // multiline comments (`/** ... */`) may have LFs (`\n`) in them,
+    // we need to split so we could handle the lines correctly
+    //
+    // we also need to remove leading and trailing blank lines
+    let mut lines: Vec<&str> = lines
+        .iter()
+        .skip_while(|s| is_blank(s))
+        .flat_map(|s| s.split('\n'))
+        .collect();
+
+    while let Some(true) = lines.last().map(|s| is_blank(s)) {
+        lines.pop();
+    }
+
+    // remove one leading space no matter what
+    for line in lines.iter_mut() {
+        if line.starts_with(' ') {
+            *line = &line[1..];
+        }
+    }
+
+    if lines.is_empty() {
+        return vec![];
+    }
+
+    let short_name = format_ident!("{}", name);
+    let long_name = format_ident!("long_{}", name);
+
+    if let Some(first_blank) = lines.iter().position(|s| is_blank(s)) {
+        let (short, long) = if preprocess {
+            let paragraphs = split_paragraphs(&lines);
+            let short = paragraphs[0].clone();
+            let long = paragraphs.join("\n\n");
+            (remove_period(short), long)
+        } else {
+            let short = lines[..first_blank].join("\n");
+            let long = lines.join("\n");
+            (short, long)
+        };
+
+        vec![
+            Method::new(short_name, quote!(#short)),
+            Method::new(long_name, quote!(#long)),
+        ]
+    } else {
+        let short = if preprocess {
+            let s = merge_lines(&lines);
+            remove_period(s)
+        } else {
+            lines.join("\n")
+        };
+
+        vec![Method::new(short_name, quote!(#short))]
+    }
+}
+
+fn split_paragraphs(lines: &[&str]) -> Vec<String> {
+    let mut last_line = 0;
+    iter::from_fn(|| {
+        let slice = &lines[last_line..];
+        let start = slice.iter().position(|s| !is_blank(s)).unwrap_or(0);
+
+        let slice = &slice[start..];
+        let len = slice
+            .iter()
+            .position(|s| is_blank(s))
+            .unwrap_or_else(|| slice.len());
+
+        last_line += start + len;
+
+        if len != 0 {
+            Some(merge_lines(&slice[..len]))
+        } else {
+            None
+        }
+    })
+    .collect()
+}
+
+fn remove_period(mut s: String) -> String {
+    if s.ends_with('.') && !s.ends_with("..") {
+        s.pop();
+    }
+    s
+}
+
+fn is_blank(s: &str) -> bool {
+    s.trim().is_empty()
+}
+
+fn merge_lines(lines: &[&str]) -> String {
+    lines.iter().map(|s| s.trim()).collect::<Vec<_>>().join(" ")
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..5e49468
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,874 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This crate is custom derive for `StructOpt`. It should not be used
+//! directly. See [structopt documentation](https://docs.rs/structopt)
+//! for the usage of `#[derive(StructOpt)]`.
+
+#![allow(clippy::large_enum_variant)]
+
+extern crate proc_macro;
+
+mod attrs;
+mod doc_comments;
+mod parse;
+mod spanned;
+mod ty;
+
+use crate::{
+    attrs::{Attrs, CasingStyle, Kind, Name, ParserKind},
+    spanned::Sp,
+    ty::{is_simple_ty, sub_type, subty_if_name, Ty},
+};
+
+use proc_macro2::{Span, TokenStream};
+use proc_macro_error::{abort, abort_call_site, proc_macro_error, set_dummy};
+use quote::{quote, quote_spanned};
+use syn::{punctuated::Punctuated, spanned::Spanned, token::Comma, *};
+
+/// Default casing style for generated arguments.
+const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;
+
+/// Default casing style for environment variables
+const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake;
+
+/// Output for the `gen_xxx()` methods were we need more than a simple stream of tokens.
+///
+/// The output of a generation method is not only the stream of new tokens but also the attribute
+/// information of the current element. These attribute information may contain valuable information
+/// for any kind of child arguments.
+struct GenOutput {
+    tokens: TokenStream,
+    attrs: Attrs,
+}
+
+/// Generates the `StructOpt` impl.
+#[proc_macro_derive(StructOpt, attributes(structopt))]
+#[proc_macro_error]
+pub fn structopt(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    let input: DeriveInput = syn::parse(input).unwrap();
+    let gen = impl_structopt(&input);
+    gen.into()
+}
+
+/// Generate a block of code to add arguments/subcommands corresponding to
+/// the `fields` to an app.
+fn gen_augmentation(
+    fields: &Punctuated<Field, Comma>,
+    app_var: &Ident,
+    parent_attribute: &Attrs,
+) -> TokenStream {
+    let mut subcmds = fields.iter().filter_map(|field| {
+        let attrs = Attrs::from_field(
+            field,
+            Some(parent_attribute),
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
+        let kind = attrs.kind();
+        if let Kind::Subcommand(ty) = &*kind {
+            let subcmd_type = match (**ty, sub_type(&field.ty)) {
+                (Ty::Option, Some(sub_type)) => sub_type,
+                _ => &field.ty,
+            };
+            let required = if **ty == Ty::Option {
+                quote!()
+            } else {
+                quote_spanned! { kind.span()=>
+                    let #app_var = #app_var.setting(
+                        ::structopt::clap::AppSettings::SubcommandRequiredElseHelp
+                    );
+                }
+            };
+
+            let span = field.span();
+            let ts = quote! {
+                let #app_var = <#subcmd_type as ::structopt::StructOptInternal>::augment_clap(
+                    #app_var
+                );
+                #required
+            };
+            Some((span, ts))
+        } else {
+            None
+        }
+    });
+
+    let subcmd = subcmds.next().map(|(_, ts)| ts);
+    if let Some((span, _)) = subcmds.next() {
+        abort!(
+            span,
+            "multiple subcommand sets are not allowed, that's the second"
+        );
+    }
+
+    let args = fields.iter().filter_map(|field| {
+        let attrs = Attrs::from_field(
+            field,
+            Some(parent_attribute),
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
+        let kind = attrs.kind();
+        match &*kind {
+            Kind::ExternalSubcommand => abort!(
+                kind.span(),
+                "`external_subcommand` is only allowed on enum variants"
+            ),
+            Kind::Subcommand(_) | Kind::Skip(_) => None,
+            Kind::Flatten => {
+                let ty = &field.ty;
+                Some(quote_spanned! { kind.span()=>
+                    let #app_var = <#ty as ::structopt::StructOptInternal>::augment_clap(#app_var);
+                    let #app_var = if <#ty as ::structopt::StructOptInternal>::is_subcommand() {
+                        #app_var.setting(::structopt::clap::AppSettings::SubcommandRequiredElseHelp)
+                    } else {
+                        #app_var
+                    };
+                })
+            }
+            Kind::Arg(ty) => {
+                let convert_type = match **ty {
+                    Ty::Vec | Ty::Option => sub_type(&field.ty).unwrap_or(&field.ty),
+                    Ty::OptionOption | Ty::OptionVec => {
+                        sub_type(&field.ty).and_then(sub_type).unwrap_or(&field.ty)
+                    }
+                    _ => &field.ty,
+                };
+
+                let occurrences = *attrs.parser().kind == ParserKind::FromOccurrences;
+                let flag = *attrs.parser().kind == ParserKind::FromFlag;
+
+                let parser = attrs.parser();
+                let func = &parser.func;
+                let validator = match *parser.kind {
+                    ParserKind::TryFromStr => quote_spanned! { func.span()=>
+                        .validator(|s| {
+                            #func(s.as_str())
+                            .map(|_: #convert_type| ())
+                            .map_err(|e| e.to_string())
+                        })
+                    },
+                    ParserKind::TryFromOsStr => quote_spanned! { func.span()=>
+                        .validator_os(|s| #func(&s).map(|_: #convert_type| ()))
+                    },
+                    _ => quote!(),
+                };
+
+                let modifier = match **ty {
+                    Ty::Bool => quote_spanned! { ty.span()=>
+                        .takes_value(false)
+                        .multiple(false)
+                    },
+
+                    Ty::Option => quote_spanned! { ty.span()=>
+                        .takes_value(true)
+                        .multiple(false)
+                        #validator
+                    },
+
+                    Ty::OptionOption => quote_spanned! { ty.span()=>
+                            .takes_value(true)
+                            .multiple(false)
+                            .min_values(0)
+                            .max_values(1)
+                            #validator
+                    },
+
+                    Ty::OptionVec => quote_spanned! { ty.span()=>
+                        .takes_value(true)
+                        .multiple(true)
+                        .min_values(0)
+                        #validator
+                    },
+
+                    Ty::Vec => quote_spanned! { ty.span()=>
+                        .takes_value(true)
+                        .multiple(true)
+                        #validator
+                    },
+
+                    Ty::Other if occurrences => quote_spanned! { ty.span()=>
+                        .takes_value(false)
+                        .multiple(true)
+                    },
+
+                    Ty::Other if flag => quote_spanned! { ty.span()=>
+                        .takes_value(false)
+                        .multiple(false)
+                    },
+
+                    Ty::Other => {
+                        let required = !attrs.has_method("default_value");
+                        quote_spanned! { ty.span()=>
+                            .takes_value(true)
+                            .multiple(false)
+                            .required(#required)
+                            #validator
+                        }
+                    }
+                };
+
+                let name = attrs.cased_name();
+                let methods = attrs.field_methods();
+
+                Some(quote_spanned! { field.span()=>
+                    let #app_var = #app_var.arg(
+                        ::structopt::clap::Arg::with_name(#name)
+                            #modifier
+                            #methods
+                    );
+                })
+            }
+        }
+    });
+
+    let app_methods = parent_attribute.top_level_methods();
+    let version = parent_attribute.version();
+    quote! {{
+        let #app_var = #app_var#app_methods;
+        #( #args )*
+        #subcmd
+        #app_var#version
+    }}
+}
+
+fn gen_constructor(fields: &Punctuated<Field, Comma>, parent_attribute: &Attrs) -> TokenStream {
+    let fields = fields.iter().map(|field| {
+        let attrs = Attrs::from_field(
+            field,
+            Some(parent_attribute),
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
+        let field_name = field.ident.as_ref().unwrap();
+        let kind = attrs.kind();
+        match &*kind {
+            Kind::ExternalSubcommand => abort!(
+                kind.span(),
+                "`external_subcommand` is allowed only on enum variants"
+            ),
+
+            Kind::Subcommand(ty) => {
+                let subcmd_type = match (**ty, sub_type(&field.ty)) {
+                    (Ty::Option, Some(sub_type)) => sub_type,
+                    _ => &field.ty,
+                };
+                let unwrapper = match **ty {
+                    Ty::Option => quote!(),
+                    _ => quote_spanned!( ty.span()=> .unwrap() ),
+                };
+                quote_spanned! { kind.span()=>
+                    #field_name: <#subcmd_type as ::structopt::StructOptInternal>::from_subcommand(
+                        matches.subcommand())
+                        #unwrapper
+                }
+            }
+
+            Kind::Flatten => quote_spanned! { kind.span()=>
+                #field_name: ::structopt::StructOpt::from_clap(matches)
+            },
+
+            Kind::Skip(val) => match val {
+                None => quote_spanned!(kind.span()=> #field_name: Default::default()),
+                Some(val) => quote_spanned!(kind.span()=> #field_name: (#val).into()),
+            },
+
+            Kind::Arg(ty) => {
+                use crate::attrs::ParserKind::*;
+
+                let parser = attrs.parser();
+                let func = &parser.func;
+                let span = parser.kind.span();
+                let (value_of, values_of, parse) = match *parser.kind {
+                    FromStr => (
+                        quote_spanned!(span=> value_of),
+                        quote_spanned!(span=> values_of),
+                        func.clone(),
+                    ),
+                    TryFromStr => (
+                        quote_spanned!(span=> value_of),
+                        quote_spanned!(span=> values_of),
+                        quote_spanned!(func.span()=> |s| #func(s).unwrap()),
+                    ),
+                    FromOsStr => (
+                        quote_spanned!(span=> value_of_os),
+                        quote_spanned!(span=> values_of_os),
+                        func.clone(),
+                    ),
+                    TryFromOsStr => (
+                        quote_spanned!(span=> value_of_os),
+                        quote_spanned!(span=> values_of_os),
+                        quote_spanned!(func.span()=> |s| #func(s).unwrap()),
+                    ),
+                    FromOccurrences => (
+                        quote_spanned!(span=> occurrences_of),
+                        quote!(),
+                        func.clone(),
+                    ),
+                    FromFlag => (quote!(), quote!(), func.clone()),
+                };
+
+                let flag = *attrs.parser().kind == ParserKind::FromFlag;
+                let occurrences = *attrs.parser().kind == ParserKind::FromOccurrences;
+                let name = attrs.cased_name();
+                let field_value = match **ty {
+                    Ty::Bool => quote_spanned!(ty.span()=> matches.is_present(#name)),
+
+                    Ty::Option => quote_spanned! { ty.span()=>
+                        matches.#value_of(#name)
+                            .map(#parse)
+                    },
+
+                    Ty::OptionOption => quote_spanned! { ty.span()=>
+                        if matches.is_present(#name) {
+                            Some(matches.#value_of(#name).map(#parse))
+                        } else {
+                            None
+                        }
+                    },
+
+                    Ty::OptionVec => quote_spanned! { ty.span()=>
+                        if matches.is_present(#name) {
+                            Some(matches.#values_of(#name)
+                                 .map_or_else(Vec::new, |v| v.map(#parse).collect()))
+                        } else {
+                            None
+                        }
+                    },
+
+                    Ty::Vec => quote_spanned! { ty.span()=>
+                        matches.#values_of(#name)
+                            .map_or_else(Vec::new, |v| v.map(#parse).collect())
+                    },
+
+                    Ty::Other if occurrences => quote_spanned! { ty.span()=>
+                        #parse(matches.#value_of(#name))
+                    },
+
+                    Ty::Other if flag => quote_spanned! { ty.span()=>
+                        #parse(matches.is_present(#name))
+                    },
+
+                    Ty::Other => quote_spanned! { ty.span()=>
+                        matches.#value_of(#name)
+                            .map(#parse)
+                            .unwrap()
+                    },
+                };
+
+                quote_spanned!(field.span()=> #field_name: #field_value )
+            }
+        }
+    });
+
+    quote! {{
+        #( #fields ),*
+    }}
+}
+
+fn gen_from_clap(
+    struct_name: &Ident,
+    fields: &Punctuated<Field, Comma>,
+    parent_attribute: &Attrs,
+) -> TokenStream {
+    let field_block = gen_constructor(fields, parent_attribute);
+
+    quote! {
+        fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self {
+            #struct_name #field_block
+        }
+    }
+}
+
+fn gen_clap(attrs: &[Attribute]) -> GenOutput {
+    let name = std::env::var("CARGO_PKG_NAME").ok().unwrap_or_default();
+
+    let attrs = Attrs::from_struct(
+        Span::call_site(),
+        attrs,
+        Name::Assigned(quote!(#name)),
+        None,
+        Sp::call_site(DEFAULT_CASING),
+        Sp::call_site(DEFAULT_ENV_CASING),
+    );
+    let tokens = {
+        let name = attrs.cased_name();
+        quote!(::structopt::clap::App::new(#name))
+    };
+
+    GenOutput { tokens, attrs }
+}
+
+fn gen_clap_struct(struct_attrs: &[Attribute]) -> GenOutput {
+    let initial_clap_app_gen = gen_clap(struct_attrs);
+    let clap_tokens = initial_clap_app_gen.tokens;
+
+    let augmented_tokens = quote! {
+        fn clap<'a, 'b>() -> ::structopt::clap::App<'a, 'b> {
+            let app = #clap_tokens;
+            <Self as ::structopt::StructOptInternal>::augment_clap(app)
+        }
+    };
+
+    GenOutput {
+        tokens: augmented_tokens,
+        attrs: initial_clap_app_gen.attrs,
+    }
+}
+
+fn gen_augment_clap(fields: &Punctuated<Field, Comma>, parent_attribute: &Attrs) -> TokenStream {
+    let app_var = Ident::new("app", Span::call_site());
+    let augmentation = gen_augmentation(fields, &app_var, parent_attribute);
+    quote! {
+        fn augment_clap<'a, 'b>(
+            #app_var: ::structopt::clap::App<'a, 'b>
+        ) -> ::structopt::clap::App<'a, 'b> {
+            #augmentation
+        }
+    }
+}
+
+fn gen_clap_enum(enum_attrs: &[Attribute]) -> GenOutput {
+    let initial_clap_app_gen = gen_clap(enum_attrs);
+    let clap_tokens = initial_clap_app_gen.tokens;
+
+    let tokens = quote! {
+        fn clap<'a, 'b>() -> ::structopt::clap::App<'a, 'b> {
+            let app = #clap_tokens
+                .setting(::structopt::clap::AppSettings::SubcommandRequiredElseHelp);
+            <Self as ::structopt::StructOptInternal>::augment_clap(app)
+        }
+    };
+
+    GenOutput {
+        tokens,
+        attrs: initial_clap_app_gen.attrs,
+    }
+}
+
+fn gen_augment_clap_enum(
+    variants: &Punctuated<Variant, Comma>,
+    parent_attribute: &Attrs,
+) -> TokenStream {
+    use syn::Fields::*;
+
+    let subcommands = variants.iter().map(|variant| {
+        let attrs = Attrs::from_struct(
+            variant.span(),
+            &variant.attrs,
+            Name::Derived(variant.ident.clone()),
+            Some(parent_attribute),
+            parent_attribute.casing(),
+            parent_attribute.env_casing(),
+        );
+
+        let kind = attrs.kind();
+        match &*kind {
+            Kind::ExternalSubcommand => {
+                quote_spanned! { attrs.kind().span()=>
+                    let app = app.setting(
+                        ::structopt::clap::AppSettings::AllowExternalSubcommands
+                    );
+                }
+            },
+
+            Kind::Flatten => {
+                match variant.fields {
+                    Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
+                        let ty = &unnamed[0];
+                        quote! {
+                            let app = <#ty as ::structopt::StructOptInternal>::augment_clap(app);
+                        }
+                    },
+                    _ => abort!(
+                        variant,
+                        "`flatten` is usable only with single-typed tuple variants"
+                    ),
+                }
+            },
+
+            _ => {
+                let app_var = Ident::new("subcommand", Span::call_site());
+                let arg_block = match variant.fields {
+                    Named(ref fields) => gen_augmentation(&fields.named, &app_var, &attrs),
+                    Unit => quote!( #app_var ),
+                    Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
+                        let ty = &unnamed[0];
+                        quote_spanned! { ty.span()=>
+                            {
+                                let #app_var = <#ty as ::structopt::StructOptInternal>::augment_clap(
+                                    #app_var
+                                );
+                                if <#ty as ::structopt::StructOptInternal>::is_subcommand() {
+                                    #app_var.setting(
+                                        ::structopt::clap::AppSettings::SubcommandRequiredElseHelp
+                                    )
+                                } else {
+                                    #app_var
+                                }
+                            }
+                        }
+                    }
+                    Unnamed(..) => abort!(variant, "non single-typed tuple enums are not supported"),
+                };
+
+                let name = attrs.cased_name();
+                let from_attrs = attrs.top_level_methods();
+                let version = attrs.version();
+                quote! {
+                    let app = app.subcommand({
+                        let #app_var = ::structopt::clap::SubCommand::with_name(#name);
+                        let #app_var = #arg_block;
+                        #app_var#from_attrs#version
+                    });
+                }
+            },
+        }
+    });
+
+    let app_methods = parent_attribute.top_level_methods();
+    let version = parent_attribute.version();
+    quote! {
+        fn augment_clap<'a, 'b>(
+            app: ::structopt::clap::App<'a, 'b>
+        ) -> ::structopt::clap::App<'a, 'b> {
+            let app = app #app_methods;
+            #( #subcommands )*;
+            app #version
+        }
+    }
+}
+
+fn gen_from_clap_enum(name: &Ident) -> TokenStream {
+    quote! {
+        fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self {
+            <#name as ::structopt::StructOptInternal>::from_subcommand(matches.subcommand())
+                .unwrap()
+        }
+    }
+}
+
+fn gen_from_subcommand(
+    name: &Ident,
+    variants: &Punctuated<Variant, Comma>,
+    parent_attribute: &Attrs,
+) -> TokenStream {
+    use syn::Fields::*;
+
+    let mut ext_subcmd = None;
+
+    let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
+        .iter()
+        .filter_map(|variant| {
+            let attrs = Attrs::from_struct(
+                variant.span(),
+                &variant.attrs,
+                Name::Derived(variant.ident.clone()),
+                Some(parent_attribute),
+                parent_attribute.casing(),
+                parent_attribute.env_casing(),
+            );
+
+            let variant_name = &variant.ident;
+
+            if let Kind::ExternalSubcommand = *attrs.kind() {
+                if ext_subcmd.is_some() {
+                    abort!(
+                        attrs.kind().span(),
+                        "Only one variant can be marked with `external_subcommand`, \
+                         this is the second"
+                    );
+                }
+
+                let ty = match variant.fields {
+                    Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
+
+                    _ => abort!(
+                        variant,
+                        "The enum variant marked with `external_attribute` must be \
+                         a single-typed tuple, and the type must be either `Vec<String>` \
+                         or `Vec<OsString>`."
+                    ),
+                };
+
+                let (span, str_ty, values_of) = match subty_if_name(ty, "Vec") {
+                    Some(subty) => {
+                        if is_simple_ty(subty, "String") {
+                            (
+                                subty.span(),
+                                quote!(::std::string::String),
+                                quote!(values_of),
+                            )
+                        } else {
+                            (
+                                subty.span(),
+                                quote!(::std::ffi::OsString),
+                                quote!(values_of_os),
+                            )
+                        }
+                    }
+
+                    None => abort!(
+                        ty,
+                        "The type must be either `Vec<String>` or `Vec<OsString>` \
+                         to be used with `external_subcommand`."
+                    ),
+                };
+
+                ext_subcmd = Some((span, variant_name, str_ty, values_of));
+                None
+            } else {
+                Some((variant, attrs))
+            }
+        })
+        .partition(|(_, attrs)| match &*attrs.kind() {
+            Kind::Flatten => true,
+            _ => false,
+        });
+
+    let external = match ext_subcmd {
+        Some((span, var_name, str_ty, values_of)) => quote_spanned! { span=>
+            match other {
+                ("", ::std::option::Option::None) => None,
+
+                (external, Some(matches)) => {
+                    ::std::option::Option::Some(#name::#var_name(
+                        ::std::iter::once(#str_ty::from(external))
+                        .chain(
+                            matches.#values_of("").into_iter().flatten().map(#str_ty::from)
+                        )
+                        .collect::<::std::vec::Vec<_>>()
+                    ))
+                }
+
+                (external, None) => {
+                    ::std::option::Option::Some(#name::#var_name({
+                        ::std::iter::once(#str_ty::from(external))
+                            .collect::<::std::vec::Vec<_>>()
+                    }))
+                }
+            }
+        },
+
+        None => quote!(None),
+    };
+
+    let match_arms = variants.iter().map(|(variant, attrs)| {
+        let sub_name = attrs.cased_name();
+        let variant_name = &variant.ident;
+        let constructor_block = match variant.fields {
+            Named(ref fields) => gen_constructor(&fields.named, &attrs),
+            Unit => quote!(),
+            Unnamed(ref fields) if fields.unnamed.len() == 1 => {
+                let ty = &fields.unnamed[0];
+                quote!( ( <#ty as ::structopt::StructOpt>::from_clap(matches) ) )
+            }
+            Unnamed(..) => abort!(
+                variant.ident,
+                "non single-typed tuple enums are not supported"
+            ),
+        };
+
+        quote! {
+            (#sub_name, Some(matches)) => {
+                Some(#name :: #variant_name #constructor_block)
+            }
+        }
+    });
+
+    let child_subcommands = flatten_variants.iter().map(|(variant, _attrs)| {
+        let variant_name = &variant.ident;
+        match variant.fields {
+            Unnamed(ref fields) if fields.unnamed.len() == 1 => {
+                let ty = &fields.unnamed[0];
+                quote! {
+                    if let Some(res) =
+                        <#ty as ::structopt::StructOptInternal>::from_subcommand(other)
+                    {
+                        return Some(#name :: #variant_name (res));
+                    }
+                }
+            }
+            _ => abort!(
+                variant,
+                "`flatten` is usable only with single-typed tuple variants"
+            ),
+        }
+    });
+
+    quote! {
+        fn from_subcommand<'a, 'b>(
+            sub: (&'b str, Option<&'b ::structopt::clap::ArgMatches<'a>>)
+        ) -> Option<Self> {
+            match sub {
+                #( #match_arms, )*
+                other => {
+                    #( #child_subcommands )else*;
+                    #external
+                }
+            }
+        }
+    }
+}
+
+#[cfg(feature = "paw")]
+fn gen_paw_impl(name: &Ident) -> TokenStream {
+    quote! {
+        impl paw::ParseArgs for #name {
+            type Error = std::io::Error;
+
+            fn parse_args() -> std::result::Result<Self, Self::Error> {
+                Ok(<#name as ::structopt::StructOpt>::from_args())
+            }
+        }
+    }
+}
+#[cfg(not(feature = "paw"))]
+fn gen_paw_impl(_: &Ident) -> TokenStream {
+    TokenStream::new()
+}
+
+fn impl_structopt_for_struct(
+    name: &Ident,
+    fields: &Punctuated<Field, Comma>,
+    attrs: &[Attribute],
+) -> TokenStream {
+    let basic_clap_app_gen = gen_clap_struct(attrs);
+    let augment_clap = gen_augment_clap(fields, &basic_clap_app_gen.attrs);
+    let from_clap = gen_from_clap(name, fields, &basic_clap_app_gen.attrs);
+    let paw_impl = gen_paw_impl(name);
+
+    let clap_tokens = basic_clap_app_gen.tokens;
+    quote! {
+        #[allow(unused_variables)]
+        #[allow(unknown_lints)]
+        #[allow(
+            clippy::style,
+            clippy::complexity,
+            clippy::pedantic,
+            clippy::restriction,
+            clippy::perf,
+            clippy::deprecated,
+            clippy::nursery,
+            clippy::cargo
+        )]
+        #[deny(clippy::correctness)]
+        #[allow(dead_code, unreachable_code)]
+        impl ::structopt::StructOpt for #name {
+            #clap_tokens
+            #from_clap
+        }
+
+        #[allow(unused_variables)]
+        #[allow(unknown_lints)]
+        #[allow(
+            clippy::style,
+            clippy::complexity,
+            clippy::pedantic,
+            clippy::restriction,
+            clippy::perf,
+            clippy::deprecated,
+            clippy::nursery,
+            clippy::cargo
+        )]
+        #[deny(clippy::correctness)]
+        #[allow(dead_code, unreachable_code)]
+        impl ::structopt::StructOptInternal for #name {
+            #augment_clap
+            fn is_subcommand() -> bool { false }
+        }
+
+        #paw_impl
+    }
+}
+
+fn impl_structopt_for_enum(
+    name: &Ident,
+    variants: &Punctuated<Variant, Comma>,
+    attrs: &[Attribute],
+) -> TokenStream {
+    let basic_clap_app_gen = gen_clap_enum(attrs);
+    let clap_tokens = basic_clap_app_gen.tokens;
+    let attrs = basic_clap_app_gen.attrs;
+
+    let augment_clap = gen_augment_clap_enum(variants, &attrs);
+    let from_clap = gen_from_clap_enum(name);
+    let from_subcommand = gen_from_subcommand(name, variants, &attrs);
+    let paw_impl = gen_paw_impl(name);
+
+    quote! {
+        #[allow(unknown_lints)]
+        #[allow(unused_variables, dead_code, unreachable_code)]
+        #[allow(
+            clippy::style,
+            clippy::complexity,
+            clippy::pedantic,
+            clippy::restriction,
+            clippy::perf,
+            clippy::deprecated,
+            clippy::nursery,
+            clippy::cargo
+        )]
+        #[deny(clippy::correctness)]
+        impl ::structopt::StructOpt for #name {
+            #clap_tokens
+            #from_clap
+        }
+
+        #[allow(unused_variables)]
+        #[allow(unknown_lints)]
+        #[allow(
+            clippy::style,
+            clippy::complexity,
+            clippy::pedantic,
+            clippy::restriction,
+            clippy::perf,
+            clippy::deprecated,
+            clippy::nursery,
+            clippy::cargo
+        )]
+        #[deny(clippy::correctness)]
+        #[allow(dead_code, unreachable_code)]
+        impl ::structopt::StructOptInternal for #name {
+            #augment_clap
+            #from_subcommand
+            fn is_subcommand() -> bool { true }
+        }
+
+        #paw_impl
+    }
+}
+
+fn impl_structopt(input: &DeriveInput) -> TokenStream {
+    use syn::Data::*;
+
+    let struct_name = &input.ident;
+
+    set_dummy(quote! {
+        impl ::structopt::StructOpt for #struct_name {
+            fn clap<'a, 'b>() -> ::structopt::clap::App<'a, 'b> {
+                unimplemented!()
+            }
+            fn from_clap(_matches: &::structopt::clap::ArgMatches) -> Self {
+                unimplemented!()
+            }
+        }
+
+        impl ::structopt::StructOptInternal for #struct_name {}
+    });
+
+    match input.data {
+        Struct(DataStruct {
+            fields: syn::Fields::Named(ref fields),
+            ..
+        }) => impl_structopt_for_struct(struct_name, &fields.named, &input.attrs),
+        Enum(ref e) => impl_structopt_for_enum(struct_name, &e.variants, &input.attrs),
+        _ => abort_call_site!("structopt only supports non-tuple structs and enums"),
+    }
+}
diff --git a/src/parse.rs b/src/parse.rs
new file mode 100644
index 0000000..11511a1
--- /dev/null
+++ b/src/parse.rs
@@ -0,0 +1,272 @@
+use std::iter::FromIterator;
+
+use proc_macro_error::{abort, ResultExt};
+use quote::ToTokens;
+use syn::{
+    self, parenthesized,
+    parse::{Parse, ParseBuffer, ParseStream},
+    punctuated::Punctuated,
+    Attribute, Expr, ExprLit, Ident, Lit, LitBool, LitStr, Token,
+};
+
+pub enum StructOptAttr {
+    // single-identifier attributes
+    Short(Ident),
+    Long(Ident),
+    Env(Ident),
+    Flatten(Ident),
+    Subcommand(Ident),
+    ExternalSubcommand(Ident),
+    NoVersion(Ident),
+    VerbatimDocComment(Ident),
+
+    // ident [= "string literal"]
+    About(Ident, Option<LitStr>),
+    Author(Ident, Option<LitStr>),
+    DefaultValue(Ident, Option<LitStr>),
+
+    // ident = "string literal"
+    Version(Ident, LitStr),
+    RenameAllEnv(Ident, LitStr),
+    RenameAll(Ident, LitStr),
+    NameLitStr(Ident, LitStr),
+
+    // parse(parser_kind [= parser_func])
+    Parse(Ident, ParserSpec),
+
+    // ident [= arbitrary_expr]
+    Skip(Ident, Option<Expr>),
+
+    // ident = arbitrary_expr
+    NameExpr(Ident, Expr),
+
+    // ident(arbitrary_expr,*)
+    MethodCall(Ident, Vec<Expr>),
+}
+
+impl Parse for StructOptAttr {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        use self::StructOptAttr::*;
+
+        let name: Ident = input.parse()?;
+        let name_str = name.to_string();
+
+        if input.peek(Token![=]) {
+            // `name = value` attributes.
+            let assign_token = input.parse::<Token![=]>()?; // skip '='
+
+            if input.peek(LitStr) {
+                let lit: LitStr = input.parse()?;
+                let lit_str = lit.value();
+
+                let check_empty_lit = |s| {
+                    if lit_str.is_empty() {
+                        abort!(
+                            lit,
+                            "`#[structopt({} = \"\")]` is deprecated in structopt 0.3, \
+                             now it's default behavior",
+                            s
+                        );
+                    }
+                };
+
+                match &*name_str {
+                    "rename_all" => Ok(RenameAll(name, lit)),
+                    "rename_all_env" => Ok(RenameAllEnv(name, lit)),
+                    "default_value" => Ok(DefaultValue(name, Some(lit))),
+
+                    "version" => {
+                        check_empty_lit("version");
+                        Ok(Version(name, lit))
+                    }
+
+                    "author" => {
+                        check_empty_lit("author");
+                        Ok(Author(name, Some(lit)))
+                    }
+
+                    "about" => {
+                        check_empty_lit("about");
+                        Ok(About(name, Some(lit)))
+                    }
+
+                    "skip" => {
+                        let expr = ExprLit {
+                            attrs: vec![],
+                            lit: Lit::Str(lit),
+                        };
+                        let expr = Expr::Lit(expr);
+                        Ok(Skip(name, Some(expr)))
+                    }
+
+                    _ => Ok(NameLitStr(name, lit)),
+                }
+            } else {
+                match input.parse::<Expr>() {
+                    Ok(expr) => {
+                        if name_str == "skip" {
+                            Ok(Skip(name, Some(expr)))
+                        } else {
+                            Ok(NameExpr(name, expr))
+                        }
+                    }
+
+                    Err(_) => abort! {
+                        assign_token,
+                        "expected `string literal` or `expression` after `=`"
+                    },
+                }
+            }
+        } else if input.peek(syn::token::Paren) {
+            // `name(...)` attributes.
+            let nested;
+            parenthesized!(nested in input);
+
+            match name_str.as_ref() {
+                "parse" => {
+                    let parser_specs: Punctuated<ParserSpec, Token![,]> =
+                        nested.parse_terminated(ParserSpec::parse)?;
+
+                    if parser_specs.len() == 1 {
+                        Ok(Parse(name, parser_specs[0].clone()))
+                    } else {
+                        abort!(name, "`parse` must have exactly one argument")
+                    }
+                }
+
+                "raw" => match nested.parse::<LitBool>() {
+                    Ok(bool_token) => {
+                        let expr = ExprLit {
+                            attrs: vec![],
+                            lit: Lit::Bool(bool_token),
+                        };
+                        let expr = Expr::Lit(expr);
+                        Ok(MethodCall(name, vec![expr]))
+                    }
+
+                    Err(_) => {
+                        abort!(name,
+                            "`#[structopt(raw(...))` attributes are removed in structopt 0.3, \
+                            they are replaced with raw methods";
+                            help = "if you meant to call `clap::Arg::raw()` method \
+                                you should use bool literal, like `raw(true)` or `raw(false)`";
+                            note = raw_method_suggestion(nested);
+                        );
+                    }
+                },
+
+                _ => {
+                    let method_args: Punctuated<_, Token![,]> =
+                        nested.parse_terminated(Expr::parse)?;
+                    Ok(MethodCall(name, Vec::from_iter(method_args)))
+                }
+            }
+        } else {
+            // Attributes represented with a sole identifier.
+            match name_str.as_ref() {
+                "long" => Ok(Long(name)),
+                "short" => Ok(Short(name)),
+                "env" => Ok(Env(name)),
+                "flatten" => Ok(Flatten(name)),
+                "subcommand" => Ok(Subcommand(name)),
+                "external_subcommand" => Ok(ExternalSubcommand(name)),
+                "no_version" => Ok(NoVersion(name)),
+                "verbatim_doc_comment" => Ok(VerbatimDocComment(name)),
+
+                "default_value" => Ok(DefaultValue(name, None)),
+                "about" => (Ok(About(name, None))),
+                "author" => (Ok(Author(name, None))),
+
+                "skip" => Ok(Skip(name, None)),
+
+                "version" => abort!(
+                    name,
+                    "#[structopt(version)] is invalid attribute, \
+                     structopt 0.3 inherits version from Cargo.toml by default, \
+                     no attribute needed"
+                ),
+
+                _ => abort!(name, "unexpected attribute: {}", name_str),
+            }
+        }
+    }
+}
+
+#[derive(Clone)]
+pub struct ParserSpec {
+    pub kind: Ident,
+    pub eq_token: Option<Token![=]>,
+    pub parse_func: Option<Expr>,
+}
+
+impl Parse for ParserSpec {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        let kind = input
+            .parse()
+            .map_err(|_| input.error("parser specification must start with identifier"))?;
+        let eq_token = input.parse()?;
+        let parse_func = match eq_token {
+            None => None,
+            Some(_) => Some(input.parse()?),
+        };
+        Ok(ParserSpec {
+            kind,
+            eq_token,
+            parse_func,
+        })
+    }
+}
+
+fn raw_method_suggestion(ts: ParseBuffer) -> String {
+    let do_parse = move || -> Result<(Ident, Punctuated<Expr, Token![,]>), syn::Error> {
+        let name = ts.parse()?;
+        let _eq: Token![=] = ts.parse()?;
+        let val: LitStr = ts.parse()?;
+        let exprs = val.parse_with(Punctuated::<Expr, Token![,]>::parse_terminated)?;
+        Ok((name, exprs))
+    };
+
+    fn to_string<T: ToTokens>(val: &T) -> String {
+        val.to_token_stream()
+            .to_string()
+            .replace(" ", "")
+            .replace(",", ", ")
+    }
+
+    if let Ok((name, exprs)) = do_parse() {
+        let suggestion = if exprs.len() == 1 {
+            let val = to_string(&exprs[0]);
+            format!(" = {}", val)
+        } else {
+            let val = exprs
+                .into_iter()
+                .map(|expr| to_string(&expr))
+                .collect::<Vec<_>>()
+                .join(", ");
+
+            format!("({})", val)
+        };
+
+        format!(
+            "if you need to call `clap::Arg/App::{}` method you \
+             can do it like this: #[structopt({}{})]",
+            name, name, suggestion
+        )
+    } else {
+        "if you need to call some method from `clap::Arg/App` \
+         you should use raw method, see \
+         https://docs.rs/structopt/0.3/structopt/#raw-methods"
+            .into()
+    }
+}
+
+pub fn parse_structopt_attributes(all_attrs: &[Attribute]) -> Vec<StructOptAttr> {
+    all_attrs
+        .iter()
+        .filter(|attr| attr.path.is_ident("structopt"))
+        .flat_map(|attr| {
+            attr.parse_args_with(Punctuated::<StructOptAttr, Token![,]>::parse_terminated)
+                .unwrap_or_abort()
+        })
+        .collect()
+}
diff --git a/src/spanned.rs b/src/spanned.rs
new file mode 100644
index 0000000..19dbe47
--- /dev/null
+++ b/src/spanned.rs
@@ -0,0 +1,97 @@
+use proc_macro2::{Ident, Span, TokenStream};
+use quote::ToTokens;
+use std::ops::{Deref, DerefMut};
+use syn::LitStr;
+
+/// An entity with a span attached.
+#[derive(Debug, Clone)]
+pub struct Sp<T> {
+    span: Span,
+    val: T,
+}
+
+impl<T> Sp<T> {
+    pub fn new(val: T, span: Span) -> Self {
+        Sp { val, span }
+    }
+
+    pub fn call_site(val: T) -> Self {
+        Sp {
+            val,
+            span: Span::call_site(),
+        }
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+}
+
+impl<T> Deref for Sp<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.val
+    }
+}
+
+impl<T> DerefMut for Sp<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.val
+    }
+}
+
+impl From<Ident> for Sp<String> {
+    fn from(ident: Ident) -> Self {
+        Sp {
+            val: ident.to_string(),
+            span: ident.span(),
+        }
+    }
+}
+
+impl From<LitStr> for Sp<String> {
+    fn from(lit: LitStr) -> Self {
+        Sp {
+            val: lit.value(),
+            span: lit.span(),
+        }
+    }
+}
+
+impl<'a> From<Sp<&'a str>> for Sp<String> {
+    fn from(sp: Sp<&'a str>) -> Self {
+        Sp::new(sp.val.into(), sp.span)
+    }
+}
+
+impl<T: PartialEq> PartialEq<T> for Sp<T> {
+    fn eq(&self, other: &T) -> bool {
+        self.val == *other
+    }
+}
+
+impl<T: PartialEq> PartialEq for Sp<T> {
+    fn eq(&self, other: &Sp<T>) -> bool {
+        self.val == **other
+    }
+}
+
+impl<T: AsRef<str>> AsRef<str> for Sp<T> {
+    fn as_ref(&self) -> &str {
+        self.val.as_ref()
+    }
+}
+
+impl<T: ToTokens> ToTokens for Sp<T> {
+    fn to_tokens(&self, stream: &mut TokenStream) {
+        // this is the simplest way out of correct ones to change span on
+        // arbitrary token tree I can come up with
+        let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
+            tt.set_span(self.span.clone());
+            tt
+        });
+
+        stream.extend(tt);
+    }
+}
diff --git a/src/ty.rs b/src/ty.rs
new file mode 100644
index 0000000..89d8b00
--- /dev/null
+++ b/src/ty.rs
@@ -0,0 +1,108 @@
+//! Special types handling
+
+use crate::spanned::Sp;
+
+use syn::{
+    spanned::Spanned, GenericArgument, Path, PathArguments, PathArguments::AngleBracketed,
+    PathSegment, Type, TypePath,
+};
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum Ty {
+    Bool,
+    Vec,
+    Option,
+    OptionOption,
+    OptionVec,
+    Other,
+}
+
+impl Ty {
+    pub fn from_syn_ty(ty: &syn::Type) -> Sp<Self> {
+        use Ty::*;
+        let t = |kind| Sp::new(kind, ty.span());
+
+        if is_simple_ty(ty, "bool") {
+            t(Bool)
+        } else if is_generic_ty(ty, "Vec") {
+            t(Vec)
+        } else if let Some(subty) = subty_if_name(ty, "Option") {
+            if is_generic_ty(subty, "Option") {
+                t(OptionOption)
+            } else if is_generic_ty(subty, "Vec") {
+                t(OptionVec)
+            } else {
+                t(Option)
+            }
+        } else {
+            t(Other)
+        }
+    }
+}
+
+pub fn sub_type(ty: &syn::Type) -> Option<&syn::Type> {
+    subty_if(ty, |_| true)
+}
+
+fn only_last_segment(ty: &syn::Type) -> Option<&PathSegment> {
+    match ty {
+        Type::Path(TypePath {
+            qself: None,
+            path:
+                Path {
+                    leading_colon: None,
+                    segments,
+                },
+        }) => only_one(segments.iter()),
+
+        _ => None,
+    }
+}
+
+fn subty_if<F>(ty: &syn::Type, f: F) -> Option<&syn::Type>
+where
+    F: FnOnce(&PathSegment) -> bool,
+{
+    only_last_segment(ty)
+        .filter(|segment| f(segment))
+        .and_then(|segment| {
+            if let AngleBracketed(args) = &segment.arguments {
+                only_one(args.args.iter()).and_then(|genneric| {
+                    if let GenericArgument::Type(ty) = genneric {
+                        Some(ty)
+                    } else {
+                        None
+                    }
+                })
+            } else {
+                None
+            }
+        })
+}
+
+pub fn subty_if_name<'a>(ty: &'a syn::Type, name: &str) -> Option<&'a syn::Type> {
+    subty_if(ty, |seg| seg.ident == name)
+}
+
+pub fn is_simple_ty(ty: &syn::Type, name: &str) -> bool {
+    only_last_segment(ty)
+        .map(|segment| {
+            if let PathArguments::None = segment.arguments {
+                segment.ident == name
+            } else {
+                false
+            }
+        })
+        .unwrap_or(false)
+}
+
+fn is_generic_ty(ty: &syn::Type, name: &str) -> bool {
+    subty_if_name(ty, name).is_some()
+}
+
+fn only_one<I, T>(mut iter: I) -> Option<T>
+where
+    I: Iterator<Item = T>,
+{
+    iter.next().filter(|_| iter.next().is_none())
+}
