#![feature(proc_macro)]
extern crate proc_macro;
use proc_macro::TokenStream;
use std::fmt::Write;
mod macro_helper;
use macro_helper::*;
#[proc_macro_attribute]
pub fn mock(attr: TokenStream, item: TokenStream) -> TokenStream {
let mock_matches = get_mock_matches(&*attr.to_string());
let mut source = item.to_string();
let insertion_point = source.find("{").unwrap() + 1;
source.insert_str(insertion_point, HEADER);
let mut modified_source = source.clone();
for m_match in mock_matches {
let ctx_getter = format!(r#"
(unsafe {{
let _mock_me_test_usize_func = _mock_me_test_context_instance.get("{}");
let _mock_me_test_transmuted_func: {} = std::mem::transmute(_mock_me_test_usize_func);
_mock_me_test_transmuted_func
}})
"#, m_match.identifier, m_match.function_signature);
modified_source = modified_source.replace(&*m_match.function_to_mock, &*ctx_getter);
}
let branched_source = format!(
r#"
#[cfg(not(test))]
{}
#[cfg(test)]
{}
"#, source, modified_source
);
branched_source.parse().unwrap()
}
#[proc_macro_attribute]
pub fn inject(attr: TokenStream, item: TokenStream) -> TokenStream {
let inject_matches = get_inject_matches(&*attr.to_string());
let mut source = item.to_string();
let mut context_setter_string = HEADER.to_string();
for i_match in inject_matches {
write!(
context_setter_string,
"_mock_me_test_context_instance.set(\"{}\".to_string(), {} as usize);\n",
i_match.identifier, i_match.function_to_mock
).unwrap();
}
let insertion_point = source.find("{").unwrap() + 1;
source.insert_str(insertion_point, &*context_setter_string);
source.parse().unwrap()
}