Is there something like C99 designated initializer for arrays?

Hi! I'm learning Rust, coming from C/C++/Python development. I'm currently rewriting some old weather station C code in Rust, and found a bit of a blocker that I solved it this way, so I'm asking for a quick code review or recommendations for a more idiomatic solution if available:

In C this const array was initialized like:

const char *forecast_icon_text[256] = { /* a full byte, just in case of undef.*/
[0x02]="Mostly Cloudy",
[0x03]="Mostly Cloudy, Rain within 12 hours",
[0x06]="Partly Cloudy",
[0x07]="Partly Cloudy, Rain within 12 hours",
[0x08]="Mostly Clear",
[0x12]="Mostly Cloudy, Snow within 12 hours",
[0x13]="Mostly Cloudy, Rain or Snow within 12 hours",
[0x16]="Partly Cloudy, Snow within 12 hours",
[0x17]="Partly Cloudy, Rain or Snow within 12 hours"};

But in Rust I had to create it like:

const FORECAST_ICON_TEXT: [&str;0x18] = [
/* 00 */ "",
/* 01 */ "",
/* 02 */ "Mostly Cloudy",
/* 03 */ "Mostly Cloudy, Rain within 12 hours",
/* 04 */ "",
/* 05 */ "",
/* 06 */ "Partly Cloudy",
/* 07 */ "Partly Cloudy, Rain within 12 hours",
/* 08 */ "Mostly Clear",
/* 09 */ "",
/* 0A */ "",
/* 0B */ "",
/* 0C */ "",
/* 0D */ "",
/* 0E */ "",
/* 0F */ "",
/* 10 */ "",
/* 11 */ "",
/* 12 */ "Mostly Cloudy, Snow within 12 hours",
/* 13 */ "Mostly Cloudy, Rain or Snow within 12 hours",
/* 14 */ "",
/* 15 */ "",
/* 16 */ "Partly Cloudy, Snow within 12 hours",
/* 17 */ "Partly Cloudy, Rain or Snow within 12 hours"];

So, the question is, is there a better way to create these sparse arrays in Rust?

I found about this quickly closed attempt for an RFC: RFC: C99-style designated initializers · Issue #11936 · rust-lang/rust · GitHub

But, since that was in 2014 maybe there is something new that I don't know how to search for as maybe it does have an unusual name?

Also, in this particular example that array index is very important and also that it is constant, so collections may not work. The related code is all working fine, and it has been a nice exercise to learn Rust.

Thanks!

You can mutate it in the initializer (at compile-time):

const FORECAST_ICON_TEXT: [&str; 0x18] = {
    let mut a = [""; 0x18];
    a[0x02] = "Mostly Cloudy";
    a[0x03] = "Mostly Cloudy, Rain within 12 hours";
    a[0x06] = "Partly Cloudy";
    a[0x07] = "Partly Cloudy, Rain within 12 hours";
    a[0x08] = "Mostly Clear";
    a[0x12] = "Mostly Cloudy, Snow within 12 hours";
    a[0x13] = "Mostly Cloudy, Rain or Snow within 12 hours";
    a[0x16] = "Partly Cloudy, Snow within 12 hours";
    a[0x17] = "Partly Cloudy, Rain or Snow within 12 hours";
    a
};

You may want a static though -- const values are essentially copied at every use.

https://doc.rust-lang.org/reference/items/constant-items.html
https://doc.rust-lang.org/reference/items/static-items.html

11 Likes

Thanks a lot! Worked great and you are correct, I was thinking about the properties of static.