Let's assume, we want a bunch of constants, associating each square of a chess board with its coordinates, so we can use those constants in our Rust code.
One such definition could be:
#[allow(dead_code)]
const A1: (usize,usize) = (0, 0);
and there would be 64 of them.
Now, as a emacs user, I could generate the source code easily, for example with:
(dolist (col '(?A ?B ?C ?D ?E ?F ?G ?H))
(dolist (row '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8))
(insert "#[allow(dead_code)]")
(end-of-line)
(newline-and-indent)
(insert "const " col row ": (usize,usize) = ("
(format "%d" (- col ?A))
", "
(format "%d" (- row ?1))
");")
(end-of-line)
(newline-and-indent)))
With the drawback, that now my file just grew by 128 exceptionally boring lines.
In Common Lisp, I would solve this aspect, by defining myself a macro, for example:
(defmacro defconst-square-names ()
(labels ((square-name (row col)
(intern
(format nil "+~C~D+"
(code-char (+ (char-code #\A) col))
(+ row 1))))
(one-square (row col)
`(defconstant ,(square-name row col)
(cons ,row ,col))))
`(eval-when (:compile-toplevel :load-toplevel :execute)
,@(loop
for col below 8
appending
(loop for row below 8
collecting (one-square row col))))))
(defconst-square-names) ;; nicer packaging of those 64 boring lines...
Now, the question arises, of course,
- if Rust macro system is able to accomplish this?
- can someone show such a macro?
- I read, you need to put such Rust macro into a separate crate or whatnot?!
UPDATE
@aedm pointed me with the comment about seq-macro
crate to my first attempt to get it done. But unfortunately, from skimming over various Rust documents about macros, I still don't know how to define and call compile time functions from within such a macro:
fn const_name(index:usize) -> String {
format!("{}{}",
char::from_u32('A' as u32
+ (index as u32 % 8)).unwrap()
, index / 8)
}
seq!(index in 0..64 {
#[allow(dead_code)]
const $crate::const_name(index) : (usize,usize) = ($(index / 8), $(index %8));
});
In my Common Lisp solution, I just defined local functions within the macro to get such things done. What is the Rust way?