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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
//! <div align="center"> //! <img alt="Rune Logo" src="https://raw.githubusercontent.com/rune-rs/rune/main/assets/icon.png" /> //! </div> //! //! <br> //! //! <div align="center"> //! <a href="https://rune-rs.github.io"> //! <b>Visit the site 🌐</b> //! </a> //! - //! <a href="https://rune-rs.github.io/book/"> //! <b>Read the book 📖</b> //! </a> //! </div> //! //! <br> //! //! <div align="center"> //! <a href="https://github.com/rune-rs/rune/actions"> //! <img alt="Build Status" src="https://github.com/rune-rs/rune/workflows/Build/badge.svg"> //! </a> //! //! <a href="https://github.com/rune-rs/rune/actions"> //! <img alt="Site Status" src="https://github.com/rune-rs/rune/workflows/Site/badge.svg"> //! </a> //! //! <a href="https://crates.io/crates/rune"> //! <img alt="crates.io" src="https://img.shields.io/crates/v/rune.svg"> //! </a> //! //! <a href="https://docs.rs/rune"> //! <img alt="docs.rs" src="https://docs.rs/rune/badge.svg"> //! </a> //! //! <a href="https://discord.gg/v5AeNkT"> //! <img alt="Chat on Discord" src="https://img.shields.io/discord/558644981137670144.svg?logo=discord&style=flat-square"> //! </a> //! </div> //! //! <br> //! //! Macros for Rune. //! //! This is part of the [Rune Language](https://rune-rs.github.io). extern crate proc_macro; mod context; mod internals; mod option_spanned; mod parse; mod quote; mod spanned; mod to_tokens; /// Helper derive to implement `ToTokens`. #[proc_macro_derive(ToTokens, attributes(rune))] #[doc(hidden)] pub fn to_tokens(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as to_tokens::Derive); derive.expand().unwrap_or_else(to_compile_errors).into() } /// Helper derive to implement `Parse`. #[proc_macro_derive(Parse, attributes(rune))] #[doc(hidden)] pub fn parse(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as parse::Derive); derive.expand().unwrap_or_else(to_compile_errors).into() } /// Helper derive to implement `Spanned`. #[proc_macro_derive(Spanned, attributes(rune))] #[doc(hidden)] pub fn spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as spanned::Derive); derive.expand().unwrap_or_else(to_compile_errors).into() } /// Helper derive to implement `OptionSpanned`. #[proc_macro_derive(OptionSpanned, attributes(rune))] #[doc(hidden)] pub fn option_spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let derive = syn::parse_macro_input!(input as option_spanned::Derive); derive.expand().unwrap_or_else(to_compile_errors).into() } /// Macro helper function for quoting the token stream as macro output. /// /// Is capable of quoting everything in Rune, except for the following: /// * Labels, which must be created using `Label::new`. /// * Dynamic quoted strings and other literals, which must be created using /// `Lit::new`. /// /// # Panics /// /// Calling this macro will panic if called outside of a macro context. A macro /// context can be setup using `with_context`. /// /// ```rust /// use rune::macros::{with_context, MacroContext}; /// let ctx = MacroContext::empty(); /// /// with_context(ctx, || { /// rune::quote!(hello self); /// }); /// ``` /// /// # Interpolating values /// /// Values are interpolated with `#value`, or `#(value + 1)` for expressions. /// /// # Iterators /// /// Anything that can be used as an iterator can be iterated over with /// `#(iter)*`. A token can also be used to join inbetween each iteration, like /// `#(iter),*`. #[proc_macro] pub fn quote(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = proc_macro2::TokenStream::from(input); let parser = crate::quote::Quote::new(); let output = match parser.parse(input) { Ok(output) => output, Err(e) => return proc_macro::TokenStream::from(e.to_compile_error()), }; output.into() } fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream { let compile_errors = errors.iter().map(syn::Error::to_compile_error); ::quote::quote!(#(#compile_errors)*) }