| Crates.io | microcad-builtin-proc-macro |
| lib.rs | microcad-builtin-proc-macro |
| version | 0.1.0 |
| created_at | 2024-12-20 14:28:31.814126+00 |
| updated_at | 2024-12-20 14:28:31.814126+00 |
| description | µcad builtin proc-macro |
| homepage | https://ucad.xyz |
| repository | https://github.com/rustfahrtagentur/microcad |
| max_upload_size | |
| id | 1490222 |
| size | 7,018 |
This proc macro generates built-in modules from structs.
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()?,
})))
}
}