finiteelement_macros 0.1.0

A library to create procedural macros that define types implementing FiniteElement
Documentation
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>() -> 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 AutoImplementable for _Spring { fn struct_name() -> String { String::from("Spring") } fn elt_list() -> Vec { vec![String::from("a"), String::from("b")] } fn cst_list() -> Vec { vec![String::from("l"), String::from("k")] } fn formal_map() -> HashMap> { //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 = (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::() } ```