//! Proc macros for `mizan-core`. See sibling modules for each macro's body: //! `derive` for `#[derive(Mizan)]`, `context` / `function` / `channel` for the //! three attribute macros, `shape` for the shared `syn::Type` lowering. //! //! The function macro is named `client` so `mizan::` stays purely a module //! path — a module path can't simultaneously be a callable macro in Rust, so //! `#[mizan(...)]` would collide with `mizan::context`. mod channel; mod context; mod derive; mod function; mod shape; use proc_macro::TokenStream; use syn::{parse_macro_input, ItemStruct}; #[proc_macro_derive(Mizan)] pub fn derive_mizan(input: TokenStream) -> TokenStream { let derived = parse_macro_input!(input as derive::MizanDerive); derive::expand(derived).into() } #[proc_macro_attribute] pub fn context(attr: TokenStream, item: TokenStream) -> TokenStream { let name = match context::ContextName::parse(attr.into()) { Ok(n) => n, Err(e) => return e.to_compile_error().into(), }; let item = parse_macro_input!(item as ItemStruct); context::expand(name, item).into() } /// The function-registration attribute macro. Used as `#[mizan::client]` /// (no args) or `#[mizan::client(context = X, affects = Y, merge = Z, /// websocket, private)]`. #[proc_macro_attribute] pub fn client(attr: TokenStream, item: TokenStream) -> TokenStream { let args = parse_macro_input!(attr as function::FunctionArgs); let handler = parse_macro_input!(item as function::Handler); function::expand(args, handler).into() } /// The channel-registration attribute macro. Used as /// `#[mizan::channel("", params = P, client_message = C, /// server_message = S)]` on a unit struct; every slot is optional. #[proc_macro_attribute] pub fn channel(attr: TokenStream, item: TokenStream) -> TokenStream { let args = parse_macro_input!(attr as channel::ChannelArgs); let item = parse_macro_input!(item as ItemStruct); channel::expand(args, item).into() }