Search code examples
rustruntimetraitsconst-generics

Map dynamic integers to const integers


I need to adapt the interior length of variants of the same struct according to a runtime parameter. The structs are defined generically and differ only in length. The only solution I could think of is using a match statement:

pub struct Foo<const L: usize> {
    data: [i32; L],
}

impl<const L: usize> Foo<L> {
    pub fn new() -> Self {
        Self { data: [0; L] }
    }
}

pub trait FooTrait {
    fn new_len_foo(&self, len: usize) -> Box<dyn FooTrait>;
}

impl<const L: usize> FooTrait for Foo<L> {
    fn new_len_foo(&self, len: usize) -> Box<dyn FooTrait> {
        match len {
            2 => { Box::new(Foo::<2>::new()) },
            3 => { Box::new(Foo::<3>::new()) },
            4 => { Box::new(Foo::<4>::new()) },
            _ => { Box::new(Foo::<1>::new()) }
        }
    }
}

However, there are many lengths I need to consider... Is there a more ergonomic way to do this?


Solution

  • You could use seq_macro to generate the code:

    fn new_len_foo(&self, len: usize) -> Box<dyn FooTrait> {
        seq!(L in 2..=24 {
            if len == L { return Box::new(Foo::<L>::new()); }
        });
        Box::new(Foo::<1>::new())
    }