[−][src]Crate finiteelement_macros
This library is used to define types that implement the trait FiniteElement
The types are defined by procedural macros. To create a new type, one must first define an
unit-like Structure and implement the trait AutoImplementable
for it. Once the trait
AutoImplementable
has been implemented it is possible to define a proc macro that will
generate the deffinition of a new type and an implementation of the trait FiniteElement
for
it.
Creation of a new macro
To create a new macro, one must first define a Zero-Sized struct
, and implement the trait
AutoImplementable
for it. For example if we want to create an element representing a spring,
we first create a zero-sized struct
: pub struct _Spring{}
and the implement the trait
Autotimplementable
for it.
The types that implement the trait AutoImplementable
can be passed as type argument to the
function macro_def<F: Float, T: AutoImplementable<F>>() -> TokenStream
. This function
can be used to define a procedural macro that will generate the code defining the
corresponding structure and its implementation of the trait FiniteElement
.
Complete example
(copied-pasted from spring.rs
)
use crate::formal::{Formal, FormalVector, FormalPoint, Float}; use crate::autoimplementable::AutoImplementable; use std::collections::HashMap; // A `Spring` likes it when `a` and `b` are at distance `l`, and // exerts a force of `k.(|ab| - l)` to achieve this. pub struct _Spring{} impl<F: Float> AutoImplementable<F> for _Spring { fn struct_name() -> String { String::from("Spring") } fn elt_list() -> Vec<String> { vec![String::from("a"), String::from("b")] } fn cst_list() -> Vec<String> { vec![String::from("l"), String::from("k")] } fn formal_map() -> HashMap<String, FormalVector<F>> { //Create a `Formal` for each element coordiate and each constants let point_a = FormalPoint { x: Formal::new_var(0), y: Formal::new_var(1), z: Formal::new_var(2) }; let point_b = FormalPoint { x: Formal::new_var(3), y: Formal::new_var(4), z: Formal::new_var(5) }; let cst_l = Formal::new_var(6); let cst_k = Formal::new_var(7); // The force applied on point a is k(|ab| - l) * ab/|ab| let ab = point_b - point_a; let force_a: FormalVector<F> = (ab.clone().norm() - cst_l.clone()) * ab.clone()/ab.clone().norm() * cst_k.clone(); // The force applied on point b is k(|ba| - l) * ba/|ba| let force_b = (ab.clone().norm() - cst_l.clone()) * ab.clone()/ab.clone().norm() * cst_k.clone() * Formal::new_cst(F::one().neg()); let mut ret = HashMap::new(); ret.insert(String::from("a"), force_a); ret.insert(String::from("b"), force_b); ret } } // Once the trait is implemented, we can write a procedural macro #[proc_macro] pub fn auto_impl_spring(_item: TokenStream) -> TokenStream { macro_def::<f32, _Spring>() }
Macros
auto_impl_spring | A |
auto_impl_stack | A |