3

I have an array of strings like

const LANGUAGES: [&str; 3] = [
  "EN",
  "ES",
  "DE",
];

and I would like to lowercase them at compile time. How can I do that?

Gaston Sanchez
  • 1,181
  • 6
  • 13
  • 1
    Doing anything like this would require either a procedural macro or a build script, neither of which are super simple solutions. Perhaps the problem you're trying to solve can be tackled another way? – eggyal Jun 09 '21 at 23:44
  • Probably not what you really want, but you can use `lazy_static` to create static objects that run some initialization code the first time they're accessed. – Todd Jun 09 '21 at 23:56
  • What do you exactly want ? To have two separate arrays, one being built from the other one ? Or only one array in lowercase. If you're thinking about two separate arrays then you should consider using structs for consistency and code clarity. – Denys Séguret Jun 10 '21 at 06:39
  • Assuming you don't just do it manually because you have tons of text data that you copied into your sources... I'd just write a python script with regular expression substitutions to lowercase any strings in the sources that need it. It only needs to be done once... – Todd Jun 10 '21 at 08:03

1 Answers1

0

Using the konst and const_str package, we can achieve this by joining a slice into a single string, applying the convert_ascii_case macro to lowercase it, and then splitting the string by the same delimiter into a slice

With arrays,

const SIZE: usize = 3;
const LANGUAGES: [&str; SIZE] = ["EN", "ES", "DE"];
const LOWERED: [&str; SIZE] = {
    const SEPERATOR: &str = "|";
    const AS_SLICE: &[&str] = &LANGUAGES;
    const JOINED: &str = konst::string::str_join!(SEPERATOR, AS_SLICE);
    const LOWERED_JOINED: &str = const_str::convert_ascii_case!(lower, JOINED);
    const_str::split!(LOWERED_JOINED, SEPERATOR)
};
println!("{:#?}", LOWERED);

With slices,

const LANGUAGES: &[&str] = &["EN", "ES", "DE"];
const LOWERED: &[&str] = {
    const SEPERATOR: &str = "|";
    const JOINED: &str = konst::string::str_join!(SEPERATOR, LANGUAGES);
    const LOWERED_JOINED: &str = const_str::convert_ascii_case!(lower, JOINED);
    &const_str::split!(LOWERED_JOINED, SEPERATOR)
};
println!("{:#?}", LOWERED);

You may also want to look into konst's for_each macro and the general idea of const_eval. But I have yet to construct a working example using that.

Umar Siregar
  • 1
  • 2
  • 1