opengl_registry_macros/lib.rs
1//! Macros utilizing the [OpenGL API and Extension Registry].
2//!
3//! [OpenGL API and Extension Registry]: https://github.com/KhronosGroup/OpenGL-Registry
4#![cfg_attr(test, feature(test))]
5#![deny(clippy::all, clippy::pedantic, missing_docs)]
6use once_cell::sync::Lazy;
7use opengl_registry::Registry;
8use proc_macro::TokenStream;
9
10use crate::repeat::for_each_opengl_command_impl;
11
12mod iter;
13mod repeat;
14mod str;
15mod token_stream;
16
17const OPENGL_CMD_NAME_REPLACE: &str = "gl_command_name";
18const OPENGL_CMD_NAME_NOPREFIX_REPLACE: &str = "gl_command_name_noprefix";
19const OPENGL_CMD_RET_TYPE_REPLACE: &str = "gl_command_ret_type";
20const OPENGL_CMD_ARGS_REPLACE: &str = "gl_command_args";
21const OPENGL_CMD_ARG_NAMES_REPLACE: &str = "gl_command_arg_names";
22const OPENGL_CMD_ARG_TYPES_REPLACE: &str = "gl_command_arg_types";
23
24static OPENGL_REGISTRY: Lazy<Registry> = Lazy::new(|| Registry::retrieve().unwrap());
25
26/// Repeats the input for each command in the [OpenGL API and Extension Registry].
27///
28/// # Replacements
29/// This macro will replace some specific identifiers **prefixed with a hashtag**.
30///
31/// ### The following identifiers will be replaced
32///
33/// **`gl_command_name`**<br>
34/// Will be replaced by the full command name. For example, `glViewport`.
35///
36/// **`gl_command_name_noprefix`**<br>
37/// Will be replaced by the command name without the "gl" prefix. For example,
38/// `Viewport`.
39///
40/// **`gl_command_ret_type`**<br>
41/// Will be replaced by the command return type. For example, `GLuint`.
42///
43/// **`gl_command_args`**<br>
44/// Will be replaced by the command arguments formatted as `name: type`, seperated by
45/// comma.
46///
47/// **`gl_command_arg_names`**<br>
48/// Will be replaced by the command argument names, seperated by comma.
49///
50/// **`gl_command_arg_types`**<br>
51/// Will be replaced by the command argument types, seperated by comma.
52///
53/// # Examples
54/// ```
55/// # use opengl_registry_macros::for_each_opengl_command;
56/// for_each_opengl_command! {
57/// fn #gl_command_name()
58/// {
59/// println!("Hello from {}", stringify!(#gl_command_name));
60/// }
61/// }
62/// ```
63///
64/// Would expand to the following if the only OpenGL commands were `glCreateShader` and
65/// `glBindBuffer`.
66///
67/// ```
68/// fn glCreateShader()
69/// {
70/// println!("Hello from {}", stringify!(glCreateShader));
71/// }
72/// fn glBindBuffer()
73/// {
74/// println!("Hello from {}", stringify!(glBindBuffer));
75/// }
76/// ```
77///
78/// [OpenGL API and Extension Registry]: https://github.com/KhronosGroup/OpenGL-Registry
79#[proc_macro]
80pub fn for_each_opengl_command(input_stream: TokenStream) -> TokenStream
81{
82 for_each_opengl_command_impl(&input_stream.into(), &OPENGL_REGISTRY).into()
83}