1// We need to support Rust 1.34 to stable
2#![allow(deprecated)]
3
4#![allow(renamed_and_removed_lints)] // support for multiple Clippy versions
5#![allow(clippy::unknown_clippy_lints)] // because of other #![allow]s
6#![allow(clippy::mem_replace_with_default)] // needs rustc 1.40
7#![allow(clippy::option_as_ref_deref)] // needs rustc 1.40
8#![allow(clippy::cyclomatic_complexity)] // old name of cognitive_complexity
9#![allow(clippy::cognitive_complexity)] // in code generated by macros
10#![allow(clippy::redundant_closure)]
11
12extern crate proc_macro;
13extern crate proc_macro2;
14#[macro_use]
15extern crate syn;
16
17#[macro_use]
18extern crate quote;
19
20mod ast;
21mod attr;
22mod bound;
23mod clone;
24mod cmp;
25mod debug;
26mod default;
27mod hash;
28mod matcher;
29mod paths;
30mod utils;
31
32use proc_macro::TokenStream;
33
34fn derive_impls(
35 input: &mut ast::Input,
36 errors: &mut proc_macro2::TokenStream,
37) -> proc_macro2::TokenStream {
38 let mut tokens = proc_macro2::TokenStream::new();
39
40 if input.attrs.clone.is_some() {
41 tokens.extend(clone::derive_clone(input));
42 }
43 if input.attrs.copy.is_some() {
44 tokens.extend(clone::derive_copy(input));
45 }
46 if input.attrs.debug.is_some() {
47 tokens.extend(debug::derive(input));
48 }
49 if let Some(ref default) = input.attrs.default {
50 tokens.extend(default::derive(input, default));
51 }
52 if input.attrs.eq.is_some() {
53 tokens.extend(cmp::derive_eq(input));
54 }
55 if input.attrs.hash.is_some() {
56 tokens.extend(hash::derive(input));
57 }
58 if input.attrs.partial_eq.is_some() {
59 tokens.extend(cmp::derive_partial_eq(input));
60 }
61 if input.attrs.partial_ord.is_some() {
62 tokens.extend(cmp::derive_partial_ord(input, errors));
63 }
64 if input.attrs.ord.is_some() {
65 tokens.extend(cmp::derive_ord(input, errors));
66 }
67
68 tokens.extend(std::mem::replace(
69 errors,
70 Default::default(),
71 ));
72
73 tokens
74}
75
76#[cfg_attr(not(test), proc_macro_derive(Derivative, attributes(derivative)))]
77pub fn derivative(input: TokenStream) -> TokenStream {
78 let mut errors: TokenStream = proc_macro2::TokenStream::new();
79
80 let mut output: TokenStream = match syn::parse::<syn::DeriveInput>(tokens:input) {
81 Ok(parsed: DeriveInput) => {
82 astResult::Input::from_ast(&parsed, &mut errors)
83 .map(|mut input: Input<'_>| derive_impls(&mut input, &mut errors))
84 .unwrap_or_default()
85 },
86 Err(error: Error) => {
87 errors.extend(iter:error.to_compile_error());
88 Default::default()
89 }
90 };
91
92 output.extend(iter:errors);
93 output.into()
94}