1

This is the scenario:

struct MyStruct;
impl MyStruct {
    const MyConstant1: &str = "Hello";
    const MyConstant2: &str = "Stackoverflow";
    // In future versions, this list of constants can grow.
}

And I would like to iterate over all associated constants in MyStruct. Is this possible? Any crates?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 3
    This might be an XY problem. What is the purpose of iterating over these constants? – kotatsuyaki Dec 21 '22 at 15:14
  • I want to use variables to refer to this strings, but at the same time count how many of this variables are there and iterate over all possible variables. – arandompersonontheinternet Dec 21 '22 at 15:15
  • 1
    That comment still doesn't explain the practical problem you are trying to solve; you are still trying to describe how you are trying to solve an unknown problem. What do these variables represent? Why would you need to count them out or iterate over them? When would it be possible for the amount to change?? – Claies Dec 21 '22 at 15:19
  • This variables represent JSON keys, I need to iterate over all possible JSON keys in order to retrieve data. The amount of keys can change whether the JSON file is changed officially by the data provider. At first, this keys are fixed to a given version, and, every time a new version is released, new keys are added to this growing list of constants and the version we support is updated as well. – arandompersonontheinternet Dec 21 '22 at 15:23
  • 2
    This seems like an odd way to handle a JSON response; What is the purpose of using constants for this? – Claies Dec 21 '22 at 15:27
  • Because the code base grows to handle new JSON keys as well, new code is written using new keys (constants). For example, if this JSON data file contains "something" then lets retrieve the value of "something" and compare it to "other". As explained, our code is based on JSON data and we accommodate our code to new released versions of this data. – arandompersonontheinternet Dec 21 '22 at 15:31

2 Answers2

3

Here's a naive solution that could possibly be improved with a macro:

struct MyStruct;

impl MyStruct {
  const ITEMS: &'static [&'static str] = &[
    "item1",
    "item2",
  ];

  const ITEM_1 : &'static str = MyStruct::ITEMS[0];
}
John Ledbetter
  • 13,557
  • 1
  • 61
  • 80
1

For those interested, this is my current approach, simple, automatic, easy to maintain and improve (haven't test it yet, but I will follow this approach):

#[macro_export]
macro_rules! arr_from_consts {
    ($nv:vis const $ni:ident = [$( $(#[doc = $doc:expr])* $v:vis const $i:ident: $t:ty = $e:expr; )*]) => {
        $($v const $i: $t = $e;)*
        $nv const $ni: [&str; count!($($i)*)] = [
            $($i),*
        ];
    }
}

And can be used like so:

arr_from_consts!(
pub const MyConstants = [
    pub const MyConstant1: &str = "Hello";
    pub const MyConstant2: &str = "Stackoverflow";
]);

Thanks to everyone.

Edit: The count macro:

macro_rules! count {
    () => (0usize);
    ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
}

From this link, for example.