summaryrefslogtreecommitdiff
path: root/macros/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/lib.rs')
-rw-r--r--macros/src/lib.rs54
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()
+}