motsu_proc/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
//! Procedural macro definitions used in `motsu`.
use proc_macro::TokenStream;
/// Shorthand to print nice errors.
///
/// Note that it's defined before the module declarations.
macro_rules! error {
($tokens:expr, $($msg:expr),+ $(,)?) => {{
let error = syn::Error::new(syn::spanned::Spanned::span(&$tokens), format!($($msg),+));
return error.to_compile_error().into();
}};
(@ $tokens:expr, $($msg:expr),+ $(,)?) => {{
return Err(syn::Error::new(syn::spanned::Spanned::span(&$tokens), format!($($msg),+)))
}};
}
mod test;
/// Defines a unit test that provides access to Stylus' execution context.
///
/// Internally, this is a thin wrapper over `#[test]` that gives access to
/// affordances like contract storage and `msg::sender`. If you don't need
/// them, you can pass no arguments to the test function or simply use
/// `#[test]` instead of `#[motsu::test]`.
///
/// # Examples
///
/// ```rust,ignore
/// #[cfg(test)]
/// mod tests {
/// #[motsu::test]
/// fn reads_balance(contract: Erc20) {
/// let balance = contract.balance_of(Address::ZERO);
/// assert_eq!(U256::ZERO, balance);
///
/// let owner = msg::sender();
/// let one = U256::from(1);
/// contract._balances.setter(owner).set(one);
/// let balance = contract.balance_of(owner);
/// assert_eq!(one, balance);
/// }
/// }
/// ```
///
/// ```rust,ignore
/// #[cfg(test)]
/// mod tests {
/// #[motsu::test]
/// fn t() { // If no params, it expands to a `#[test]`.
/// ...
/// }
/// }
/// ```
#[proc_macro_attribute]
pub fn test(attr: TokenStream, input: TokenStream) -> TokenStream {
test::test(&attr, input)
}