Hey 
I try to generate a lookup table which consists of &'static str
.
This lookup table is const
and can in theory be calculated at compile time.
My issue right now is, that I would like to use a variable from the const fn
to be part of the &'static str
i write into each array element.
const LOOKUP: [&'static str; 8] = {
let mut tbl = [""; 8];
let mut i = 0usize;
while i < tbl.len() {
tbl[i] = "0xi"; // big question is how to solve this here
i += 1;
}
tbl
};
pub fn main(){
println!("{:?}", LOOKUP);
// what i would want to read is
// ["0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7"]
// right now it only reads 0xi for each element
}
I know that there is the const_format
crate for exmaple, but it is denying work, because i
is not const
when calling it's formatting macro. Any ideas how to solve this?
Is it possible to do what I want in Rust right now?
1 Like
You can do this with a proc-macro. Here's an example that doesn't need any extra dependencies (though you might eventually want to use quote
and proc-macro2
):
// strmac/lib.rs
use proc_macro::TokenStream;
use std::fmt::Write;
#[proc_macro]
pub fn make_lookup(_item: TokenStream) -> TokenStream {
let mut lookup = String::from("[");
for i in 0..8 {
lookup.write_fmt(format_args!(r#""0x{i}","#)).unwrap();
}
lookup.push(']');
lookup.parse().unwrap()
}
Use it in your other crate by importing the macro:
use strmac::make_lookup;
const LOOKUP: [&str; 8] = make_lookup!();
fn main() {
println!("{:?}", LOOKUP);
}
Alternatively, if you don't plan on having proc macros and don't mind extra deps, there's the seq-macro crate:
#!/usr/bin/env rust-script
//! ```cargo
//! [dependencies]
//! const_format = "0.2"
//! seq-macro = "0.3"
//! ```
//!
//!
use seq_macro::seq;
use const_format::concatcp;
const LIST: [&str; 8] = {
let mut l = [""; 8];
seq!(i in 0..8u64 {
l[i as usize] = concatcp!("0x",i);
});
l
};
fn main() {
println!("{LIST:?}");
}
// ["0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7"]
it's a bit finnicky though with what it accepts in the ranges though...
I really would prefer to not include any other dependencies (I always think the meme about node.js modules and black holes), but this really looks tidy and compact <3
Too bad this somehow is so cumbersome with just pure std Rust 
Would prefer if the language would be a tiny bit more expressive/flexible, in order to write concise code, instead of having to write half a book or add extra dependencies.
Thanks for this, will play around with it after work 
Avoiding extra dependencies is actually something I would value a lot.
Too bad it isn't doable with pure std Rust, but a proc-macro is something I thought of myself as well.
Guess it is time for me to dive into that rabbit hole as well 
Thanks for taking the time to formulate this snippet, will play with it after work.
You can write bytes to buffer and then call std::str::from_utf8
.
Didn't know this existed, it certainly will come in handy at one point, thanks!
If I feel like it, I might write my own little macro for formatting in const functions with it 
That crate is cool konst - Rust