1 unstable release
new 0.1.0 | Dec 20, 2024 |
---|
#485 in Procedural macros
Used in 2 crates
(via microcad-std)
8KB
63 lines
Built-in proc macro
This proc macro generates built-in modules from structs.
Example
Let's look at µcad's built-in module rect
.
It has the following parameter signature: rect(width: scalar, height: scalar, x: scalar y: scalar)
.
Notice that the parameters are all of type scalar
and not length
.
This is because the built-in module is not aware of the unit system.
The built-in modules are not meant to be used directly.
Instead, they are wrapped in a module written µcad language that provides units, asserts, default values and multiple initializers.
In Rust, a built-in module is defined by a struct that implements the BuiltinModule
trait.
For our rect
module, the struct looks like this:
#[derive(DefineBuiltinModule)]
struct Rect {
width: Scalar,
height: Scalar,
x: Scalar,
y: Scalar,
}
The DefineBuiltinModule
trait is defined as follows:
pub trait DefineBuiltinModule {
fn name() -> &'static str;
fn parameters() -> ParameterList;
fn node(args: &ArgumentMap) -> Node;
fn function() -> &'static BuiltinModuleFn { ... }
}
fn builtin_module() -> BuiltinModule {
BuiltinModule {
name: Self::name(),
parameters: Self::parameters(),
function: Self::function(),
}
}
}
For the rect
module, the implementation of the DefineBuiltinModule
trait looks like this approximately:
impl DefineBuiltinModule for Rectangle {
fn name() -> &'static str {
"rect"
}
fn parameters() -> ParameterList {
parameter_list![
parameter!(width: Scalar),
parameter!(height: Scalar),
parameter!(x: Scalar),
parameter!(y: Scalar),
]
}
fn node(args: &ArgumentMap) -> Result<Node, Error> {
Ok(Node::new(NodeInner::Generator2D(Box::new(Rect {
width: args["width"].try_into()?,
height: args["height"].try_into()?,
x: args["x"].try_into()?,
y: args["y"].try_into()?,
})))
}
}
Dependencies
~225–670KB
~16K SLoC