lib.rs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. extern crate proc_macro;
  2. use proc_macro::TokenStream;
  3. use quote::ToTokens;
  4. use syn::parse_macro_input;
  5. mod case_convert;
  6. mod error;
  7. mod generation;
  8. mod model;
  9. mod parsing;
  10. mod validation;
  11. use crate::{model::ProtocolModel, parsing::Protocol};
  12. macro_rules! unwrap_or_compile_err {
  13. ($result:expr) => {
  14. match $result {
  15. Ok(value) => value,
  16. Err(err) => return err.into_compile_error().into(),
  17. }
  18. };
  19. }
  20. /// Generates types for the actors participating in a messaging protocol.
  21. ///
  22. /// ## Usage Restrictions
  23. /// You must also ensure all message types referenced by the protocol are in scope.
  24. ///
  25. /// ## Grammar
  26. /// The grammar recognized by this macro is given below in the dialect of Extended Backus-Naur Form
  27. /// recognized by the `llgen` tool. The terminal symbols `Ident` and `LitInt` have the same meaning
  28. /// as they do in the [syn] crate.
  29. ///
  30. /// ```ebnf
  31. /// protocol : name_def ';' ( version_def ';')? ( actor_def ';' )+ ( transition ';' )+ ;
  32. /// name_def : "named" Ident ;
  33. /// version_def: "version" LitInt;
  34. /// actor_def : "let" Ident '=' ident_array ;
  35. /// ident_array : '[' Ident ( ',' Ident )* ','? ']' ;
  36. /// transition : state ( '?' message )? "->" states_list ( '>' dest_list )? ;
  37. /// state : Ident ident_array? ;
  38. /// states_list : state ( ',' state )* ','? ;
  39. /// dest_list : dest ( ',' dest )* ;
  40. /// dest : dest_state '!' message
  41. /// dest_state : ( "service" '(' Ident ')' ) | state ;
  42. /// message : Ident ( "::" "Reply" )? ident_array? ;
  43. /// ```
  44. #[proc_macro]
  45. pub fn protocol(input: TokenStream) -> TokenStream {
  46. let input = parse_macro_input!(input as Protocol);
  47. let model = unwrap_or_compile_err!(ProtocolModel::new(input));
  48. unwrap_or_compile_err!(model.validate());
  49. model.to_token_stream().into()
  50. }