runestick_macros/
lib.rs

1//! <div align="center">
2//!     <img alt="Rune Logo" src="https://raw.githubusercontent.com/rune-rs/rune/main/assets/icon.png" />
3//! </div>
4//!
5//! <br>
6//!
7//! <div align="center">
8//! <a href="https://rune-rs.github.io">
9//!     <b>Visit the site 🌐</b>
10//! </a>
11//! -
12//! <a href="https://rune-rs.github.io/book/">
13//!     <b>Read the book 📖</b>
14//! </a>
15//! </div>
16//!
17//! <br>
18//!
19//! <div align="center">
20//! <a href="https://github.com/rune-rs/rune/actions">
21//!     <img alt="Build Status" src="https://github.com/rune-rs/rune/workflows/Build/badge.svg">
22//! </a>
23//!
24//! <a href="https://github.com/rune-rs/rune/actions">
25//!     <img alt="Site Status" src="https://github.com/rune-rs/rune/workflows/Site/badge.svg">
26//! </a>
27//!
28//! <a href="https://crates.io/crates/rune">
29//!     <img alt="crates.io" src="https://img.shields.io/crates/v/rune.svg">
30//! </a>
31//!
32//! <a href="https://docs.rs/rune">
33//!     <img alt="docs.rs" src="https://docs.rs/rune/badge.svg">
34//! </a>
35//!
36//! <a href="https://discord.gg/v5AeNkT">
37//!     <img alt="Chat on Discord" src="https://img.shields.io/discord/558644981137670144.svg?logo=discord&style=flat-square">
38//! </a>
39//! </div>
40//!
41//! <br>
42//!
43//! Macros for Runestick, a stack-based virtual machine for the Rust programming
44//! language.
45//!
46//! This is part of the [Rune Language](https://rune-rs.github.io).
47
48extern crate proc_macro;
49
50use quote::quote;
51
52mod any;
53mod context;
54mod from_value;
55mod internals;
56mod to_value;
57
58/// Conversion macro for constructing proxy objects from a dynamic value.
59#[proc_macro_derive(FromValue, attributes(rune))]
60pub fn from_value(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
61    let input = syn::parse_macro_input!(input as syn::DeriveInput);
62    from_value::expand(&input)
63        .unwrap_or_else(to_compile_errors)
64        .into()
65}
66
67/// Conversion macro for constructing proxy objects from a dynamic value.
68#[proc_macro_derive(ToValue, attributes(rune))]
69pub fn to_value(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
70    let input = syn::parse_macro_input!(input as syn::DeriveInput);
71    to_value::expand(&input)
72        .unwrap_or_else(to_compile_errors)
73        .into()
74}
75
76/// Macro to mark a value as external, which will implement all the appropriate
77/// traits.
78///
79/// This is required to support the external type as a type argument in a
80/// registered function.
81///
82/// ## `#[rune(name = "..")]` attribute
83///
84/// The name of a type defaults to its identifiers, so `struct Foo {}` would be
85/// given the name `"Foo"`.
86///
87/// This can be overrided with the `#[rune(name = "...")]` attribute:
88///
89/// ```rust
90/// use runestick::Any;
91///
92/// #[derive(Any)]
93/// #[rune(name = "Bar")]
94/// struct Foo {
95/// }
96///
97/// fn install() -> Result<runestick::Module, runestick::ContextError> {
98///     let mut module = runestick::Module::new();
99///     module.ty::<Foo>()?;
100///     Ok(module)
101/// }
102/// ```
103#[proc_macro_derive(Any, attributes(rune))]
104pub fn any(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
105    let derive = syn::parse_macro_input!(input as any::Derive);
106    derive.expand().unwrap_or_else(to_compile_errors).into()
107}
108
109/// Internal macro to implement external.
110#[proc_macro]
111#[doc(hidden)]
112pub fn __internal_impl_any(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
113    let internal_call = syn::parse_macro_input!(input as any::InternalCall);
114    internal_call
115        .expand()
116        .unwrap_or_else(to_compile_errors)
117        .into()
118}
119
120fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
121    let compile_errors = errors.iter().map(syn::Error::to_compile_error);
122    quote!(#(#compile_errors)*)
123}