mockers_derive/
lib.rs

1#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))]
2
3extern crate proc_macro;
4
5#[macro_use]
6extern crate lazy_static;
7
8use options::MockAttrOptionsBuilder;
9use proc_macro::TokenStream;
10use proc_macro2::Span;
11use syn::parse_macro_input;
12
13mod codegen;
14mod options;
15mod type_manip;
16mod error;
17#[cfg(feature="debug")] mod debug;
18mod id_gen;
19mod util;
20mod diagnostics;
21
22use crate::codegen::{mock_impl, mocked_impl, register_types_impl};
23use diagnostics::{Diagnostic, Level};
24
25fn emit_error(err: syn::Error) {
26    Diagnostic::spanned(err.span().unstable(), Level::Error, err.to_string()).emit();
27}
28
29/// Implementation `#[mocked]` attribute — main entry point of library.
30/// Attribute may be used on trait, extern module, struct and impl block.
31/// This itself is a thin wrapper around `mocked_impl` where actual work is done.
32#[proc_macro_attribute]
33pub fn mocked(attr: TokenStream, input: TokenStream) -> TokenStream {
34    let opts_span = Span::call_site();
35
36    let mut opts_builder = MockAttrOptionsBuilder::default();
37    let opts_parser = syn::meta::parser(|meta| opts_builder.parse_arg(meta));
38    parse_macro_input!(attr with opts_parser);
39    let opts = match opts_builder.build() {
40        Ok(opts) => opts,
41        Err(err) => {
42            emit_error(err.into());
43            return proc_macro2::TokenStream::new().into();
44        }
45    };
46
47    match mocked_impl(input.into(), opts_span, &opts) {
48        Ok(tokens) => tokens,
49        Err(err) => {
50            emit_error(err);
51            proc_macro2::TokenStream::new()
52        },
53    }
54    .into()
55}
56
57#[proc_macro]
58pub fn mock(input: TokenStream) -> TokenStream {
59    match mock_impl(input.into()) {
60        Ok(tokens) => tokens,
61        Err(err) => {
62            emit_error(err);
63            proc_macro2::TokenStream::new()
64        }
65    }
66    .into()
67}
68
69#[proc_macro]
70pub fn register_types(input: TokenStream) -> TokenStream {
71    match register_types_impl(input.into()) {
72        Ok(tokens) => tokens,
73        Err(err) => {
74            emit_error(err);
75            proc_macro2::TokenStream::new()
76        }
77    }
78    .into()
79}