#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))]
extern crate proc_macro;
#[macro_use]
extern crate lazy_static;
use options::MockAttrOptionsBuilder;
use proc_macro::TokenStream;
use proc_macro2::Span;
use syn::parse_macro_input;
mod codegen;
mod options;
mod type_manip;
mod error;
#[cfg(feature="debug")] mod debug;
mod id_gen;
mod util;
mod diagnostics;
use crate::codegen::{mock_impl, mocked_impl, register_types_impl};
use diagnostics::{Diagnostic, Level};
fn emit_error(err: syn::Error) {
Diagnostic::spanned(err.span().unstable(), Level::Error, err.to_string()).emit();
}
#[proc_macro_attribute]
pub fn mocked(attr: TokenStream, input: TokenStream) -> TokenStream {
let opts_span = Span::call_site();
let mut opts_builder = MockAttrOptionsBuilder::default();
let opts_parser = syn::meta::parser(|meta| opts_builder.parse_arg(meta));
parse_macro_input!(attr with opts_parser);
let opts = match opts_builder.build() {
Ok(opts) => opts,
Err(err) => {
emit_error(err.into());
return proc_macro2::TokenStream::new().into();
}
};
match mocked_impl(input.into(), opts_span, &opts) {
Ok(tokens) => tokens,
Err(err) => {
emit_error(err);
proc_macro2::TokenStream::new()
},
}
.into()
}
#[proc_macro]
pub fn mock(input: TokenStream) -> TokenStream {
match mock_impl(input.into()) {
Ok(tokens) => tokens,
Err(err) => {
emit_error(err);
proc_macro2::TokenStream::new()
}
}
.into()
}
#[proc_macro]
pub fn register_types(input: TokenStream) -> TokenStream {
match register_types_impl(input.into()) {
Ok(tokens) => tokens,
Err(err) => {
emit_error(err);
proc_macro2::TokenStream::new()
}
}
.into()
}