extern crate proc_macro; use proc_macro::TokenStream; use quote::ToTokens; use syn::parse_macro_input; mod case_convert; mod error; mod generation; mod model; mod parsing; mod validation; use crate::{model::ProtocolModel, parsing::Protocol}; macro_rules! unwrap_or_compile_err { ($result:expr) => { match $result { Ok(value) => value, Err(err) => return err.into_compile_error().into(), } }; } /// Generates types for the actors participating in a messaging protocol. /// /// ## Usage Restrictions /// You must also ensure all message types referenced by the protocol are in scope. /// /// ## Grammar /// The grammar recognized by this macro is given below in the dialect of Extended Backus-Naur Form /// recognized by the `llgen` tool. The terminal symbols `Ident` and `LitInt` have the same meaning /// as they do in the [syn] crate. /// /// ```ebnf /// protocol : name_def ';' ( version_def ';')? ( actor_def ';' )+ ( transition ';' )+ ; /// name_def : "named" Ident ; /// version_def: "version" LitInt; /// actor_def : "let" Ident '=' ident_array ; /// ident_array : '[' Ident ( ',' Ident )* ','? ']' ; /// transition : state ( '?' message )? "->" states_list ( '>' dest_list )? ; /// state : Ident ident_array? ; /// states_list : state ( ',' state )* ','? ; /// dest_list : dest ( ',' dest )* ; /// dest : dest_state '!' message /// dest_state : ( "service" '(' Ident ')' ) | state ; /// message : Ident ( "::" "Reply" )? ident_array? ; /// ``` #[proc_macro] pub fn protocol(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as Protocol); let model = unwrap_or_compile_err!(ProtocolModel::new(input)); unwrap_or_compile_err!(model.validate()); model.to_token_stream().into() }