diff options
author | HampusM <hampus@hampusmat.com> | 2023-03-18 17:14:42 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-03-18 17:15:30 +0100 |
commit | c48271aef7e6b0819c497f302127c161845a83d7 (patch) | |
tree | a18d7b5fc8e017b4b7e0917a55534b28a01fe57d /macros/src/lib.rs | |
parent | 2ca8017deebe7bfe5aac368aead777a2c4910ca2 (diff) |
refactor: rewrite the mock macro as a procedural macro
Diffstat (limited to 'macros/src/lib.rs')
-rw-r--r-- | macros/src/lib.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..ce91f87 --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,54 @@ +#![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, TraitItem}; + +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::<MockInput>(input_stream.clone()).unwrap_or_abort(); + + let mock_ident = input.mock; + + let mock_mod_ident = format_ident!("__{mock_ident}"); + + let method_items = input + .items + .into_iter() + .filter_map(|item| match item { + TraitItem::Method(item_method) => Some(item_method), + _ => None, + }) + .collect::<Vec<_>>(); + + let mock = Mock::new(mock_ident.clone(), input.mocked_trait, &method_items); + + let expectations = method_items + .iter() + .map(|item_method| Expectation::new(&mock_ident, item_method)); + + quote! { + mod #mock_mod_ident { + use super::*; + + #mock + + #(#expectations)* + } + + use #mock_mod_ident::#mock_ident; + } + .into() +} |