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#[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}