#![deny(clippy::all, clippy::pedantic)] use proc_macro::TokenStream; use proc_macro_error::{proc_macro_error, ResultExt}; use quote::{format_ident, quote}; use syn::{parse, ImplItem}; use crate::expectation::Expectation; use crate::mock::Mock; use crate::mock_input::MockInput; mod expectation; mod mock; mod mock_input; mod syn_ext; mod util; #[proc_macro] #[proc_macro_error] pub fn mock(input_stream: TokenStream) -> TokenStream { let input = parse::(input_stream.clone()).unwrap_or_abort(); let mock_ident = input.mock; let mock_mod_ident = format_ident!("__{mock_ident}"); let method_items = input .item_impl .items .into_iter() .filter_map(|item| match item { ImplItem::Method(item_method) => Some(item_method), _ => None, }) .collect::>(); let mock = Mock::new( mock_ident.clone(), input.mocked_trait, &method_items, input.item_impl.generics.clone(), ); let expectations = method_items.iter().map(|item_method| { Expectation::new( &mock_ident, item_method, input.item_impl.generics.params.clone(), ) }); quote! { mod #mock_mod_ident { use super::*; #mock #(#expectations)* } use #mock_mod_ident::#mock_ident; } .into() }