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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
//! Various macros for integrating with the `gluon` vm.
//!
//! ## Derive Macros
//!
//! Custom derives for the following `gluon`-Traits are available:
//!
//! ### Getable
//!
//! Derives `Getable` for any enum or struct as long as all fields also implement
//! `Getable` (generic type parameters included). If the type is generic over a
//! lifetime, the lifetime will be constrained to that of the `'vm` lifetime in the
//! trait definition.
//!
//! __Note:__ Newtype structs are expected to be their inner type on the Gluon side.
//!
//! #### Examples
//!
//! Marhalling this gluon type:
//!
//! ```gluon
//! type Comment =
//! | Normal String
//! | Multiline String
//! | Doc String
//! ```
//!
//! To this rust enum:
//!
//! ```rust
//! #[macro_use]
//! extern crate gluon_codegen;
//! extern crate gluon;
//!
//! enum Comment {
//! Normal(String),
//! Multiline(String),
//! Doc(String),
//! }
//! # fn main() {}
//! ```
//!
//! ### Pushable
//!
//! Derives `Pushable` for any enum or struct as long as all fields also implement
//! `Pushable` (generic type parameters included).
//!
//! __Note:__ Newtype structs are pushed as their inner type.
//!
//! #### Examples
//!
//! Allowing the `User` struct to be marshalled to gluon code:
//!
//! ```rust
//! #[macro_use]
//! extern crate gluon_codegen;
//! extern crate gluon;
//!
//! #[derive(Pushable)]
//! struct User {
//! name: String,
//! age: u32,
//! }
//! # fn main() {}
//! ```
//!
//! As this compatible Record:
//!
//! ```gluon
//! type User = { name: String, age: Int }
//! ```
//!
//! ### VmType
//!
//! Derives `VmType` for a rust type, mapping it to a gluon type.
//!
//! Alternatively, you can specify the corresponding gluon type with the
//! `#[gluon(vm_type = "<gluon_type>")]` attribute, where the gluon type is the fully qualified type name.
//! The gluon type must be registered before a binding using the mapped rust type is first loaded.
//!
//! If the rust type has type parameters, they have to implement `VmType` as well.
//! All lifetimes have to be `'static`.
//!
//! __Note:__ Newtype structs are mapped to their inner type.
//!
//! #### Examples
//!
//! Deriving `VmType` for a struct:
//!
//! ```rust
//! #[macro_use]
//! extern crate gluon_codegen;
//! extern crate gluon;
//!
//! // will map to: `{ string: String, number: Int, vec: Array Float }`
//! #[derive(VmType)]
//! struct Struct {
//! string: String,
//! number: u32,
//! vec: Vec<f64>,
//! }
//! # fn main() {}
//! ```
//!
//! Mapping to an existing type, assuming the following gluon type in the module `types`:
//!
//! ```gluon
//! type Either l r = | Left l | Right r
//! ```
//!
//! Requires the additional `vm_type` attribute:
//!
//! ```rust
//! #[macro_use]
//! extern crate gluon_codegen;
//! extern crate gluon;
//!
//! #[derive(VmType)]
//! #[gluon(vm_type = "types.Either")]
//! enum Either<L, R> {
//! Left(L),
//! Right(R),
//! }
//! # fn main() {}
//! ```
//!
//! ### Userdata
//!
//! Derives `Userdata` and the required `Traverseable` and `VmType` for a rust type.
//! Note that you will still have to use `Thread::register_type` to register the
//! rust type with the vm before it is used.
//!
//! #### Examples
//!
//! Deriving `Userdata` for a type that will be opaque for the gluon code:
//!
//! ```rust
//! #[macro_use]
//! extern crate gluon_codegen;
//! extern crate gluon;
//!
//! use std::sync::Arc;
//!
//! // Userdata requires Debug + Send + Sync
//! #[derive(Userdata, Debug)]
//! struct Ident {
//! group: Arc<str>,
//! name: Arc<str>,
//! }
//! # fn main() {}
//! ```
//!
#![recursion_limit = "128"]
extern crate proc_macro;
extern crate proc_macro2;
#[macro_use]
extern crate quote;
extern crate syn;
mod attr;
mod getable;
mod pushable;
mod shared;
mod userdata;
mod vm_type;
#[doc(hidden)]
#[proc_macro_derive(Getable, attributes(gluon))]
pub fn getable(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
getable::derive(input.into()).into()
}
#[doc(hidden)]
#[proc_macro_derive(Pushable, attributes(gluon))]
pub fn pushable(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
pushable::derive(input.into()).into()
}
#[doc(hidden)]
#[proc_macro_derive(Userdata, attributes(gluon))]
pub fn userdata(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
userdata::derive(input.into()).into()
}
#[doc(hidden)]
#[proc_macro_derive(VmType, attributes(gluon))]
pub fn vm_type(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
vm_type::derive(input.into()).into()
}