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}