lox_macros/lib.rs
1#![recursion_limit="256"]
2
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6
7
8#[macro_use]
9mod util;
10
11mod mesh;
12
13
14/// Convenience macro to quickly create a small mesh.
15///
16/// # Examples
17///
18/// Here we create two triangles:
19///
20/// ```
21/// use lox::{
22/// mesh,
23/// prelude::*,
24/// core::SharedVertexMesh,
25/// };
26///
27///
28/// let (mesh, positions, distances, face_colors) = mesh! {
29/// type: SharedVertexMesh,
30/// vertices: [
31/// v0: ([0.0, 0.0, 0.0], 0.0),
32/// v1: ([0.0, 1.0, 0.0], 1.0),
33/// v2: ([1.0, 0.0, 0.0], 1.0),
34/// v3: ([1.0, 1.0, 0.0], 1.414),
35/// ],
36/// faces: [
37/// [v0, v2, v1]: ("red"),
38/// [v3, v1, v2]: ("green"),
39/// ],
40/// };
41///
42/// assert_eq!(mesh.num_vertices(), 4);
43/// assert_eq!(mesh.num_faces(), 2);
44/// ```
45///
46/// In the code above, we associate a position and a scalar value with each
47/// vertex and a color (or rather, a color name) with each face. Properties of
48/// vertices and faces are specified after a colon (`:`) in parenthesis (like a
49/// tuple).
50///
51/// For each property you add in those parenthesis, the macro returns an
52/// additional property map. The full return value is:
53///
54/// ```text
55/// (mesh, /* vertex property maps */, /* face property maps*/)
56/// ```
57///
58/// ## Without properties
59///
60/// We don't need to specify any properties. We can either write empty
61/// parenthesis (`()`) or just omit the colon and the parenthesis:
62///
63/// ```
64/// use lox::{
65/// mesh,
66/// core::SharedVertexMesh,
67/// };
68///
69///
70/// let mesh = mesh! {
71/// type: SharedVertexMesh,
72/// vertices: [
73/// v0: (), // <-- this is equivalent to:
74/// v1, // <-- this
75/// v2,
76/// v3,
77/// ],
78/// faces: [
79/// [v0, v2, v1],
80/// [v3, v1, v2],
81/// ],
82/// };
83/// ```
84///
85/// Of course, you can also add properties to the vertices, but not the faces,
86/// or the other way around. However, you always have to specify the same
87/// number of properties for all vertices and the same number of properties for
88/// all faces.
89///
90/// ## An empty mesh
91///
92/// This is not particularly useful in itself, but it works. You can use this
93/// syntax when you haven't yet decided how your mesh should look like.
94///
95/// ```
96/// use lox::{
97/// mesh,
98/// core::SharedVertexMesh,
99/// };
100///
101///
102/// let empty_mesh = mesh! {
103/// type: SharedVertexMesh,
104/// vertices: [],
105/// faces: [],
106/// };
107/// ```
108#[proc_macro]
109pub fn mesh(input: TokenStream) -> TokenStream {
110 use crate::mesh::MeshInput;
111
112 match syn::parse::<MeshInput>(input) {
113 Ok(x) => x.output().into(),
114 Err(e) => e.to_compile_error().into(),
115 }
116}